3.2 KiB
Secret Store and encrypted full backup/restore
RustProxy keeps application credentials in a central encrypted Secret Store. Provider and ACME secrets are not stored as plaintext configuration values in SQLite.
Secret Store
Secret records live in the secret_store SQLite table and contain an identifier, provider/type, encryption version, nonce, ciphertext, metadata and timestamps. Values are encrypted with AES-256-GCM using a random local data key stored at:
<data-dir>/secrets/master.key
The key file is created with mode 0600; its directory is private. The application loads it during normal startup, so normal operation does not require an interactive password.
Existing ACME DNS credential files are migrated on startup for Cloudflare, OVH and RFC2136. After successful import, the legacy plaintext credential file is removed. Certbot-compatible credential files are recreated only as short-lived private files around the external operation and removed afterwards.
Do not copy only config.sqlite3 as a Secret Store backup: the local key material is also required. Use the encrypted full-backup command below.
Create a full backup
Stop RustProxy first so the data directory lock is available. The output file must be outside the RustProxy data directory and must not already exist.
rust-proxy --data-dir /var/lib/rustproxy backup create \
--output /private/rustproxy-backup.rpb
When run from a TTY, RustProxy asks for the backup password without putting it in process arguments or shell history. Press Enter at the password prompt to generate a strong random password. A generated password is printed exactly once and is required for restore.
For non-interactive backup create, RustProxy generates the password automatically and prints it once to standard output. Protect that output as a secret.
The encrypted backup contains the durable application state needed for recovery, including:
- a consistent SQLite snapshot,
- configuration and Secret Store records,
- backup-wrapped Secret Store key material,
- certificates and private keys,
- ACME state and durable provider data,
- other durable RustProxy data accepted by the backup manifest.
It excludes rebuildable/runtime data such as cache, logs, temporary files, sockets, PID/lock files and SQLite WAL/SHM sidecars.
The outer container derives a backup key with Argon2id and encrypts authenticated chunks with AES-256-GCM. The backup password is independent from the local Secret Store key.
Restore
Restore is CLI-only and requires an interactive TTY for the password:
rust-proxy --data-dir /var/lib/rustproxy backup restore \
/private/rustproxy-backup.rpb
Before replacing the destination, RustProxy verifies the encrypted container, password/authentication tags, manifest, checksums, backup format, RustProxy/schema compatibility, restored SQLite database and decryptability of all Secret Store records.
Files are first restored into a private staging directory. Only after validation succeeds is the staged data directory atomically activated; activation failure attempts to roll back to the previous directory. Sensitive restored files use restrictive permissions.
A lost backup password cannot be recovered by RustProxy.