Files
RustProxy/docs/SECRET_STORE_BACKUP.md
T
2026-10-03 18:10:20 +02:00

59 lines
3.2 KiB
Markdown

# 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:
```text
<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.
```bash
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:
```bash
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.