Read secrets from Docker secrets or env vars too (1.1.0) #6

Merged
joeyr merged 1 commit from feat/secrets-outside-config into main 2026-10-05 20:17:16 -05:00
Owner

The Jellyfin API token, TMDB API key and SMTP password can now stay out of config.yml.

Each is read from the first of <NAME>_FILE, /run/secrets/<name>, <NAME> and config.yml, the same order as mcp-gateway. The names are jellyfin_api_token, tmdb_api_key and smtp_password. Existing configs work unchanged.

  • config/secret_sources.go (new): resolution, then the checks the YAML tags used to do (required, required unless TLS is NONE, jwt), with messages that name every place a secret can go.
  • config/model.go, loader.go: the three tags are relaxed and the resolver is called after parsing. main.go logs one "Secret loaded" line per secret with its source, never the value.
  • Tests: the source order, an unreadable _FILE, a config with all three secrets outside it, a non-JWT TMDB key, and no SMTP password with TLS NONE. Three expected errors in the upstream loader test change.
  • Checked end to end with the built image: secrets mounted at /run/secrets and removed from the config, the app running as its non-root user, logs Secret loaded … from /run/secrets/…, connects to Jellyfin, and generates the email.
  • config-example.yml, CHANGELOG, CLAUDE.md. VERSION 1.1.0 (new feature).

🤖 Generated with Claude Code

The Jellyfin API token, TMDB API key and SMTP password can now stay out of `config.yml`. Each is read from the first of `<NAME>_FILE`, `/run/secrets/<name>`, `<NAME>` and `config.yml`, the same order as mcp-gateway. The names are `jellyfin_api_token`, `tmdb_api_key` and `smtp_password`. Existing configs work unchanged. - `config/secret_sources.go` (new): resolution, then the checks the YAML tags used to do (required, required unless TLS is NONE, jwt), with messages that name every place a secret can go. - `config/model.go`, `loader.go`: the three tags are relaxed and the resolver is called after parsing. `main.go` logs one "Secret loaded" line per secret with its source, never the value. - Tests: the source order, an unreadable `_FILE`, a config with all three secrets outside it, a non-JWT TMDB key, and no SMTP password with TLS NONE. Three expected errors in the upstream loader test change. - Checked end to end with the built image: secrets mounted at `/run/secrets` and removed from the config, the app running as its non-root user, logs `Secret loaded … from /run/secrets/…`, connects to Jellyfin, and generates the email. - `config-example.yml`, CHANGELOG, CLAUDE.md. VERSION 1.1.0 (new feature). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Read secrets from Docker secrets or env vars too (1.1.0)
All checks were successful
CI / gate (pull_request) Successful in 59s
CI / lint (pull_request) Successful in 55s
CI / image (pull_request) Has been skipped
63b9ce8cf2
The Jellyfin API token, TMDB API key and SMTP password can now stay out
of config.yml. Each is read from the first of <NAME>_FILE,
/run/secrets/<name>, <NAME> and config.yml, the order mcp-gateway uses,
with names jellyfin_api_token, tmdb_api_key and smtp_password. An
unreadable <NAME>_FILE is an error rather than a fallback, so a typo
can't hide behind an old value in config.yml. Values are trimmed, since
a secret created with echo ends in a newline.

The YAML tags can no longer require these fields, because a value may
arrive after parsing. resolveSecrets applies the same rules afterwards
(required, required unless TLS is NONE, jwt) with messages that name
every place a secret can go. Three expected errors in the upstream
loader test change accordingly.

main logs one "Secret loaded" line per secret with its source, never
the value, so a deployment can confirm it is reading the Docker secret.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
joeyr merged commit 5f7baae35a into main 2026-10-05 20:17:16 -05:00
joeyr deleted branch feat/secrets-outside-config 2026-10-05 20:17:16 -05:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
joeyr/jellyfin-newsletter!6
No description provided.