fix(secret-scope): merge BWS-proven keys into profile secret scope - #66342
fix(secret-scope): merge BWS-proven keys into profile secret scope#66342beecave-orchestrator wants to merge 2 commits into
Conversation
build_profile_secret_scope loaded only .env, making BWS-injected keys (tracked in env_loader._SECRET_SOURCES) invisible under an active scope in cron/multiplex execution. This caused nightly ollama-cloud provider resolution failures because OLLAMA_API_KEY existed in os.environ but was not in the scope dict. Fix: after loading .env, merge keys from os.environ that have a recorded external source label in _SECRET_SOURCES. Only provenance-tracked keys are eligible, so arbitrary process-env keys from other profiles remain excluded. .env values take precedence over external-source values, matching the .env-first resolution order in get_env_value_prefer_dotenv. Regression tests cover: (1) BWS key visible under active scope via get_secret, (2) .env value wins over BWS, (3) empty _SECRET_SOURCES does not leak unrelated os.environ keys, (4) multiplex isolation preserved (BWS key visible, untracked env key excluded). Root cause: investigator/reports/t_294e40cf-bws-key-loss-root-cause.md Review constraints: code-reviewer/verdict-cards/bws-cron-scope-key-loss-2026-07-12.md
Integration Review: APPROVEDReviewer: code-reviewer (Hermes Kanban task t_a8707ddb) Verification performed
VerdictAPPROVED. The cherry-pick is a clean reproduction of the previously approved fix onto current origin/main. No integration issues. Safe to merge. |
Related: #58111 addresses the same BWS profile-secret resolution failure with per-home provenance. This PR also adds file-descriptor parsing, but its global |
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Clean, well-scoped change with good test coverage. No security concerns.
Reviewed by Hermes Agent
|
Addressed the isolation concern in 70d9165.
Verification: |
Re-Review: APPROVED (follow-up commit 70d9165)Reviewer: code-reviewer (Hermes Kanban task t_0fce8496) Follow-up to @alt-glitch's isolation concern. The global Verification performed
Acceptance criteria
Non-blocking observationThe regression test directly populates VerdictAPPROVED — safe to merge. The follow-up cleanly resolves the per-home isolation concern without regressing the provenance gate, |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing the per-home isolation concern from #58111. The current-main premise is real: agent/secret_scope.py:197-204 builds scopes from .env only.
Problems
- The new map is only useful after a home has applied its external sources (
hermes_cli/env_loader.py:373-380). Gateway startup loads sources only for the process home atgateway/run.py:1408; secondary profiles instead enter_profile_runtime_scopeand load config atgateway/run.py:8857-8858, without applying their sources. A BWS-only secondary-profile key therefore still has no snapshot to merge atagent/secret_scope.py:243. - The new tests assign
_SECRET_SOURCE_VALUES_BY_HOMEdirectly (tests/agent/test_secret_scope.py:165,:254), so they do not exercise that missing production handoff.
Suggested changes
- Add a profile-safe per-home source-resolution/snapshot path before constructing the profile scope; avoid repopulating global
os.environ, which the scope isolation design explicitly avoids. - Add a two-home end-to-end regression through the source-application seam.
- Consider splitting the unrelated file-reference parser at
agent/secret_scope.py:72into a documented follow-up.
Automated hermes-sweeper review.
| """ | ||
| return load_env_file(Path(hermes_home) / ".env") | ||
| secrets = load_env_file(Path(hermes_home) / ".env") | ||
| _merge_external_secret_sources(Path(hermes_home), secrets) |
There was a problem hiding this comment.
This only merges a snapshot that already exists. Secondary multiplex profiles enter _profile_runtime_scope from gateway/run.py:8857 without applying their external sources first, while startup loads only the process home at gateway/run.py:1408; a BWS-only secondary-profile key will therefore still be absent. Please add a profile-safe snapshot-population path before this scope is built, plus an end-to-end two-home regression.
GottZ
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Summary
Three PRs address secret-scope credential loss through two distinct paths: #66342 adds per-home snapshots for externally sourced secrets and file-backed .env descriptors, while #67827 and #69057 restore process-environment fallback for scoped single-profile execution without weakening multiplex isolation.
Related pull requests
- #66342
related— (+227/-4) — keep open: The diff snapshots externally applied secret values per resolvedHERMES_HOMEand merges them into profile scopes, but secondary profiles still have no demonstrated production path that applies their external sources before scope construction. This follows the contributor keep_open review on #66342: the tests populate_SECRET_SOURCE_VALUES_BY_HOMEdirectly and therefore do not cover the identified missing handoff; add that profile-safe resolution path and a two-home end-to-end regression before merge. - #67827 [closed]
related— (+68/-4) — superseded by #69057: It makes an installed scope an overlay overos.environwhen multiplexing is off while retaining authoritative, fail-closed scope behavior when multiplexing is on. The change remains relevant because its commit was rebase-merged as-is through #69057 with authorship preserved. - #69057 [merged]
related— (+80/-5) — merged reference implementation: It carries #67827's single-profile scope-miss fallback unchanged and adds the gateway test correction that explicitly enables multiplex mode when verifying cross-profile isolation. This resolves the process-environment-only cron failure, but not #66342's separate external-source application gap for secondary profiles.
Duplicates
#67827 and #69057 implement essentially the same resolver change; #69057 is the merged salvage of #67827, with an additional gateway test correction.
Suggested consolidation
Keep merged #69057 as the canonical implementation for non-multiplex os.environ fallback and treat closed #67827 as its superseded duplicate. Keep #66342 open rather than merging it yet: consistent with the visible keep_open review on #66342, its diff stores and consumes per-home snapshots but does not establish the missing secondary-profile source-application handoff or test that path end to end.
Cross-PR triage: Reviewed 3 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 25 kB of PR diffs, 6 kB of issue/PR text, 9 kB of discussion (10 comments), 1 verify verdict. verdicts reflect diff content, not PR titles. Part of an automated triage batch.
|
Thanks for the thoughtful review and response. The relevant work has since landed upstream, so this draft is now superseded. I’m closing it rather than continuing it here. |
Summary
build_profile_secret_scopeloaded only.env, making BWS-injected keys (tracked inenv_loader._SECRET_SOURCES) invisible under an active scope in cron/multiplex execution. This caused nightly ollama-cloud provider resolution failures becauseOLLAMA_API_KEYexisted inos.environbut was not in the scope dict.Fix
After loading
.env, merge keys fromos.environthat have a recorded external source label in_SECRET_SOURCES. Only provenance-tracked keys are eligible, so arbitrary process-env keys from other profiles remain excluded..envvalues take precedence over external-source values, matching the.env-first resolution order inget_env_value_prefer_dotenv.Additionally, a
_resolve_secret_reference()helper resolves{"source":"file","path":...}secret descriptors in.envvalues, supporting file-backed secret injection (BWS ecosystem).Root Cause
Detailed in investigator report:
investigator/reports/t_294e40cf-bws-key-loss-root-cause.md.Test Coverage
tests/agent/test_secret_scope.py(including 4 new regression tests)tests/test_env_loader_secret_sources.pytests/cron/test_shutdown_interrupt.pyNew regression tests cover:
get_secret.envvalue wins over BWS_SECRET_SOURCESdoes not leak unrelatedos.environkeysReview
Code-review approved via verdict card:
bws-scope-fix-2026-07-17.md. All 4 review focus areas satisfied (real resolution path, multiplex isolation, BWS-disabled safety, provenance gate exclusivity).Changed Files
agent/secret_scope.py(+63 lines)tests/agent/test_secret_scope.py(+106 lines)