Backup & Restore

How to back up and restore your TameFlare instance. TameFlare stores all state in SQLite files and environment variables — no external database required.


What to back up

| Item | Location | Contains | Priority | |---|---|---|---| | Control plane DB | apps/web/local.db | Agents, policies, audit log, sessions, org settings | Critical | | Gateway DB | .TameFlare/gateway.db | Traffic logs, permissions, connector configs | Important | | Credential vault | .TameFlare/credentials.enc | Encrypted API keys for connectors | Critical | | CA certificate | .TameFlare/ca.crt | TLS CA cert (agents trust this) | Important | | CA private key | .TameFlare/ca.key | TLS CA signing key | Critical | | Environment variables | .env.local | All configuration | Critical | | Gateway config | .TameFlare/config.yaml | Gateway settings | Important |

Warning
Back up SETTINGS_ENCRYPTION_KEY separately. If you lose this key, all encrypted settings (Slack tokens, GitHub PATs stored via the dashboard) cannot be decrypted. Store it in a password manager or secrets vault.

Backup procedure

SQLite databases

SQLite files can be copied while the application is running (WAL mode ensures consistency):

# Control plane database
cp apps/web/local.db backups/local-$(date +%Y%m%d).db
 
# Gateway database
cp .TameFlare/gateway.db backups/gateway-$(date +%Y%m%d).db

For guaranteed consistency, use SQLite's backup API:

sqlite3 apps/web/local.db ".backup backups/local-$(date +%Y%m%d).db"
sqlite3 .TameFlare/gateway.db ".backup backups/gateway-$(date +%Y%m%d).db"

Config export (policies + agents)

TameFlare includes a built-in config export that bundles policies and agents into a JSON file:

# Via dashboard: Settings → Export Configuration
# Via API (requires admin role):
curl -H "Cookie: session=YOUR_SESSION" \
  http://localhost:3000/api/dashboard/export > config-backup.json

The export includes:

  • All policies (YAML content, metadata)
  • All agents (names, status — not API keys)
  • Organization settings

It does not include: API keys, credentials, audit logs, traffic logs, or sessions.

Full backup script

#!/bin/bash
BACKUP_DIR="backups/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
 
# Databases
sqlite3 apps/web/local.db ".backup $BACKUP_DIR/local.db"
sqlite3 .TameFlare/gateway.db ".backup $BACKUP_DIR/gateway.db"
 
# Credentials and keys
cp .TameFlare/credentials.enc "$BACKUP_DIR/"
cp .TameFlare/ca.crt "$BACKUP_DIR/"
cp .TameFlare/ca.key "$BACKUP_DIR/"
cp .TameFlare/config.yaml "$BACKUP_DIR/"
 
# Environment (contains secrets — encrypt this backup!)
cp apps/web/.env.local "$BACKUP_DIR/"
 
echo "Backup complete: $BACKUP_DIR"
Warning
Your backup contains secrets (CA key, credentials, env vars). Encrypt the backup directory or store it in a secure location.

Restore procedure

From SQLite backup

# Stop TameFlare
# Replace databases
cp backups/local-20260208.db apps/web/local.db
cp backups/gateway-20260208.db .TameFlare/gateway.db
 
# Restore credentials and keys
cp backups/credentials.enc .TameFlare/
cp backups/ca.crt .TameFlare/
cp backups/ca.key .TameFlare/
 
# Start TameFlare
pnpm dev

From config export

# Via dashboard: Settings → Import Configuration
# Via API (requires owner role):
curl -X POST \
  -H "Cookie: session=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d @config-backup.json \
  http://localhost:3000/api/dashboard/import

Config import creates policies and agents from the backup. It does not overwrite existing items with the same name — duplicates are skipped.

Schema migration after restore

If restoring a database from an older version:

pnpm db:push    # Applies any new schema changes

This is safe to run on an existing database — it only adds new columns/tables, never drops data.


Automated backups

Cron job (Linux/macOS)

# Daily backup at 2 AM, keep 30 days
0 2 * * * /path/to/agent-firewall/scripts/backup.sh && find /path/to/backups -mtime +30 -delete

Docker volume backup

If running via Docker Compose, back up the named volumes:

docker compose stop
docker run --rm -v agent-firewall_web-data:/data -v $(pwd)/backups:/backup \
  alpine tar czf /backup/web-data-$(date +%Y%m%d).tar.gz /data
docker compose start

Disaster recovery

| Scenario | Recovery | |---|---| | Lost local.db | Restore from backup. If no backup: fresh DB (pnpm db:push), re-register, re-create policies/agents. Audit history is lost. | | Lost .TameFlare/ directory | Restore from backup. If no backup: tf init creates new CA + config. Re-add connectors and credentials. Agents need new CA cert. | | Lost SETTINGS_ENCRYPTION_KEY | Encrypted settings in DB cannot be decrypted. Re-enter Slack tokens, GitHub PATs via dashboard Settings. | | Lost SIGNING_KEY_PRIVATE | Outstanding decision tokens become unverifiable. Generate new key pair, restart. Agents re-request pending actions. | | Corrupted SQLite | See Failure Modes — run integrity check, restore from backup, or recreate. |


Next steps