fix(kanban): strip parent credentials from worker env - #55600
Conversation
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Security fix that strips parent profile credentials from kanban worker subprocess environments. Uses the centralized hermes_subprocess_env(inherit_credentials=False) and then explicitly removes GATEWAY_RELAY_SECRET, GATEWAY_RELAY_*, and AUXILIARY_*_API_KEY/AUXILIARY_*_BASE_URL variables. Well-tested.
Looks Good
- Defense-in-depth: centralized env sanitizer + explicit credential stripping
- Test verifies both credential removal and profile routing preservation
- Clean separation of concerns
Reviewed by Hermes Agent
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing this worker-profile credential boundary. Current origin/main still builds the worker environment with dict(os.environ) at hermes_cli/kanban_db.py:8085, so routing through hermes_subprocess_env(inherit_credentials=False) is a valid fix.
Problems
hermes_cli/kanban_db.py:7692removes everyGATEWAY_RELAY_*variable. The centralized sanitizer deliberately preserves non-secret routing hints such asGATEWAY_RELAY_URLandGATEWAY_RELAY_PLATFORMS(tools/environments/local.py:292-320;tests/tools/test_local_env_blocklist.py:691-730).
Suggested changes
- Remove the extra manual filtering loop at
hermes_cli/kanban_db.py:7691-7698; the centralized helper already strips provider keys, auxiliary secrets, relay authentication material, and relay identity when called withinherit_credentials=False. - Add a worker-spawn regression assertion that a non-secret relay routing hint remains available.
Automated hermes-sweeper review.
| from tools.environments.local import hermes_subprocess_env | ||
| env = hermes_subprocess_env(inherit_credentials=False) | ||
| for key in list(env): | ||
| if key == "GATEWAY_RELAY_SECRET" or key.startswith("GATEWAY_RELAY_"): |
There was a problem hiding this comment.
Please remove this broad GATEWAY_RELAY_* filter. hermes_subprocess_env(inherit_credentials=False) already removes relay authentication material, while the shared sanitizer intentionally preserves non-secret routing hints such as GATEWAY_RELAY_URL and GATEWAY_RELAY_PLATFORMS.
Summary
This prevents Kanban worker subprocesses from inheriting provider and gateway credentials from the dispatching process environment.
_default_spawn()launches workers for the assignee profile by settingHERMES_HOME/HERMES_PROFILE, but it previously started fromdict(os.environ). Because Hermes credential resolution checks process env before the profile.env, a worker intended to run under one profile could still see provider keys and internal gateway secrets from the dispatcher/default profile.Why
Kanban workers are profile-scoped subprocesses. Their config, auth state, and
.envshould come from the assignee profile, not from whichever gateway/CLI process happened to dispatch the task.Before this change, a dispatcher process containing values such as
OPENAI_API_KEY,ANTHROPIC_API_KEY,AUXILIARY_*_API_KEY, orGATEWAY_RELAY_SECRETpassed those values straight into the worker env. That can cause wrong-profile credential use and leaks internal gateway routing secrets into an unrelated worker process.Changes
hermes_subprocess_env(inherit_credentials=False)instead of rawos.environ.HERMES_HOME,HERMES_PROFILE,HERMES_KANBAN_*, workspace, branch, and runtime settings.AUXILIARY_*_API_KEY,AUXILIARY_*_BASE_URL,GATEWAY_RELAY_*) from the worker env._default_spawn()workers.Tests