Repository navigation
awsutil: LoadSecretBundle(ctx) — opt-in Lambda env-cap reclamation (D5 of sc-secrets-bundle-mode) - #20
Merged
Conversation
New helper that reads a FORGE_SECRETS_BUNDLE_ARN env (constant
SecretsBundleEnv), fetches the JSON payload via the existing
secretcache.Cache, parses it as {envName:string → value:string},
and os.Setenv's each key before the service's main() reads a
secret env.
The design (SC + SDK coordinated change — see forge/docs/design/
2026-10-17/sc-secrets-bundle-mode/README.md) uses this to replace
N per-key Secrets Manager ARN env vars with ONE bundle env on
Lambda stacks that hit the 4KB env cap. SC's Pulumi renderer is
the sibling change in the api repo.
Contract preserved for the rest of the fleet:
- Unset FORGE_SECRETS_BUNDLE_ARN = NO-OP (nil error). Services
can pin this SDK version before any opt in on the SC side.
- Set-but-not-ARN = loud error (`not a Secrets Manager ARN`).
Operator typos surface instead of loading garbage.
- Operator-pinned env values win over bundle values (os.Setenv
skips keys already set). Literal env always wins.
- Non-string JSON values are rejected explicitly rather than
silently flattened via Go's default string format.
- Shares the SAME lazy secretcache.Cache GetEnvOrSecret uses;
no second AWS session on Yandex where no bundle is wired.
Also adds LoadSecretBundleFromEnv for services that need a
different bundle env name (staged migrations).
Four hermetic tests pin the unset-noop, non-ARN rejection,
explicit-env-name variant, and the error-message truncation
helper.
Semgrep Scan ResultsRepository:
Scanned at 2026-10-17 13:57 UTC |
Security Scan ResultsRepository:
Scanned at 2026-10-17 14:00 UTC |
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.
Summary
Fifth slice (D5) of the
sc-secrets-bundle-modeinitiative — seeforge/docs/design/2026-10-17/sc-secrets-bundle-mode/README.mdfor the full design.Adds
LoadSecretBundle(ctx)topkg/awsutil/secrets.go: reads aFORGE_SECRETS_BUNDLE_ARNenv (theSecretsBundleEnvconstant), fetches the JSON payload via the existingsecretcache.Cache, parses it as{envName:string → value:string}, andos.Setenv's each key.SC's Pulumi renderer (D3/D4 in the api repo) is the sibling change that writes the
FORGE_SECRETS_BUNDLE_ARNenv + the ONE Secrets Manager JSON secret per service. Together, N per-key ARN envs become 1 — reclaims ~4-5 KB on the forge-conductor Lambda, which has been at the 4KB env cap since 2026-10-16.Contract preserved for the rest of the fleet
FORGE_SECRETS_BUNDLE_ARN= NO-OP (nil error). This SDK version can be pinned before any service opts in on the SC side. Legacy per-keyGetEnvOrSecretworks unchanged.is set but is not a Secrets Manager ARN (got prefix "..."). Operator typos surface instead of loading garbage.os.Setenvskips keys already set in the environment — anything the operator pinned viaenv:in client.yaml overrides the bundle.secretcache.CacheGetEnvOrSecretuses. No second AWS session. On Yandex (no bundle env, no AWS creds) the cache stays unbuilt.Also adds
LoadSecretBundleFromEnv(ctx, envName)for services that need a different bundle env name during staged migrations.Call-site contract
Services opt in by adding ONE line to the top of
main():Everything downstream continues to call
GetEnvOrSecret/os.Getenvunchanged.Test plan
TestLoadSecretBundleUnsetIsNoop— unset bundle env is a no-op (nil error)TestLoadSecretBundleRejectsNonArn— garbage value surfaces as "not a Secrets Manager ARN"TestLoadSecretBundleFromEnvRespectsExplicitEnvName— explicit env-name variant worksTestFirstN— error-message truncation helperTestGetEnvOrSecretReturnsLiteralWithoutTouchingAws+TestGetEnvOrSecretReturnsEmptyForUnsetVariablestill passgo vet+go build+gofumpt -w+gci writeappliedReferences
forge/docs/design/2026-10-17/sc-secrets-bundle-mode/README.mdforge/docs/roadmap/items/sc-secrets-bundle-mode.md(slice D5)conductor-lambda-env-4kb-cap, Resend webhook pivot PR #601 workaround