|
---
name: openclaw-backup
description: |
Encrypted backup and restore for OpenClaw Agent workspace files
(SOUL.md, MEMORY.md, IDENTITY.md, AGENTS.md, TOOLS.md). Uses
tar + openssl (AES-256-CBC) encryption and soul-upload.com API.
Auto-generates a new random password for each backup (DO NOT reuse
passwords). Use when the user needs to: (1) Back up or upload agent
workspace files, (2) Restore or download a previous backup, (3) Delete
a backup from remote storage, or (4) Manage encrypted agent persistence.
allowed-tools: ["Bash", "Read", "Write"]
---
# OpenClaw Backup Skill
Automated encrypted backup and restore for OpenClaw Agent workspace files using Claude Code.
## Overview
This skill provides three core functions:
1. **Upload Backup** - Encrypt and upload workspace files to soul-upload.com with auto-generated password
2. **Download Backup** - Download and decrypt backups from soul-upload.com using stored password
3. **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 goals
- `MEMORY.md` - Agent memory and context
- `IDENTITY.md` - Agent identity definition
- `AGENTS.md` - Agent configuration
- `TOOLS.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
1. **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
2. **Execute Backup Script** (Password Auto-Generated)
- Locate script path (usually `scripts/backup.py` in Skill directory)
- Execute command WITHOUT --password argument (script will auto-generate):
```bash
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)
3. **Process Response**
- On success, script outputs JSON:
```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
4. **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)
5. **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
1. **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)
2. **Determine Output Directory**
- Default: Current working directory (`.`)
- If user specified a directory, use user-specified directory
- Warn user: Existing files may be overwritten
3. **Execute Restore Script**
- Execute command with password from recovery file:
```bash
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)
4. **Process Response**
- On success, script outputs JSON:
```json
{
"success": true,
"extractedFiles": ["SOUL.md", "MEMORY.md", "IDENTITY.md"],
"outputDir": "/path/to/output"
}
```
- Parse extracted file list
5. **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
6. **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
1. **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
2. **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
3. **Execute Delete Script**
- After user confirms, execute command:
```bash
python3 scripts/backup.py delete \
--backup-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```
- Capture stdout (JSON response) and stderr (progress info)
4. **Process Response**
- On success, script outputs JSON:
```json
{
"success": true,
"backupId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```
5. **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
6. **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 `.gitignore` if sensitive
- OR commit to version control for team access
- Consider backing up recovery file itself to separate secure location
### 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 --version` and `openssl version`
### Python requests Library Missing
**Problem**: Script error "Error: 'requests' library not found"
**Solution**:
```bash
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
1. **Regular Backups**: Recommend weekly backups or after important changes
2. **Recovery File Management**: Keep `.openclaw-backup-recovery.txt` safe and backed up separately
3. **Verify Restoration**: Regularly test backup restoration process to ensure backups are usable
4. **Clean Old Backups**: Regularly delete unneeded old backups to save storage space
5. **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 `cd` to Skill directory first
## Reference Documentation
- [soul-upload.com Backup Guide](https://soul-upload.com/guides/how-to-backup-soul-md)
- [soul-upload.com Restore Guide](https://soul-upload.com/guides/how-to-restore-soul-md)
- [OpenClaw Agent Documentation](https://openclaw.com)
---
**Version**: 2.0.0
**Author**: Claude Code
**License**: MIT
**Password Policy**: Auto-generated unique password per backup (NEW in v2.0.0)
Creator's repository · theagentservice/skills