Repository navigation
docs(media): the tier has no secrets file by decision, and the handover says where Jellyfin's admin lives (#528) - #546
Merged
Conversation
…er says where Jellyfin's admin lives (#528) stacks/media was the one tier with no secrets/<stack>.example.yaml and no .sops.yaml rule, and #528 asked whether that is a gap or a decision. It is a decision, for three reasons written into docs/security.md beside the Home Assistant exception it belongs with: - Jellyfin's admin is created by its own setup wizard and kept as a hash in jellyfin.db inside jellyfin-config. No environment variable or rendered file could hand it in, so a value in a secrets file would reach nothing. Audiobookshelf (#140) and Navidrome (#141) create their first user the same way. - `make secrets-init STACK=media` has to run on the stack's host, and smaug runs TrueNAS with neither make nor sops. A media rule would stay a placeholder forever or hold the estate's key, which is the inversion ADR-0020's per-stack rules exist to prevent. - The successor's way in is host access plus Jellyfin's own Forgot Password flow, which writes a PIN file into the config volume from a LAN client. That needs no password at all, so successor-handover.md now lists the Jellyfin and TrueNAS admins under what the repository does not hold, with the reset command. .sops.yaml gains a comment saying there is no media rule on purpose, so the next reader does not add one and land a future file on the estate's key. The compose header and .env.example, which #413's commit had already brought up to date with the 2026-09-19 deploy, now name the decision where they said "#528's". The README layout tree and secrets/README.md name the exception in one line each. Not changed here: scripts/backup-volumes.sh has no jellyfin-config sentinel while stacks/media/README.md says the volume is backed up by it. That is #484's. Refs #138 #140 #141 #484 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
stacks/mediawas the one tier with nosecrets/<stack>.example.yamland no.sops.yamlrule. #528 asked whether that is a gap or a decision, and forsuccessor-handover.mdto say where the media admin lives. This records the decision: no secrets file, on purpose, beside the Home Assistant exception indocs/security.md§ Secrets.Why no file
adminis created by its own setup wizard and kept as a hash injellyfin.dbinsidejellyfin-config. No environment variable or rendered file is a way to hand it in. Audiobookshelf (Media tier: Audiobookshelf #140) and Navidrome (Media tier: Navidrome #141) create their first user the same way, so the exception is the tier's, not Jellyfin's.make secrets-init STACK=mediahas to run on the stack's host (bootstrap.shrefuses elsewhere), andsmaugruns TrueNAS with neithermakenorsops. A media rule would stay a placeholder forever or hold the estate's key, which is the inversion ADR-0020's per-stack rules exist to prevent.stacks/media/README.mdand in the handover, which now lists Jellyfin'sadminand TrueNAS's own web-UI admin under what the repository does not hold.The alternative, a vault-style
secrets/media.sops.yamlencrypted to the estate's recipients, was considered and declined: it renders nothing, the tooling cannot create it onprometheus, and it adds an ADR-0024 proof obligation for a credential the host it protects cannot use.What changed
docs/security.md— the decision, what protects the credential, and what would retire the exception (a media service taking a credential from outside).docs/runbooks/successor-handover.md— the two admins under "what it does not hold", the reset flow, and astacks/mediarow under "safe to stop".stacks/media/README.md— a section on where the admin lives, why there is no secrets file, and the way back in without the password..sops.yaml— a comment saying there is no media rule on purpose, so the next reader does not add one.stacks/media/compose.yaml,.env.example— name the decision where they said "stacks/media has no secrets file: Jellyfin's admin credential lives only in a password manager #528's" (the headers themselves were brought up to date by Buy and build the NAS, smaug, on CasaBonita (ADR-0016, ADR-0040) #413's commit onmain).README.md,secrets/README.md— one line each.No ADR: this applies ADR-0035's class and ADR-0020's rule. Nothing deploys and nothing on
smaugchanges.Verified
make validategreen in this worktree on the second run. The first run failedobservability: promtool check configonce and its own diagnostic rerun printed SUCCESS with only the expectedfile_sdwarnings — the known local promtool flake, on files this branch does not touch.check_sops_rules.pystill mapssecrets/media.sops.yamlto the catch-all and passes, which is the point of the.sops.yamlcomment.Adjacent, not fixed here
scripts/backup-volumes.shhas nojellyfin-configsentinel whilestacks/media/README.mdsays the volume is backed up by it. That belongs to #484.Closes #528
Refs #138 #140 #141 #484
🤖 Generated with Claude Code