Skip to content

ANTHROPIC_AUTH_TOKEN readable in agent container — missing from AWF_ONE_SHOT_TOKENS protection #6408

Description

@lpcox

Summary

ANTHROPIC_AUTH_TOKEN (Anthropic key format, sk-ant-p prefix, len 47) is provisioned into the agent container environment and is freely readable by the agent and all its subprocesses. Unlike ANTHROPIC_API_KEY, it is absent from AWF_ONE_SHOT_TOKENS, so the one-shot-token.so LD_PRELOAD shim never intercepts it, and it is also absent from the GH_AW_SECRET_NAMES redaction list. The Anthropic SDK/CLI accept ANTHROPIC_AUTH_TOKEN as a valid auth credential, so an adversarial prompt injection could read and exfiltrate it via any allowed outbound channel.

This is an inconsistency in AWF's credential-protection model: a sibling Anthropic credential name escapes the exact mechanism (AWF_ONE_SHOT_TOKENS + one-shot-token.so) that AWF uses to neutralize named secrets.

Originally identified in the security repo as githubnext/gh-aw-security#2775 (open). Filing here because the fix lives in the firewall/AWF layer (the one-shot token list, the redaction list, and the awf --exclude-env invocation).

Runtime confirmation (new)

Two secret-digger pentest cards were run under the hardened agent runtimes using the most powerful model (Opus):

So the exposure is present under the default and gVisor runtimes and is contained only by the docker-sbx microVM boundary. The right fix is at the AWF token-protection layer so it holds regardless of runtime.

Evidence

ANTHROPIC_AUTH_TOKEN present and readable, but not protected while ANTHROPIC_API_KEY is:

$ python3 -c "import os; v=os.environ.get('ANTHROPIC_AUTH_TOKEN',''); print(f'present={bool(v)}, len={len(v)}, prefix={v[:8]}')"
present=True, len=47, prefix=sk-ant-p

$ python3 -c "import os; l=os.environ.get('AWF_ONE_SHOT_TOKENS','').split(','); print('AUTH_TOKEN protected:', 'ANTHROPIC_AUTH_TOKEN' in l); print('API_KEY protected:', 'ANTHROPIC_API_KEY' in l)"
AUTH_TOKEN protected: False
API_KEY protected: True

Full AWF_ONE_SHOT_TOKENS list (no ANTHROPIC_AUTH_TOKEN):

COPILOT_GITHUB_TOKEN,GITHUB_TOKEN,GH_TOKEN,GITHUB_API_TOKEN,GITHUB_PAT,
GH_ACCESS_TOKEN,OPENAI_API_KEY,OPENAI_KEY,ANTHROPIC_API_KEY,CLAUDE_API_KEY,
CODEX_API_KEY,COPILOT_API_KEY,COPILOT_PROVIDER_API_KEY

Readable via /proc/self/environ (bypasses the getenv/secure_getenv hook even for covered names):

$ cat /proc/self/environ | tr '\0' '\n' | grep -oE '^ANTHROPIC_AUTH_TOKEN'
ANTHROPIC_AUTH_TOKEN

One-shot shim is active (so the omission is a list gap, not a disabled mechanism):

$ ls -la $(printenv LD_PRELOAD)
-rwxr-xr-x 1 root root 14712 /tmp/awf-lib/one-shot-token.so
$ nm -D /tmp/awf-lib/one-shot-token.so | grep ' T '
... T getenv
... T secure_getenv

Reproduction

# 1. Token present and readable
python3 -c "import os; v=os.environ.get('ANTHROPIC_AUTH_TOKEN',''); print(f'present={bool(v)}, len={len(v)}, prefix={v[:8]}')"
#   hardened: NOT_SET or intercepted; observed: present=True, len=47, prefix=sk-ant-p

# 2. Absent from one-shot protection
python3 -c "import os; print('protected:', 'ANTHROPIC_AUTH_TOKEN' in os.environ.get('AWF_ONE_SHOT_TOKENS','').split(','))"
#   observed: False

# 3. Sibling key IS protected
python3 -c "import os; print('API_KEY protected:', 'ANTHROPIC_API_KEY' in os.environ.get('AWF_ONE_SHOT_TOKENS','').split(','))"
#   observed: True

Preconditions: any Claude-engine gh-aw workflow where ANTHROPIC_AUTH_TOKEN is provisioned into the agent container and the agent has bash access.

Suggested mitigations

  1. Add ANTHROPIC_AUTH_TOKEN to AWF_ONE_SHOT_TOKENS so one-shot-token.so intercepts getenv/secure_getenv and unsetenv()s it after first read.
  2. Add ANTHROPIC_AUTH_TOKEN to the GH_AW_SECRET_NAMES redaction list so it is scrubbed from logs/artifacts.
  3. Prefer excluding it from the agent container entirely via awf --exclude-env ANTHROPIC_AUTH_TOKEN (analogous to the existing --exclude-env ANTHROPIC_API_KEY) if the token is only needed by the api-proxy sidecar — this is the most robust fix since it also closes the /proc/self/environ read path that the LD_PRELOAD shim cannot cover.
  4. Audit all Anthropic-recognized credential variable names for any other names missing from the protection/exclusion/redaction lists.

Notes

  • No secret values are disclosed here — only the non-sensitive sk-ant-p format prefix and length.
  • Cross-reference: githubnext/gh-aw-security#2775 (canonical finding). Related: githubnext/gh-aw-security#2338 (GEMINI_API_KEY similar gap).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions