fix: overlay skill-declared secrets dynamically (closes #48)#51
Open
initializ-mk wants to merge 1 commit into
Open
fix: overlay skill-declared secrets dynamically (closes #48)#51initializ-mk wants to merge 1 commit into
initializ-mk wants to merge 1 commit into
Conversation
Replace the hardcoded knownKeys list in Runner.overlaySecrets and OverlaySecretsToEnv with a dynamic union of the builtin keys and whatever the secrets provider exposes via List(). Custom skill env vars stored via `forge secrets set` now reach the OS environment so SkillCommandExecutor / cli_execute can read them, with no edits to runner.go required when adding a new skill. - Extract builtinSecretKeys to a single package-level slice (used as the fallback when a provider cannot enumerate, e.g. EnvProvider). - Add secretOverlayKeys helper that returns builtins ∪ provider.List(), deduped. List errors are surfaced but builtins are still returned so the builtin overlay path keeps working when enumeration fails (wrong passphrase on a global file, etc.). - Keep cross-category secret-reuse detection scoped to builtinSecretKeys (only set with categories defined in secretCategory). - Tests: stub-provider unit tests for union/dedup/error paths plus an end-to-end test that writes a non-builtin key into an encrypted file and verifies OverlaySecretsToEnv lands it in os.Environ.
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
Fixes #48 — skill-declared env vars stored in the encrypted secrets file are now passed to downstream binaries.
The hardcoded
knownKeysallowlist inRunner.overlaySecretsandOverlaySecretsToEnvis replaced with a dynamic union of the builtin keys and whatever the secrets provider exposes viaProvider.List(). Custom skill env vars (e.g.MY_API_KEY) declared inSKILL.mdand stored viaforge secrets setnow reach the OS environment soSkillCommandExecutorandCLIExecuteToolcan read them viaos.Getenv/os.LookupEnv.Adding a new skill with new env var names no longer requires any edits to
runner.go.Approach
builtinSecretKeysto a single package-level slice. It is kept as a fallback so providers that cannot enumerate (e.g.EnvProvider.List()returnsnilby design) still get LLM/channel keys overlaid viaGet().secretOverlayKeys(provider) ([]string, error)— returnsbuiltins ∪ provider.List(), deduped.Listerrors are surfaced but the builtins are still returned, so a failed enumeration degrades to today's behavior rather than dropping the LLM/channel keys.builtinSecretKeys— only those keys have defined categories insecretCategory. Custom keys have no defined category so they are not part of the check.Tests
TestSecretOverlayKeys_NonEnumerableProvider— providers returningnilfromList()still yield the builtin set.TestSecretOverlayKeys_UnionsBuiltinsAndListed— builtins ∪ custom keys with dedup.TestSecretOverlayKeys_ListError— list errors propagate but builtins are preserved.TestOverlaySecretsToEnv_CustomSkillKey— end-to-end regression: a non-builtin key (MY_SKILL_API_KEY) written to an encrypted file lands inos.EnvironafterOverlaySecretsToEnv. IsolatesHOMEto avoid touching the developer's real~/.forge/secrets.enc.Acceptance criteria from #48
runner.gorequired for a new skill with new env var names.Known follow-up (out of scope for #48)
While testing I noticed
OverlaySecretsToEnv(and the runner'sbuildSecretProvider) unconditionally appends the global~/.forge/secrets.encto the chain even if that file uses a different passphrase.ChainProvider.List()propagates the resulting decrypt error and forces the new code into the builtins-only fallback for custom keys — so a stale global file can hide skill-declared keys. The same brittleness already affectsGetfor keys not present in the local file, so it predates this change. Worth a separate issue (gate the global path onos.Stat, or makeChainProvider.List/Getlenient to per-provider failures).Test plan
secrets.providers: [encrypted-file], declare a custom env var (e.g.MY_API_KEY) underforge.env.requiredin a skill, store the value viaforge secrets set MY_API_KEY=..., run the agent, and confirm the skill script / cli_execute sees the value.OPENAI_API_KEY,ANTHROPIC_API_KEY, etc.) and channel keys (SLACK_BOT_TOKEN,TELEGRAM_BOT_TOKEN) still resolve the same as before.