Healthy Backup
Version: 1.3.0
A health-first backup skill for OpenClaw.
Before touching a single file, healthy-backup audits your rig. If anything critical is broken, it aborts with a clear report. No silent snapshots of a broken state.
How it works
- 1. Health audit — checks required binaries, config integrity, key directories, disk space, encryption readiness, secrets file permissions, and optional rclone remote
- Hard block — any failing check aborts the backup immediately with a full report
- Stage — collects files for your chosen tier; secret-bearing paths are always excluded (see Secrets policy)
- Compress → Encrypt (AES256 GPG) → Save
- Prune — keeps the last N healthy backups; older archives are deleted
- Sync (optional) — pushes to your configured rclone remote
Run with --dry-run to execute the full audit and see exactly what would be staged — without writing anything.
Secrets policy (enforced in code)
openclaw.json — scrubbed before staging
INLINECODE2 is never copied verbatim. Before staging, the script uses jq walk() to replace the value of any field whose name contains password, token, secret, or key with "<redacted>". Config structure and all non-sensitive values are preserved. The live file on disk is never modified.
Recommendation: store your backup password in ~/.openclaw/credentials/backup.key (chmod 600) rather than inline in openclaw.json. The health audit will warn if an inline password is detected.
rsync exclusions — always applied, no config override
The following paths are hard-excluded from rsync at every tier:
CODEBLOCK0
Secrets manifest
At all tiers the script reads openclaw-secrets.env to extract variable names only — values are never written. The resulting secrets-manifest.txt lists what environment variables your rig expects, useful for rebuilding on a new machine.
GPG passphrase
Written to a chmod 600 temp file and passed to GPG via --passphrase-file — never on the CLI, never visible in ps. Deleted via trap EXIT on success or failure.
What this script reads
This section lists every file and system call the script makes, so there are no surprises:
| What | Why | Sensitive? |
|---|
| INLINECODE17 | Load config + stage (scrubbed copy) | Sensitive fields redacted before staging |
| INLINECODE18 |
Extract variable
names for manifest | Values never written; file never copied |
|
~/.openclaw/credentials/backup.key | Load encryption password | Read into memory only; file excluded from rsync |
|
~/.openclaw/ (migratable+) | rsync to staging | Secrets paths hard-excluded |
| Workspace + skills dirs (full tier) | rsync to staging | Secrets paths hard-excluded |
|
command -v <bin> | Check required binaries exist | No |
|
df -m $HOME | Check available disk space | No |
|
ollama list (audit + opt-in manifest) | Check models loaded / list for DEPENDENCIES.md | Model names only |
|
npm list -g (opt-in, default off) | List global packages for DEPENDENCIES.md | Can reveal installed tooling |
|
crontab -l (opt-in, default off) | List cron jobs for DEPENDENCIES.md | VAR=values redacted before writing |
|
rclone listremotes (if uploadMode=rclone) | Verify configured remote exists | No |
|
rclone sync (if uploadMode=rclone) | Upload encrypted archives | Transfers only
*.gpg files |
No network calls are made by the script itself beyond rclone when explicitly configured.
| Tier | What's included |
|---|
| INLINECODE30 | INLINECODE31 + secrets manifest (key names only) |
| INLINECODE32 |
Everything in minimal +
~/.openclaw (secrets excluded) +
DEPENDENCIES.md |
|
full | Everything in migratable + workspace + skills (secrets excluded in all) |
Default tier: INLINECODE36
DEPENDENCIES.md
Generated for migratable and full tiers. By default, only binary versions and OS info are collected. Sensitive system state (crontab, npm globals) requires explicit opt-in:
| Config key | Default | What it collects |
|---|
| INLINECODE39 | INLINECODE40 | Installed Ollama model names |
| INLINECODE41 |
false |
npm list -g --depth=0 output |
|
collectCrontab |
false | Crontab — values after
= are redacted before staging |
Even when collectCrontab is enabled, any VAR=VALUE patterns in cron lines are replaced with VAR=<REDACTED> before the file is written.
Setup
1. Run the setup wizard
CODEBLOCK1
The wizard will ask about tier, backup location, retention, cloud sync, and optional collectors. It writes config to ~/.openclaw/config/healthy-backup/hb-config.json, creates your encryption key file if needed, runs a dry-run automatically, and optionally installs the cron job — all in one flow.
To reconfigure at any time, just run bash setup.sh again.
2. System dependencies
CODEBLOCK2
For rclone (only required when uploadMode = rclone):
CODEBLOCK3
These are OS-level binaries, listed in skill metadata for dependency checking only — not as npm packages.
2. Encryption password (choose one — in priority order)
CODEBLOCK4
The health audit checks that backup.key has permissions 600 and will hard-fail if it does not.
3. Install the script
CODEBLOCK5
4. Schedule with cron (Linux)
CODEBLOCK6
Example — daily at 03:00:
CODEBLOCK7
Configuration
All config lives in ~/.openclaw/openclaw.json under skills.entries["healthy-backup"].config.
CODEBLOCK8
Do not add a password field here. Although the script scrubs it from the backup copy, the value would still exist in your live openclaw.json on disk. Use ~/.openclaw/credentials/backup.key (chmod 600) instead — it is excluded from staging entirely.
### Full configuration reference
| Key | Env var | Default | Description |
|-----|---------|---------|-------------|
| `backupTier` | `BACKUP_TIER` | `migratable` | `minimal` / `migratable` / `full` |
| `backupRoot` | `BACKUP_ROOT` | `~/openclaw-backups` | Local backup storage directory |
| `uploadMode` | `UPLOAD_MODE` | `local-only` | `local-only` or `rclone` |
| `remoteDest` | `REMOTE_DEST` | _(none)_ | rclone destination e.g. `gdrive:backups` |
| `maxBackups` | `MAX_BACKUPS` | `5` | Healthy backups to retain |
| `minDiskMb` | `MIN_DISK_MB` | `500` | Minimum free disk (MB) required |
| `skillsDir` | `SKILLS_DIR` | `~/.openclaw/skills` | Skills directory |
| `collectOllama` | `COLLECT_OLLAMA` | `true` | Include Ollama model list in DEPENDENCIES.md |
| `collectNpm` | `COLLECT_NPM` | `false` | Include npm globals in DEPENDENCIES.md (opt-in) |
| `collectCrontab` | `COLLECT_CRONTAB` | `false` | Include sanitised crontab in DEPENDENCIES.md (opt-in) |
| `password` | `BACKUP_PASSWORD` | _(none)_ | ⚠ Discouraged — prefer key file; if set, value is scrubbed from backup copy but remains in live config |
**Priority:** Config file → Env var → Auto-detect
---
## Health checks
| Check | Behaviour |
|-------|-----------|
| Required binaries (`tar`, `gpg`, `jq`, `rsync`) | Hard fail |
| `rclone` present (if `uploadMode = rclone`) | Hard fail |
| `openclaw.json` is valid JSON | Hard fail |
| Key directories exist (OpenClaw dir, workspace) | Hard fail |
| Free disk ≥ `minDiskMb` | Hard fail |
| Encryption password available | Hard fail |
| `backup.key` permissions = 600 (if file exists) | Hard fail |
| Secrets file permissions = 600 (if file exists) | Hard fail |
| rclone remote reachable (if `uploadMode = rclone`) | Hard fail |
| Skills dir present | Warn only |
| Ollama models loaded | Warn only |
| No agents in config | Warn only |
---
## Archive contents
config/openclaw.json ← always present
config/secrets-manifest.txt ← key names only, no values (migratable+)
openclaw/ ← ~/.openclaw minus secrets paths (migratable+)
workspace/ ← workspace minus secrets paths (full only)
skills/ ← skills minus secrets paths (full only)
DEPENDENCIES.md ← system snapshot (migratable+, opt-in fields)
HEALTH_REPORT.txt ← full audit log from backup time
---
## Verifying the script
After downloading, verify the script has not been modified:
bash
sha256sum healthy-backup.sh
Compare the output against the checksum published in the skill's release or provided by the author. The script also prints its own SHA256 on every successful run so you can confirm the installed version matches what ran.
---
## Restore
bash
gpg --batch --passphrase-file /path/to/backup.key \
--decrypt healthy-backup-YYYYMMDD-HHMMSS-migratable.tgz.gpg \
| tar -xzf - -C /restore/target
---
## Security checklist
- [ ] `backup.key` exists and has `chmod 600`
- [ ] `openclaw-secrets.env` has `chmod 600`
- [ ] Backup root directory is not world-readable
- [ ] If using rclone cloud sync: prefer `rclone crypt` remote for an additional encryption layer
- [ ] Tested decryption of at least one archive before relying on backups
- [ ] `collectCrontab` and `collectNpm` left `false` unless you specifically need them
---
## Credits
Inspired by and building on:
- **simple-backup** by VACInc — GPG + rclone pattern, config resolution hierarchy
- **claw-backup** by vidarbrekke — tier thinking, dependency manifests, restore notes
---
## License
MIT
---
## Release checksums (v1.3.0)
Verify your downloaded files match these SHA256 hashes before running:
a8e0f8e922c05755a43a8bb156a327984d9fbc50a620ce08e172a48d72f79a39 healthy-backup.sh
ae0bda0195e408aee84f441a39494995f8cd1eb5578eba07d0870810d6ad1433 verify-backup.sh
185fa27b052ed1c9d294f4d40a7700a501683906b0d6d2e75ab059532decbd4f setup.sh
bash
sha256sum healthy-backup.sh verify-backup.sh setup.sh
```
健康备份
版本: 1.3.0
一个面向OpenClaw的健康优先备份技能。
在触碰任何文件之前,healthy-backup会审计您的设备。如果任何关键组件损坏,它将中止操作并生成清晰的报告。不会对损坏状态进行静默快照。
工作原理
- 1. 健康审计 — 检查必需的二进制文件、配置完整性、关键目录、磁盘空间、加密就绪状态、密钥文件权限以及可选的rclone远程连接
- 硬阻断 — 任何失败的检查都会立即中止备份并生成完整报告
- 暂存 — 收集您所选层级所需的文件;包含密钥的路径始终被排除(参见密钥策略)
- 压缩 → 加密(AES256 GPG)→ 保存
- 清理 — 保留最近N个健康备份;旧归档文件将被删除
- 同步(可选)— 推送到您配置的rclone远程位置
使用--dry-run参数运行可执行完整审计,并查看将要暂存的内容——不会写入任何内容。
密钥策略(代码中强制执行)
openclaw.json — 暂存前进行脱敏处理
openclaw.json 从不直接复制。在暂存前,脚本使用jq walk()将任何名称包含password、token、secret或key的字段的值替换为。配置结构和所有非敏感值都会被保留。磁盘上的实时文件不会被修改。
建议: 将备份密码存储在~/.openclaw/credentials/backup.key(chmod 600)中,而不是直接写在openclaw.json中。健康审计会在检测到内联密码时发出警告。
rsync排除项 — 始终应用,不可通过配置覆盖
以下路径在所有层级中都被硬性排除在rsync之外:
~/.openclaw/shared/secrets/
~/.openclaw/credentials/
/.key /.pem /.env /.secret /.env
密钥清单
在所有层级中,脚本读取openclaw-secrets.env仅提取变量名称 — 值从不写入。生成的secrets-manifest.txt列出了您的设备所需的环境变量,有助于在新机器上重建。
GPG密码短语
写入一个chmod 600的临时文件,并通过--passphrase-file传递给GPG — 从不通过命令行传递,在ps中不可见。在成功或失败时通过trap EXIT删除。
此脚本读取的内容
本节列出了脚本进行的每个文件和系统调用,以确保没有意外:
| 内容 | 原因 | 敏感? |
|---|
| ~/.openclaw/openclaw.json | 加载配置并暂存(脱敏副本) | 敏感字段在暂存前被脱敏 |
| ~/.openclaw/shared/secrets/openclaw-secrets.env |
提取变量
名称用于清单 | 值从不写入;文件从不复制 |
| ~/.openclaw/credentials/backup.key | 加载加密密码 | 仅读入内存;文件被排除在rsync之外 |
| ~/.openclaw/(可迁移+) | rsync到暂存区 | 密钥路径被硬性排除 |
| 工作区 + 技能目录(完整层级) | rsync到暂存区 | 密钥路径被硬性排除 |
| command -v
| 检查必需的二进制文件是否存在 | 否 |
| df -m $HOME | 检查可用磁盘空间 | 否 |
| ollama list(审计 + 可选清单) | 检查已加载的模型 / 列出用于DEPENDENCIES.md | 仅模型名称 |
| npm list -g(可选,默认关闭) | 列出全局包用于DEPENDENCIES.md | 可能暴露已安装的工具 |
| crontab -l(可选,默认关闭) | 列出cron任务用于DEPENDENCIES.md | 写入前将VAR=值脱敏 |
| rclone listremotes(如果uploadMode=rclone) | 验证配置的远程位置是否存在 | 否 |
| rclone sync(如果uploadMode=rclone) | 上传加密归档文件 | 仅传输*.gpg文件 |
脚本本身不会进行任何网络调用,除非明确配置了rclone。
| 层级 | 包含内容 |
|---|
| minimal | openclaw.json + 密钥清单(仅键名) |
| migratable |
minimal中的所有内容 + ~/.openclaw(排除密钥)+ DEPENDENCIES.md |
| full | migratable中的所有内容 + 工作区 + 技能(所有层级均排除密钥) |
默认层级:migratable
DEPENDENCIES.md
为migratable和full层级生成。默认情况下,仅收集二进制版本和操作系统信息。敏感系统状态(crontab、npm全局包)需要明确选择加入:
| 配置键 | 默认值 | 收集内容 |
|---|
| collectOllama | true | 已安装的Ollama模型名称 |
| collectNpm |
false | npm list -g --depth=0输出 |
| collectCrontab | false | Crontab — =后的值在暂存前被脱敏 |
即使启用了collectCrontab,cron行中的任何VAR=VALUE模式在写入文件前都会被替换为VAR=。
设置
1. 运行设置向导
bash
chmod +x setup.sh healthy-backup.sh verify-backup.sh
bash setup.sh
向导会询问层级、备份位置、保留策略、云同步和可选收集器。它会将配置写入~/.openclaw/config/healthy-backup/hb-config.json,在需要时创建加密密钥文件,自动运行一次dry-run,并可选择安装cron任务 — 全部在一个流程中完成。
如需随时重新配置,只需再次运行bash setup.sh。
2. 系统依赖
bash
sudo apt install tar gpg jq rsync # Debian/Ubuntu
sudo dnf install tar gpg jq rsync # Fedora/RHEL
对于rclone(仅在uploadMode = rclone时需要):
bash
推荐 — 包管理器:
sudo apt install rclone # Debian/Ubuntu
sudo dnf install rclone # Fedora/RHEL
备选 — 官方二进制文件。下载并在运行前检查:
curl -fsSL https://rclone.org/install.sh -o rclone-install.sh
cat rclone-install.sh # 先查看内容
sudo bash rclone-install.sh
不要在不查看脚本的情况下直接将curl输出管道到bash。
这些是操作系统级别的二进制文件,仅在技能元数据中列出用于依赖检查 — 不是作为npm包。
2. 加密密码(选择一种 — 按优先级排序)
bash
推荐:具有严格权限的密钥文件
mkdir -p ~/.openclaw/credentials
echo your-strong-password > ~/.openclaw/credentials/backup.key
chmod 600 ~/.openclaw/credentials/backup.key
或者:环境变量
export BACKUP_PASSWORD=your-strong-password
或者:在技能配置中内联(最不推荐 — 参见配置部分)
健康审计会检查backup.key的权限是否为600,如果不是则会硬性失败。
3. 安装脚本
bash
放在您存放脚本的任何位置:
chmod +x /path/to/healthy-backup.sh
推荐:在计划任务前进行测试运行 — 审计设备并显示将要暂存的内容:
/path/to/healthy-backup.sh --dry-run
4. 使用cron计划任务(Linux)
bash
crontab -e
示例 — 每天03:00:
0 3 * /path/to/healthy-backup.sh >> ~/.openclaw/logs/healthy-backup.log 2>&1
配置
所有配置都位于~/.openclaw/openclaw.json的skills.entries[healthy-backup].config下。
json
{
skills: {
entries: {
healthy-backup: {
config: {
backupTier: migratable,
backupRoot: ~/openclaw-backups,
uploadMode: local-only,
remoteDest: gdrive:openclaw-backups,
maxBackups: 5,
minDiskMb: 500