← Back to Plugins
Tools

B2 Sync Backup

backblaze-b2-samples By backblaze-b2-samples 👁 27 views ▲ 0 votes

OpenClaw automatic backup and sync to Backblaze B2. Keep state durable across machines, restore instantly on new hardware, and roll back to previous snapshots if configs break or memory becomes corrupted.

Homepage GitHub

Install

openclaw plugins install @openclaw/b2-backup

Configuration Example

{
  "plugins": {
    "entries": {
      "b2-backup": {
        "enabled": true,
        "config": {
          "keyId": "004a...",
          "applicationKey": "K004...",
          "bucket": "my-openclaw-backups"
        }
      }
    }
  }
}

README

# OpenClaw B2 Backup

> Automatic encrypted backup and sync of [OpenClaw](https://github.com/openclaw/openclaw) state to [Backblaze B2](https://www.backblaze.com/cloud-storage). Install the plugin, set 3 fields, restart your gateway — backups happen automatically.

## What Is OpenClaw B2 Backup?

OpenClaw B2 Backup is a plugin that snapshots your entire OpenClaw state directory to Backblaze B2 on a schedule. It uses incremental SHA-256 diffing and AES-256-GCM encryption so only changed files are uploaded and everything is encrypted at rest. If something goes wrong — corrupted config, lost memory, bad compaction — you restore from a timestamped snapshot or ask your agent to roll back from chat.

### Problem

OpenClaw state is plain files on disk. One bad edit, a misinterpreted agent instruction, or an aggressive compaction can permanently destroy config, memory, and session history. There's no built-in undo, and manual backup scripts don't know how to safely snapshot SQLite databases mid-flight.

### Solution

This plugin runs inside the gateway process, uses SQLite's `.backup()` API for consistent database snapshots, and pushes incremental encrypted diffs to B2. It triggers automatically on schedule, before compaction, and on shutdown. On a new machine, it auto-restores from the latest snapshot on first start.

### Who Should Use This

Anyone running OpenClaw who wants automatic off-machine backups without managing scripts, cron jobs, or external tools like restic/rclone.

## Key Features

- **Encrypted by default** — AES-256-GCM with per-file random salt/IV, key derived from your B2 application key via scrypt
- **Incremental sync** — SHA-256 manifest diffing; only changed files are uploaded
- **Safe SQLite snapshots** — uses `.backup()` API, no half-written databases
- **Auto-restore on new machines** — detects empty state dir on start, pulls latest snapshot automatically
- **Safety snapshots before rollback** — creates a restore point before any pull, stored out-of-band and never auto-pruned
- **Compaction protection** — triggers a push before compaction fires (5-minute debounce to prevent rapid-fire)
- **Conversational rollback** — `b2_rollback` agent tool lets you list and restore snapshots from chat
- **Zero runtime dependencies** — hand-rolled S3 Sig V4 client, uses only `node:crypto` and OpenClaw's bundled `croner`
- **Backward-compatible decryption** — auto-detects unencrypted data and passes through, so enabling encryption doesn't break old snapshots

## Quick Start

### 1. Install

```bash
openclaw plugins install @openclaw/b2-backup
```

### 2. Configure

Add to your `openclaw.json` (or use the Control UI):

```json
{
  "plugins": {
    "entries": {
      "b2-backup": {
        "enabled": true,
        "config": {
          "keyId": "004a...",
          "applicationKey": "K004...",
          "bucket": "my-openclaw-backups"
        }
      }
    }
  }
}
```

### 3. Restart

```bash
openclaw gateway restart
```

That's it. Region is auto-detected, encryption is on by default, and the first backup runs at midnight.

## Configuration

All optional beyond the 3 required fields:

| Setting | Type | Default | Required | Description |
|---------|------|---------|----------|-------------|
| `keyId` | string | — | Yes | B2 application key ID |
| `applicationKey` | string | — | Yes | B2 application key (also used as encryption key source) |
| `bucket` | string | — | Yes | B2 bucket name |
| `region` | string | Auto-detected | No | B2 region (derived from key if omitted) |
| `prefix` | string | `"openclaw-backup"` | No | Object key prefix in the bucket |
| `schedule` | string | `"daily"` | No | `"daily"`, `"weekly"`, or a cron expression |
| `encrypt` | boolean | `true` | No | AES-256-GCM encryption before upload |
| `keepSnapshots` | number | `10` | No | Snapshots retained; oldest auto-pruned |

## What Gets Synced

Everything that makes your OpenClaw instance *yours*:

| Data | Path | Why |
|------|------|-----|
| Config | `openclaw.json` (+`.bak` rotation) | Your setup — channels, models, agent bindings |
| Workspace | `workspace/**`, `workspace-*/**` | SOUL.md, AGENTS.md, MEMORY.md, custom instructions |
| Sessions | `agents/*/sessions/*.jsonl` | Conversation history |
| Session store | `agents/*/sessions/sessions.json` | Routing metadata |
| Memory DB | `agents/*/memory/*.sqlite` | Long-term knowledge (vector search index) |
| Agent state | `agents/*/agent/**` | Agent runtime config (minus auth profiles) |
| Cron jobs | `cron/**` | Scheduled tasks |
| Hooks | `hooks/**` | Custom hook scripts |

### Not Synced (by design)

- **`credentials/`** and **`auth-profiles.json`** — secrets stay per-machine; re-auth on new machines
- **`media/`** — ephemeral (2-min TTL), not worth syncing
- **`extensions/`** — install plugins independently per machine
- **`*.lock`**, **`*.tmp`**, **`*-wal`**, **`*-shm`** — transient files

## Common Scenarios

### Your agent forgot everything after compaction

Compaction rewrites your session transcript to save context window space. If important context lived only in the chat history and wasn't captured in MEMORY.md or the memory DB, it's gone.

With this plugin, a snapshot is automatically taken *before* compaction fires. Roll back from chat:

> "Show me my B2 backup snapshots and restore the one from before compaction"

### You (or your agent) deleted MEMORY.md

OpenClaw memory is plain Markdown files on disk. A single misinterpreted instruction can permanently delete them. With daily snapshots in B2, you restore MEMORY.md from the last known-good version.

### Config got corrupted or you broke a channel integration

One bad edit and you're rebuilding from scratch — re-onboarding channels, re-pairing devices, re-teaching your agent. With this plugin, you restore the entire state directory from a snapshot instead.

### You suspect a malicious skill compromised your setup

Restore from a pre-compromise snapshot, rotate your secrets, and you're back to a known-good state. The timestamped snapshots in B2 give you a clear timeline of what your state looked like before and after the incident.

### Moving to a new machine

```bash
openclaw plugins install @openclaw/b2-backup
# Add the same 3 config fields to openclaw.json
openclaw gateway restart
# Plugin detects empty state + existing snapshots → auto-restores latest
```

Your new machine has the same memory, sessions, config, and personality as the old one. No manual file copying.

## How It Works

### Sync Triggers

| Trigger | When | Behavior |
|---------|------|----------|
| Cron schedule | Midnight daily (default) | Full incremental push |
| `gateway_stop` | Gateway shutdown | Final push before exit |
| `before_compaction` | Before session compaction | Push with 5-min debounce to prevent rapid-fire |
| Auto-restore | Service start, empty state dir | Pull latest snapshot (no safety snapshot created) |

### Push (your machine -> B2)

Each sync creates a timestamped snapshot (e.g., `openclaw-backup/2026-02-19T00-00-00Z/`):

1. Walk the state directory, collect files matching include patterns
2. Create safe SQLite snapshots via `.backup()` API (no half-written databases)
3. Compute SHA-256 hashes on **plaintext**, diff against last push
4. Encrypt changed files with AES-256-GCM (if enabled)
5. Upload changed files + unencrypted manifest
6. Prune old snapshots beyond `keepSnapshots` limit

Manifest hashes are always computed on plaintext so incremental diffing works regardless of encryption (random IV/salt means identical plaintext produces different ciphertext).

Unlike external backup tools (Restic, rclone), this plugin runs *inside* the gateway process and doesn't require stopping the gateway.

### Pull (B2 -> your machine)

1. Push a **safety snapshot** to `{prefix}/safety-{timestamp}/` (preserves current state before overwriting)
2. Fetch manifest from the selected snapshot
3. Compare local files by SHA-256 hash
4. Download + decrypt (if encrypted) only changed/missing files
5. Verify hashes against plaintext before writing

Safety snapshots are stored out-of-band and never auto-pruned, so you can always recover from a bad rollback.

## Agent Tool

The plugin registers a `b2_rollback` tool that lets you manage backups conversationally:

**List snapshots:**
> "Show me my B2 backup snapshots"

Returns all regular snapshots and safety snapshots with timestamps.

**Restore a snapshot:**
> "Roll back to the snapshot from February 15th"

Creates a safety snapshot of current state, then restores the selected snapshot.

The tool is registered as optional so it only appears when the agent needs it.

## Architecture

Zero external dependencies beyond what OpenClaw already ships:

| Need | Solution |
|------|----------|
| S3 API calls | Hand-rolled AWS Sig V4 signing (`node:crypto`) |
| Encryption | AES-256-GCM, scrypt key derivation from `applicationKey` |
| Scheduling | `croner` (already in OpenClaw core) |
| SQLite snapshots | `node:sqlite` `.backup()` API (Node 22+) |
| Push debounce | Shared timer prevents rapid-fire from overlapping triggers |
| JSON persistence | `readJsonFileWithFallback` / `writeJsonFileAtomically` from plugin SDK |

```
src/
  types.ts            # Config + manifest types, SAFETY_PREFIX
  b2-client.ts        # S3-compatible B2 client with Sig V4 signing
  gatherer.ts         # Walk state dir, collect syncable files
  sqlite-snapshot.ts  # Safe .backup() wrapper
  manifest.ts         # SHA-256 hashing + diff logic
  encryption.ts       # AES-256-GCM encrypt/decrypt/isEncrypted
  debounce.ts         # Push rate limiter
  snapshots.ts        # List, prune, filter snapshots in B2
  push.ts             # Upload changed files to B2 (with PushOptions)
  pull.ts             # Download + restore from B2 (with PullOptions)
  service.ts          # Background scheduler + auto-restore
index.ts              # Plugin entry: hooks, tool registration, debounce wiring
openclaw.plugin.json  # Plugin manifest
```

## Storage

Backblaz

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...