Skip to content

fix(security): strip Bedrock inference bearer token from subprocess env (#32314) - #34498

Merged
teknium1 merged 2 commits into
mainfrom
fix/32314-bedrock-bearer-token-strip
May 29, 2026
Merged

fix(security): strip Bedrock inference bearer token from subprocess env (#32314)#34498
teknium1 merged 2 commits into
mainfrom
fix/32314-bedrock-bearer-token-strip

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

The bug (confirmed live on main)

bedrock's ProviderConfig declares api_key_env_vars=() because it uses
auth_type="aws_sdk" (boto3 credential chain). _build_provider_env_blocklist()
only consults api_key_env_vars, and there were zero AWS_* entries in the
hardcoded set. Net effect: every other provider's key is stripped from
terminal/execute_code subprocess env, but a Bedrock user's
AWS_BEARER_TOKEN_BEDROCK leaked into every child process — the reporter
caught it when opencode models run inside a Hermes terminal enumerated the
entire Bedrock catalog off the leaked bearer token.

Closes #32314.

The fix — narrow, no capability regression

Strip only AWS_BEARER_TOKEN_BEDROCK, the Bedrock-specific Hermes
inference secret (exactly analogous to OPENAI_API_KEY). The strip is keyed
off auth_type=="aws_sdk", so it is self-healing — any future SDK-cred
provider is covered automatically without editing a list.

The general AWS credential chain (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN, AWS_PROFILE, region/config/role pointers) is
intentionally left inheritable. Per SECURITY.md §3.2 the local terminal is
the user's trusted operator shell; the agent having the same general AWS access
the user's own shell has is the intended posture.

Hard-blocklisting the full chain (as the original PRs in this cluster did) would:

  1. Regress every user, not just Bedrock users — PROVIDER_REGISTRY is
    iterated unconditionally at import, so the aws_sdk branch fires for
    everyone. A pure-OpenAI user running aws s3 cp / terraform apply / a
    boto3 script in the agent terminal would lose their creds for no security
    benefit.
  2. Be unrecoverabletools/env_passthrough.py refuses to re-allow
    anything in _HERMES_PROVIDER_ENV_BLOCKLIST (GHSA-rhgp-j443-p4rf), so there
    is no config or skill escape hatch. Capability gone, permanently.

Verification

Live E2E (real bash subprocess via LocalEnvironment.execute(), AWS vars
actually in os.environ — not mocked):

STRIPPED:    AWS_BEARER_TOKEN_BEDROCK, OPENAI_API_KEY
PRESERVED:   AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN,
             AWS_PROFILE, AWS_DEFAULT_REGION

Tests (tests/tools/test_local_env_blocklist.py, all 22 pass):

Salvage / attribution

Built on @zapabob's #34387 (the self-healing auth_type=="aws_sdk" mechanism),
narrowed to bearer-token-only. Supersedes #34387, #32319 (@briandevans),
#32402 (@leavedrop), #32374 (@HiddenPuppy) — all four implemented the same
fix but hard-blocklisted the full AWS chain, which trips the regression above.

Co-authored-by: zapabob 1920071390@campus.ouj.ac.jp

zapabob and others added 2 commits May 29, 2026 01:27
…ken only

Scopes the AWS_SDK subprocess strip down from the full AWS credential chain
to just AWS_BEARER_TOKEN_BEDROCK — the only Hermes-managed *inference* secret
(analogous to OPENAI_API_KEY). The general AWS credential chain
(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN / AWS_PROFILE
/ config + role pointers) is intentionally left inheritable.

Why: per SECURITY.md §3.2 the local terminal is the user's trusted operator
shell. Hard-blocklisting the general chain would (a) regress *every* user who
runs aws/terraform/cdk/boto3 in the agent terminal — not just Bedrock users,
since PROVIDER_REGISTRY is iterated unconditionally at import — and (b) be
unrecoverable, because env_passthrough.py refuses to re-allow anything in
_HERMES_PROVIDER_ENV_BLOCKLIST (GHSA-rhgp-j443-p4rf). The narrow strip closes
the reported leak (opencode enumerating the Bedrock catalog off the leaked
bearer token) with no capability loss.

Keeps zapabob's self-healing auth_type=="aws_sdk" mechanism so any future
SDK-cred provider is covered automatically.

Tests: bearer token stripped + general chain preserved (no-regression guard),
on both the runtime strip path and the blocklist-membership path.

Co-authored-by: zapabob <1920071390@campus.ouj.ac.jp>
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: fix/32314-bedrock-bearer-token-strip vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9439 on HEAD, 9439 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4898 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/local Local shell execution P1 High — major feature broken, no workaround provider/bedrock AWS Bedrock (boto3, IAM) type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: auth_type="aws_sdk" never feeds into subprocess credential blocklist; AWS env vars leak to terminal/execute_code

3 participants