Harden the container: non-root, pinned images and dependencies, the key in a file (B-91, SEC-51, SEC-52, SEC-53; closes B-71, B-72)

- app runs as uid 1000; a one-shot data-permissions service chowns ./data to it
  and closes it to others (works on an older root-owned install with no host sudo);
  files are created 0600 (umask 077)
- python:3.12-slim and caddy:2-alpine pinned by digest; dependencies installed from
  requirements.lock with --require-hashes
- the Fernet key is XPRV_ENCRYPTION_KEY_FILE (./secrets/xprv_encryption.key, a compose
  secret), out of every environment variable and of a ./data backup
- setup.md no longer presents a second way to run the server (B-72)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5.5 committed 2026-10-18 00:54:23 +02:00
1 parent 40ac490826
commit c1b192f6d1
23 files changed
+1500 -183

No files matched your search

+2 -2
View File
@@ -8,7 +8,7 @@ locally, only when you actually need it (e.g. disaster-recovery backup).
Usage:
python scripts/decrypt_master_key.py
Requires XPRV_ENCRYPTION_KEY to already be set (.env), same as the running
Requires XPRV_ENCRYPTION_KEY_FILE (.env) to point at the key file, same as the running
server. Looks for the encrypted key at MASTER_KEY_PATH (.env) — if that path
doesn't exist, falls back to ./data/keys/master.xprv.enc, the location
docker-compose.yml bind-mounts it to, since .env's default (./master.xprv.enc)
@@ -34,7 +34,7 @@ def _resolve_key_path() -> str:
if __name__ == "__main__":
if not settings.xprv_encryption_key:
raise SystemExit("XPRV_ENCRYPTION_KEY is not set")
raise SystemExit("XPRV_ENCRYPTION_KEY_FILE is not set, or its file is missing or empty")
key_path = _resolve_key_path()