feat(core): add file-or-env secret reader (secret_env) (PSA-37) #10
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/psa-37-secret-env-core"
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?
What
Move the file-or-env secret reader into dunite-core so every consumer shares one implementation. Adds
dunite_core::services::secret_env::secret_env(name)(re-exported asdunite_core::services::secret_env).Semantics (unchanged from bunyip's original)
Resolution order:
{NAME}_FILE: if set and non-empty, the secret is the trimmed contents of that file (a composesecrets:mount under/run/secrets/...). An unreadable file PANICS - a misconfigured secret mount must fail fast at startup, never silently fall back.{NAME}: the plain environment variable (the dev.envpath).Empty values (empty file or empty env var) are treated as unset and return
None, so compose${VAR:-}defaults and empty secret files both mean "not configured".Why
This is generic, domain-free infrastructure (the same family as dunite-core's jwt/encryption/password services). Keeping it in bunyip-domain forces every other dunite consumer (mokosh-server, future services) that wants Docker file-based secrets to re-implement the convention with potentially divergent trim/empty/fail-fast semantics. Raised as finding 8 of the bunyip PR #40 review.
Tests
The five unit tests ported from bunyip's config.rs: plain-env fallback (with trim), unset/blank -> None, file precedence over env var, empty file -> None, and fail-fast panic on an unreadable file. No new dependencies (std::env + std::fs only). fmt + clippy -D warnings clean; full
cargo test --workspacegreen.Follow-up (separate, not in this PR)
Switch bunyip-domain to re-export
dunite_core::services::secret_envand delete its local copy. That depends on a dunite-core release and a bunyip dependency bump, so it lands after this merges and a release is cut.#PSA-37
Code review doc clarifications (no behavior change): document that a set `{NAME}_FILE` is authoritative so an empty file resolves to None and does NOT fall back to the plain `{NAME}` var; that surrounding whitespace is stripped from the resolved value (so whitespace-significant secrets are unsupported and should be encoded); and that the function is intended for startup/config load because an unreadable secret file panics. #PSA-37 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>