← Back to PRs

#13988: feat(backup): add backup/restore CLI with local + S3 storage

by n24q02m open 2026-02-11 09:08 View on GitHub →
cli size: XL
## Summary Implements [Issue #13616](https://github.com/openclaw/openclaw/issues/13616): comprehensive backup and restore system for OpenClaw. ## New Modules | File | Purpose | |------|---------| | `src/backup/types.ts` | Core types, `StorageBackend` interface, config types | | `src/backup/storage/local.ts` | Local filesystem storage backend | | `src/backup/storage/s3.ts` | S3-compatible storage (AWS, R2, MinIO, GCS) | | `src/backup/storage/factory.ts` | Pluggable backend factory | | `src/backup/manifest.ts` | Manifest creation, validation, SHA-256 integrity | | `src/backup/crypto.ts` | AES-256-GCM encryption via `node:crypto` | | `src/backup/collector.ts` | File collection with secrets redaction | | `src/backup/export.ts` | Export orchestration (collect -> tar.gz -> store) | | `src/backup/import.ts` | Import/restore with dry-run and cron merge | | `src/cli/backup-cli.ts` | CLI commands: export, import, list, restore | ## Features - **Local and S3 storage backends** — supports AWS S3, Cloudflare R2, MinIO, GCS via endpoint config - **AES-256-GCM encryption** with PBKDF2 key derivation (zero external deps) - **SHA-256 integrity verification** via manifest checksums - **Secrets redaction** — API keys stripped from config backups - **Dry-run mode** for safe restore preview - **Cron job merge** — intelligently merge instead of overwrite - **Sidecar manifests** for quick backup listing without downloading archives - **Pluggable architecture** — easy to add new storage backends ## Usage ```bash # Export backup (local) openclaw backup export -o my-backup.tar.gz # Export with encryption openclaw backup export -o my-backup.tar.gz -e mypassphrase # Export specific components openclaw backup export -c config,workspace,cron # List backups openclaw backup list # Restore (dry-run) openclaw backup import my-backup.tar.gz --dry-run # Restore for real openclaw backup restore my-backup.tar.gz # Restore with decryption and cron merge openclaw backup import my-backup.tar.gz -d mypassphrase --merge ``` ## Components Backed Up | Component | Files | |-----------|-------| | `config` | `openclaw.json` (secrets redacted) | | `workspace` | `SOUL.md`, `MEMORY.md`, `memory/`, `skills/`, `USER.md` | | `cron` | `cron/jobs.json` | | `skills` | `~/.openclaw/skills/` | | `sessions` | `sessions.json` | | `approvals` | `exec-approvals.json` | | `pairing` | `~/.openclaw/pairing/` | ## Modified Files - `src/cli/program/register.subclis.ts` — added `backup` subcli entry ## Testing - Format check: `oxfmt --check` passes - No external dependencies required (S3 SDK is optional/lazy-loaded) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds a new `openclaw backup` sub-CLI with export/import/list/restore commands, plus a backup subsystem (file collector, manifest + integrity checks, optional AES-256-GCM encryption) and two storage backends (local filesystem and optional S3 via lazy-loaded AWS SDK). The overall structure fits the existing CLI registration pattern (`register.subclis.ts`) and reuses existing path resolution helpers and archive extraction utilities, but there are a few correctness/security issues that should be addressed before merging (notably tar extraction safety, and aligning cron store restore with the existing cron store IO semantics). <h3>Confidence Score: 2/5</h3> - This PR should not be merged as-is due to a confirmed unsafe tar extraction path traversal in the restore flow. - The backup/restore feature is substantial and generally coherent, but `import/restore` currently extracts tar archives without validating entry paths, enabling arbitrary file writes outside the intended directory. There are also correctness issues around cron store merge IO semantics and S3 prefix handling that will impact real users. - src/backup/import.ts, src/infra/archive.ts, src/backup/storage/s3.ts <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs