openclaw-backup
Encrypted backup and restore for OpenClaw Agent workspace files with auto-generated AES-256-CBC passwords.
- Supports three core operations: upload workspace files with auto-generated encryption passwords, download and decrypt previous backups, and delete remote backups from soul-upload.com
- Automatically backs up default OpenClaw files (SOUL.md, MEMORY.md, IDENTITY.md, AGENTS.md, TOOLS.md) or user-specified files; stores recovery information including auto-generated passwords in
.openclaw-backup-recovery.txt - Enforces 20 MB backup size limit and requires Python 3.7+, tar, openssl, and the requests library
- Each backup receives a unique 32-character random password that is never reused; recovery file is essential for restoration since it contains the only copy of the password
OpenClaw Backup Skill
Automated encrypted backup and restore for OpenClaw Agent workspace files using Claude Code.
Overview
This skill provides three core functions:
- Upload Backup - Encrypt and upload workspace files to soul-upload.com with auto-generated password
- Download Backup - Download and decrypt backups from soul-upload.com using stored password
- Delete Backup - Delete backups from remote storage
All backups use AES-256-CBC encryption (via openssl) with auto-generated random passwords. Each backup gets a unique password that is stored in the recovery file.
System Requirements
Before executing backup operations, ensure the following tools are installed:
- Python 3.7+ (script runtime environment)
- requests library (
pip install requests) - tar (file archiving)
- openssl (encryption/decryption)
- curl (HTTP requests, system built-in)
Default Backup Files
If the user doesn't specify files, the following OpenClaw workspace files are backed up by default:
SOUL.md- Agent core identity and goalsMEMORY.md- Agent memory and contextIDENTITY.md- Agent identity definitionAGENTS.md- Agent configurationTOOLS.md- Tool configuration
Workflow 1: Upload Backup
Trigger Scenarios
Execute when the user requests to backup workspace files:
- "Back up my workspace files"
- "Upload SOUL.md to soul-upload"
- "Create an encrypted backup of my agent files"
- "Backup SOUL.md and MEMORY.md"
Execution Steps
-
Collect File List
- If user specified files, use the user-specified files
- Otherwise, use default list:
SOUL.md MEMORY.md IDENTITY.md AGENTS.md TOOLS.md - Use Read tool to verify files exist
-
Execute Backup Script (Password Auto-Generated)
- Locate script path (usually
scripts/backup.pyin Skill directory) - Execute command WITHOUT --password argument (script will auto-generate):
python3 scripts/backup.py upload \ --files "SOUL.md MEMORY.md IDENTITY.md" - Script automatically generates a 32-character random password
- Capture stdout (JSON response) and stderr (progress info including generated password)
- Locate script path (usually
-
Process Response
- On success, script outputs JSON:
{ "backupId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "downloadUrl": "https://soul-upload.com/backup/...", "sizeBytes": 12345, "sha256": "abc123...", "password": "auto-generated-32-char-random-password" } - Parse JSON and extract key information including the auto-generated password
- On success, script outputs JSON:
-
Save Recovery Information
- Use Write tool to create/update
.openclaw-backup-recovery.txt - CRITICAL: Include the auto-generated password in the recovery file
- Format:
Backup ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Password: auto-generated-32-char-random-password Download URL: https://soul-upload.com/backup/... Created: 2024-01-15 10:30:00 UTC Size: 12.05 KB SHA256: abc123... Files: SOUL.md, MEMORY.md, IDENTITY.md --- - Append to end of file (preserve history)
- Use Write tool to create/update
-
Display Success Message
- Inform user backup is complete
- Show Backup ID and file size
- IMPORTANT: Inform user that password was auto-generated and saved to
.openclaw-backup-recovery.txt - Warn user: Recovery file is CRITICAL - without it, backup cannot be restored
Error Handling
| Error Scenario | Detection | User Guidance |
|---|---|---|
| Files not found | Script returns error: "Files not found: ..." | List missing files, ask if user wants to continue backing up other files |
| Files too large | Script returns error: "Backup size ... exceeds limit ..." | Show actual size, suggest removing large files or splitting backup |
| Network error | Script returns error: "Network error: ..." | Suggest checking network connection, ask if retry is wanted |
| 413 Too Large | Script returns error: "File too large (413 Payload Too Large)" | Indicate 20MB limit exceeded, suggest reducing backup size |
| Encryption failed | Script returns error: "openssl encryption failed: ..." | Check if openssl is properly installed |
Example Conversation
User: Back up my SOUL.md and MEMORY.md
Claude: I'll backup these files with auto-generated encryption.
[Executes backup script]
Backup complete!
- Backup ID: 3f8a2b1c-...
- Size: 45.2 KB
- Password: Auto-generated (32 chars)
- Recovery info saved to .openclaw-backup-recovery.txt
IMPORTANT: Keep .openclaw-backup-recovery.txt safe!
It contains the password needed to restore this backup.
Workflow 2: Download Backup
Trigger Scenarios
Execute when user requests to restore backup:
- "Restore my backup"
- "Download my last backup"
- "Recover backup [backup-id]"
- "Restore from [download-url]"
Execution Steps
-
Get Backup ID and Password
- Check if user provided Backup ID or Download URL
- If not provided, use Read tool to read
.openclaw-backup-recovery.txt - Extract latest Backup ID AND password from file
- If file doesn't exist or is empty, cannot proceed (password unknown)
-
Determine Output Directory
- Default: Current working directory (
.) - If user specified a directory, use user-specified directory
- Warn user: Existing files may be overwritten
- Default: Current working directory (
-
Execute Restore Script
- Execute command with password from recovery file:
python3 scripts/backup.py download \ --backup-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \ --password "password-from-recovery-file" \ --output-dir "." - Capture stdout (JSON response) and stderr (progress info)
- Execute command with password from recovery file:
-
Process Response
- On success, script outputs JSON:
{ "success": true, "extractedFiles": ["SOUL.md", "MEMORY.md", "IDENTITY.md"], "outputDir": "/path/to/output" } - Parse extracted file list
- On success, script outputs JSON:
-
Verify Restoration Result
- Use Read tool to read first few lines of restored files
- Show file preview for user to confirm content is correct
- Remind user to check complete content
-
Display Success Message
- List restored files
- Show output directory
- Suggest user verify file content
Error Handling
| Error Scenario | Detection | User Guidance |
|---|---|---|
| Backup ID doesn't exist | Script returns error: "Backup not found: ..." | Check if Backup ID is correct, may have been deleted |
| Recovery file missing | .openclaw-backup-recovery.txt not found |
Cannot restore - password is unknown without recovery file |
| Wrong password | Script returns error: "Decryption failed - wrong password ..." | Recovery file may be corrupted or from different backup |
| Network error | Script returns error: "Network error: ..." | Suggest checking network connection, ask if retry is wanted |
| Extraction failed | Script returns error: "tar extraction failed: ..." | File may be corrupted, try downloading again |
Example Conversation
User: Restore my last backup
Claude: I found the most recent backup in .openclaw-backup-recovery.txt
- Backup ID: 3f8a2b1c-...
- Created: 2024-01-15 10:30:00 UTC
Downloading and decrypting backup...
Restoration complete! Extracted the following files:
- SOUL.md
- MEMORY.md
- IDENTITY.md
Files saved to current directory, please verify content is correct.
Workflow 3: Delete Backup
Trigger Scenarios
Execute when user requests to delete remote backup:
- "Delete my backup"
- "Remove backup [backup-id]"
- "Delete the backup from soul-upload"
Execution Steps
-
Get Backup ID
- Check if user provided Backup ID
- If not provided, use Read tool to read
.openclaw-backup-recovery.txt - Show available backup list for user to select
- If file doesn't exist or is empty, ask user to provide Backup ID
-
Request Confirmation
- Warning: This operation is irreversible, backup will be permanently deleted
- Show Backup ID to delete and creation time
- Ask user to confirm deletion
-
Execute Delete Script
- After user confirms, execute command:
python3 scripts/backup.py delete \ --backup-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - Capture stdout (JSON response) and stderr (progress info)
- After user confirms, execute command:
-
Process Response
- On success, script outputs JSON:
{ "success": true, "backupId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
- On success, script outputs JSON:
-
Update Recovery Info File
- Use Read tool to read
.openclaw-backup-recovery.txt - Remove deleted backup record (including its password)
- Use Write tool to save updated file
- If file becomes empty, can delete the file
- Use Read tool to read
-
Display Success Message
- Confirm backup was deleted
- Show deleted Backup ID
- Remind user: If backup is needed again, must create new one with new password
Error Handling
| Error Scenario | Detection | User Guidance |
|---|---|---|
| Backup ID doesn't exist | Script returns error: "Backup not found: ..." | Backup may have been deleted or ID is incorrect |
| Network error | Script returns error: "Network error: ..." | Suggest checking network connection, ask if retry is wanted |
| User cancels | User declines confirmation | Operation cancelled, backup not deleted |
Example Conversation
User: Delete my backup
Claude: I found the following backups in .openclaw-backup-recovery.txt:
1. Backup ID: 3f8a2b1c-... (2024-01-15 10:30:00)
2. Backup ID: 7b2c9d4e-... (2024-01-14 08:20:00)
Which backup would you like to delete? (1 or 2)
User: 1
Claude: Warning: This will permanently delete backup 3f8a2b1c-...
This action cannot be undone. Confirm deletion? (yes/no)
User: yes
Claude: Backup deleted.
- Backup ID: 3f8a2b1c-...
To backup again, create a new backup with a new auto-generated password.
Security Notes
Password Policy (NEW)
- Auto-Generated Passwords: Each backup gets a unique 32-character random password
- Never Reuse Passwords: Per soul-upload.com policy, do NOT reuse passwords across backups
- Password Storage: Password is stored in
.openclaw-backup-recovery.txt(necessary for decryption) - User Responsibility: Users must keep recovery file safe - without it, backup cannot be restored
Recovery File Security
- File Location:
.openclaw-backup-recovery.txt(workspace root directory) - Content: Backup ID, Password (CRITICAL), Download URL, timestamp, SHA256
- CRITICAL: Recovery file is the ONLY place password is stored
- Recommendation:
- Add to
.gitignoreif sensitive - OR commit to version control for team access
- Consider backing up recovery file itself to separate secure location
- Add to
Encryption Algorithm
- Algorithm: AES-256-CBC (symmetric encryption)
- Salting: openssl automatically adds salt for enhanced security
- Compatibility: Consistent with soul-upload.com official documentation
Temporary File Cleanup
- Script uses try-finally to ensure temporary files are cleaned up
- Avoids leaving unencrypted sensitive data on disk
File Size Limits
- Maximum Backup Size: 20 MB (compressed and encrypted)
- Check Timing: Automatically checked before upload
- Limit Exceeded Handling: Show actual size, suggest user:
- Remove large files (like logs, caches)
- Split backup (backup different files in batches)
API Reference
soul-upload.com Backup API:
| Endpoint | Method | Function | Response |
|---|---|---|---|
/backup |
POST | Upload backup | {backupId, downloadUrl, sizeBytes, sha256} |
/backup/:backupId |
GET | Download backup | 302 redirect to R2 storage URL |
/backup/:backupId |
DELETE | Delete backup | {success: true, backupId} |
Common Status Codes:
- 200 - Success
- 404 - Backup not found
- 413 - File too large (exceeds 20MB)
- 415 - Unsupported file type
- 500 - Server error
Troubleshooting
Missing Dependencies
Problem: Script error "Missing required tools: tar, openssl"
Solution:
- macOS:
brew install openssl(tar built-in) - Ubuntu/Debian:
sudo apt-get install tar openssl - Verify installation:
tar --versionandopenssl version
Python requests Library Missing
Problem: Script error "Error: 'requests' library not found"
Solution:
pip install requests
# or
pip3 install requests
Recovery File Lost
Problem: Cannot restore backup - recovery file missing
Solution:
- Recovery file is CRITICAL - contains the only copy of the password
- Without recovery file, backup CANNOT be restored
- Recommend backing up recovery file to separate secure location
- If lost, backup is permanently inaccessible
Network Timeout
Problem: Timeout during upload/download
Solution:
- Check network connection
- Reduce backup file size (remove unnecessary files)
- Script default timeout is 5 minutes, usually sufficient
File Already Exists
Problem: Overwriting existing files during restore
Solution:
- Backup existing files before restore
- Specify different output directory
- Manually move existing files to other location
Usage Examples
Example 1: Backup All Default Files
User: Back up my workspace files
Claude: [Execute upload workflow using default file list]
[Auto-generate password and save to recovery file]
Example 2: Backup Specific Files
User: Back up only SOUL.md and MEMORY.md
Claude: [Execute upload workflow, backup only specified files]
[Auto-generate password and save to recovery file]
Example 3: Restore Latest Backup
User: Restore my last backup
Claude: [Read latest Backup ID and password from .openclaw-backup-recovery.txt]
[Execute download workflow]
Example 4: Restore Specific Backup
User: Restore backup 3f8a2b1c-1234-5678-90ab-cdef12345678
Claude: [Read password for this Backup ID from recovery file]
[Execute download workflow]
Example 5: Delete Old Backups
User: Delete my old backups
Claude: [Show available backup list from recovery file]
[User selects backup to delete]
[Execute delete workflow]
[Remove entry from recovery file]
Best Practices
- Regular Backups: Recommend weekly backups or after important changes
- Recovery File Management: Keep
.openclaw-backup-recovery.txtsafe and backed up separately - Verify Restoration: Regularly test backup restoration process to ensure backups are usable
- Clean Old Backups: Regularly delete unneeded old backups to save storage space
- Multiple Copies: Consider keeping recovery file in multiple secure locations
Script Path
Script file is located in Skill directory at scripts/backup.py.
When executing Bash commands, ensure correct relative or absolute path is used. Usually:
- If currently in Skill directory:
python3 scripts/backup.py ... - If in other directory: Use absolute path or
cdto Skill directory first
Reference Documentation
Version: 2.0.0 Author: Claude Code License: MIT Password Policy: Auto-generated unique password per backup (NEW in v2.0.0)