Security
ClawDNA's security model is designed around one principle: your agent's secrets and sensitive data never leave your machine unless you explicitly intend it.
Secrets Sanitizer
Every push, export, and distillation operation passes through a secrets sanitizer before any data leaves the machine. This is a hard gate — it cannot be bypassed without the explicit --force-unsafe flag.
Detection Patterns
Built-in patterns detect the most common secret formats:
| Pattern | Example Match |
|---|---|
| Telegram bot token | 1234567890:ABC... |
| OpenAI API key | sk-... (48 chars) |
| Anthropic API key | sk-ant-... (95 chars) |
| Generic bearer token | bearer eyJ... |
| JWT | eyJ...header.payload.signature |
| Private key header | -----BEGIN RSA PRIVATE KEY----- |
| Discord token | MTA2... |
Custom Patterns
Add custom patterns in ~/.clawdna/.secretsignore to match your organization's secret formats.
Sanitizer Behavior
- Scans all identity files before any network call
- If a secret is found, the operation is immediately aborted
- Only the first 8 characters of the match are shown in the error (rest redacted)
- For
openclaw.json, inline token values are replaced with$ENV_VARreferences
Encryption at Rest
Identity bundles stored in ClawDNA Cloud are encrypted client-side before upload. The encryption key never touches ClawDNA servers — bundles are opaque blobs from the server's perspective.
Algorithm
| Component | Specification |
|---|---|
| Cipher | AES-256-GCM |
| Key derivation | PBKDF2 with HMAC-SHA256 |
| Iterations | 600,000 |
| Key storage | System keychain (via keytar) |
How It Works
- User sets an encryption passphrase (stored in system keychain, never in config files)
- PBKDF2 derives a 256-bit key from the passphrase (600,000 iterations)
- Each bundle is encrypted with AES-256-GCM using a unique IV
- Encrypted bundle is uploaded to R2 storage
- On pull, the bundle is downloaded and decrypted locally
The encryption key never leaves your machine. ClawDNA Cloud stores only encrypted blobs and cannot read your identity data.
Webhook Signatures
Webhook payloads are signed to prevent tampering and replay attacks.
Signature Format
# HTTP Header
X-ClawDNA-Signature: hmac-sha256=<hex-encoded-signature>Verification
- Compute HMAC-SHA256 of the raw request body using your webhook secret
- Compare using timing-safe equality to prevent timing attacks
- Reject requests with missing or invalid signatures
// Example verification (Node.js)
import crypto from "crypto";
function verifySignature(
body: string,
signature: string,
secret: string,
): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}File Permissions
The CLI enforces strict file permissions on all ClawDNA-managed files:
| Path | Permission | Meaning |
|---|---|---|
~/.clawdna/config.json | 600 | Owner read/write only |
~/.clawdna/envs/*.yaml | 600 | Owner read/write only |
~/.clawdna/snapshots/ | 700 | Owner read/write/execute only |
~/.clawdna/sync-state.json | 600 | Owner read/write only |
Running clawdna doctor checks these permissions and warns if they are too permissive. This prevents other users on shared systems from reading your agent's config or sync state.
Security Checklist
- Secrets sanitizer runs as a hard gate before every push, export, and distillation
- AES-256-GCM encryption at rest — key derived via PBKDF2 (600k iterations)
- Encryption key stays in your system keychain, never on ClawDNA servers
- HMAC-SHA256 webhook signatures with timing-safe verification
- Strict file permissions (
600/700) enforced by CLI .env, credentials, sessions, and local-only files are never synced- Rate limiting via Cloudflare KV prevents abuse
