secrets: vault dev and Centralis; render dev without common.yaml #77
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Jinemi/thermograph#77
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/centralis-vault"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Brings the last two credential stores under SOPS. All three environments and the control plane are now managed the same way.
dev.yaml— dev wasn't "intentionally not wired in", it was brokenThe vault README claimed dev had no real secrets. Both halves were false.
Dev needed secrets it didn't have.
thermograph-dev-daemon-1has been in a crash loop, restarting every ~60s:neither THERMOGRAPH_INTERNAL_TOKEN nor THERMOGRAPH_AUTH_SECRET is set; refusing to start. So dev has had no Discord gateway and no job timers. And withTHERMOGRAPH_BASE_URLunset the app falls back tohttps://thermograph.org, so dev's IndexNow pings and verification links have been claiming to be prod.Dev already held production credentials.
backend-deploy-dev.ymlinjectsS3_ACCESS_KEY/S3_SECRET_KEYinto every dev deploy — and the only provisioned keypair for that bucket is read-write, on the bucket holding prod's database backups. Dev doesn't need them: without bucket creds thelakeservice 503s and history falls through to the archive. Those two workflow lines still need removing — outside this change's scope.dev renders
dev.yamlaloneVia
THERMOGRAPH_SECRETS_SKIP_COMMON=1. Eleven ofcommon.yaml's sixteen values are live production credentials, the render is a plaintext concatenation consumed throughenv_file:, and dev is the operator's desktop and the Forgejo CI runner — executing unrevieweddev-branch code with the docker socket mounted. An override indev.yamlwouldn't help: last-wins governs consumers, but the production value would still physically be a line in the file.Verified by running the real renderer in throwaway containers: current renderer leaks 28 lines onto dev including both S3 keypairs and the VAPID private key; patched gives exactly 12 keys, zero production credentials. Beta's render is byte-identical either way.
centralis.prod.yaml— its own file, its own renderer/etc/centralis.envwas hand-edited, which is how a JSON registry got written unquoted into a shell-sourced file and silently collapsed three identities to one. The renderer owns the file now.Why not fold
CENTRALIS_*intoprod.yaml:/etc/thermograph.envis loaded into every container in the app stack. Folding these in would putCENTRALIS_AUTH_TOKENandCENTRALIS_TOKENS— which authenticate an endpoint carryingrun_on_hostandsql_query(write:true)— into the web backend's environment. A read-anything bug in the app becomes a foothold on the control plane.The finding that justifies the whole exercise
sops -d --output-type dotenvemits values verbatim. Reusing the existing render path would have reproduced the original bug exactly. The new function decrypts to JSON and emits POSIX single-quoted assignments. Then three guarantees rather than one:env -i,set -a) and compares every value to the plaintext before touching/etc.CENTRALIS_TOKENSparses as a non-empty subject→token object after sourcing. Fed the literal{emi:x}shape it aborts and leaves the destination byte-identical.$(...), globs,;rm -rf /, empty string. All round-trip exactly.Value-identity proven, not asserted
Rendered vs live compared as effective values on prod — a textual diff would report a false difference, and would report a false match if the vault had captured quote characters as part of the value. Plus both env files producing a byte-identical
docker compose configdigest. 9 keys, both token subjects preserved. No value printed, logged, or shipped; only ciphertext crossed the wire.Nothing is deployed.
/etc/centralis.envis untouched; only a0600backup was placed alongside it.Noted for later, not fixed here
/etc/thermograph.envis also shell-sourced, and survives on raw dotenv only because none of its 32 current values happens to contain a shell-special character. It is one quoted secret away from the identical bug.