Opinionated Agents Ship Faster
Why convention over configuration — the principle that powered Rails, Vercel, and Cloudflare — matters even more when the developer isn't human.
Disclosure: I’m a Cloudflare employee and shareholder. Opinions expressed here are my own and do not represent the views of Cloudflare.
Early on, I made a deliberate choice: OpenClaw (formerly Clawdbot and Moltbot) runs in an isolated container on a dedicated host, not on my laptop or workstation.
The reason is straightforward. An AI agent that manages your projects, reads your messages, and coordinates your work accumulates context fast — personal information, access tokens, communication patterns. Running that on your daily driver means the agent shares your identity surface. Your browser sessions, your SSH keys, your credentials — all within reach of a process you’re still learning to trust.
We’re not there yet. The identity and access models for autonomous agents are immature at best. There’s no widely adopted standard for scoped agent privileges, no robust framework for limiting what an agent can touch versus what it can see. Until that work is done — and it’s some of the most important work in this space — I’d rather keep my agent in a box with clear boundaries. It gets what it needs and nothing more.
A headless container also forces discipline. No GUI crutches. Everything the agent does is through CLI tools, APIs, and files — which means everything is scriptable, auditable, and reproducible.
Running headless has another benefit: it pushes you toward proper structure early.
For a desktop agent, it’s tempting to let artefacts sprawl — files in Downloads, notes on the desktop, half-finished scripts in random directories. A headless agent doesn’t have that luxury. Everything lives in the workspace, and the workspace needs to be organised.
GitHub becomes invaluable here. Not just as a backup target, but as a structured layer on top of the workspace. Project artefacts, documentation, even OpenClaw configuration changes — all versioned, browsable, and reviewable from any device. For a headless setup where you can’t just open a folder and scroll through files, having a GitHub repo you can browse from your phone or laptop is a genuine quality-of-life improvement.
It’s also another storage layer. R2 holds encrypted snapshots for disaster recovery. GitHub holds the living, versioned state. Between the two, you’d have to try pretty hard to lose anything.
With that context, here’s what we built. Three tools, each doing one thing well:
R2 speaks S3, which means rclone works out of the box — once you get the endpoint format right.
[r2-backup]
type = s3
provider = Cloudflare
access_key_id = your_access_key_here
secret_access_key = your_secret_key_here
acl = private
endpoint = https://<ACCOUNT_ID>.r2.cloudflarestorage.com
The endpoint URL is the one thing people get wrong. No trailing slash — just https://<account-id>.r2.cloudflarestorage.com. Your account ID is in the R2 dashboard.
Create your bucket in the Cloudflare dashboard first. Then verify:
rclone lsd r2-backup:
If you see your bucket, you’re in business.
We chose age over rclone’s built-in crypt layer for one reason: key separation.
The backup process only needs the public key. The agent running nightly backups can encrypt but never decrypt. If the host is compromised, the attacker gets encrypted blobs they can’t read. The private key lives elsewhere — a password manager, a hardware key, wherever you keep things that matter.
Generate a keypair:
age-keygen -o backup-key.txt
This gives you a public key (starts with age1...) and a secret key. Store that secret key somewhere safe and separate from your infrastructure. It’s the only way back in.
Nothing clever here. Compress, encrypt, upload.
#!/bin/bash
set -euo pipefail
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
WORKSPACE="$HOME/.openclaw/workspace"
DEST="r2-backup:your-bucket/workspace"
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
# Compress
tar -czf "$TMPDIR/workspace-${TIMESTAMP}.tar.gz" \
-C "$(dirname "$WORKSPACE")" "$(basename "$WORKSPACE")"
# Encrypt (public key only)
age -r "age1your-public-key-here" \
-o "$TMPDIR/workspace-${TIMESTAMP}.tar.gz.age" \
"$TMPDIR/workspace-${TIMESTAMP}.tar.gz"
# Upload
rclone copy "$TMPDIR/workspace-${TIMESTAMP}.tar.gz.age" "${DEST}/"
Schedule it with cron. Ours runs at 3am.
The reverse path. Download, decrypt, extract.
# Download
rclone copy r2-backup:your-bucket/workspace/workspace-20260209-030000.tar.gz.age .
# Decrypt (requires the secret key)
age -d -i /path/to/secret-key.txt workspace-20260209-030000.tar.gz.age > workspace.tar.gz
# Extract
tar -xzf workspace.tar.gz
Test this. A backup you’ve never restored is a hypothesis, not a strategy.
Effectively zero. R2’s free tier covers 10GB of storage and 10 million reads per month. Our daily backups don’t come close. And because there are no egress fees, restores are free, too.
Why not rclone crypt? It works fine, but the encryption keys live on the same machine doing the backups. If someone roots the box, they have the keys and the data. With age, the private key is physically elsewhere.
Why not GPG? Life’s too short for GPG key management. age does the same job with a fraction of the complexity.
Why R2 over S3/B2/GCS? Zero egress. I was already having OpenClaw shipping apps to Cloudflare’s developer platform and few prompts were required to add backups to R2.
I want to be honest: this setup protects against data loss, not against everything.
If the agent’s credentials are compromised, encryption doesn’t help — the attacker has live access, not just backups. If I misconfigure the container’s network access, isolation is theatre. If the age secret key is lost, every backup becomes a paperweight. And if the agent itself behaves in ways I don’t expect — well, I’m trusting a process I can audit after the fact, not one I can fully predict.
No solution is risk-free. This is a meaningful step, not a finish line.
We’re giving these agents our context, our projects, our communication patterns — and increasingly, our trust. We’re building working relationships with them.
So who’s responsible when that trust is misplaced? The developer who built the framework? The person who gave the agent access? The agent itself?
Agentically co-authored.