feat(secrets): add file source re-read on reload#181
Merged
Conversation
A file source reads the secret from a path on disk, re-resolving on every pipeline build (boot and each POST /v1/reload) and, when ttl is set, on cache expiry. Unlike env (fixed at process exec), this lets an integrator rotate a running proxy's secret value by rewriting the file (atomically: write-temp + rename) and reloading — no restart. The value is the exact file contents (no trimming), matching how Kubernetes and Docker expose file-mounted secrets, so the writer controls trailing whitespace. Optional ttl/failure_ttl and the shared json_key extraction apply as they do for the other sources.
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.
What
Adds a
filesecret source that reads the secret from a path on disk:The file is re-resolved on every pipeline build — boot and each
POST /v1/reload— and, whenttlis set, on cache expiry. Optionalttl/failure_ttland the sharedjson_keyextraction apply exactly as for the existing sources.Why
envis fixed at process exec, so a pre-warmed/long-lived proxy can never observe a secret value minted after it started. The cloud sources (aws_sm,aws_ssm,1password*) solve rotation but require that managed infrastructure in the egress path. A file source closes the gap with the smallest surface — no new endpoint, no watcher; the existing reload just re-reads the file like it re-reads the config.Our use case (per [chat with Matt]): one iron-proxy per sandbox, pre-warmed ahead of a customer claim. At claim we rewrite config +
POST /v1/reload(works great, thanks for the pointer) — but the per-session budget-scoped key isn't known at boot. We're on bare metal, so the cloud sources aren't in play. The integrator writes the file atomically (write-temp + rename, e.g. on a tmpfs mount,0400) and reloads; the proxy re-reads it. We understand the 0.42 control-plane is the intended longer-term home for dynamic principals/secrets — happy to align there too; this is the minimal v0.41-compatible bridge.Behavior notes
env's empty-value error).pathrequired), consistent with the lazy-resolve contract; the read happens on firstGet.reading secret file %qerror through the existing failure-cache path.Tests
go test ./internal/transform/secrets/— 187 pass. New unit tests cover happy path, exact-bytes preservation, ttl refresh picking up an atomically-rotated file, missingpath/ nonexistent file / empty file errors.gofmtclean,go vetclean. No integration test added — the source needs no external backend, matchingenv's unit-only coverage.