Blog Published: Aug 2, 2026

Claude Code GitHub Action: When a File-Read Tool Crosses the CI Secret Boundary

Microsoft found that untrusted GitHub issue, pull request, or comment text could direct Claude Code GitHub Action to read /proc/self/environ. Bash commands were inside bubblewrap and received a scrubbed environment, but the in-process Read tool used a different path and returned ANTHROPIC_API_KEY; removing its prefix helped evade refusal and GitHub redaction. Anthropic patched the reported sensitive /proc read, but every tool path still needs the same secret boundary and deterministic authorization.

Indirect Prompt InjectionCredential ExposureTool AuthorizationAI Coding AgentGitHub Security
6 applicable AIDEFEND defenses
Source: Securing CI/CD in an agentic world: Claude Code Github action case 
Authors: Microsoft Defender Security Research Team, Dor Edry, Amit Eliahu
Original article: Jun 5, 2026

Threat Analysis

  • Untrusted GitHub text becomes agent context. An attacker with no repository write access can place a compliance-framed instruction in an issue, pull request, or comment that an eligible workflow passes to Claude Code.
  • Two tool paths enforce different boundaries. Bash runs inside bubblewrap and receives environment scrubbing through CLAUDE_CODE_SUBPROCESS_ENV_SCRUB. The in-process Read tool was outside both protections and could open /proc/self/environ.
  • Transformation weakens downstream filters. The prompt asks Claude to remove the first seven characters from the Anthropic key, avoiding the model's refusal behavior and the recognizable sk-ant- pattern used by GitHub redaction.
  • Several release channels may exist. Depending on workflow configuration, transformed data could leave through WebFetch, Bash, GitHub MCP actions, or show_full_output logs.
  • This was controlled research and is patched. Microsoft reported the issue on April 29, 2026 and says Anthropic fixed it in Claude Code 2.1.128 by rejecting reads of sensitive /proc files.

Applicable AIDEFEND Defenses (6)

AID-H-017.003
Decoupled Plan-Then-Execute Architecture
Very High
Require Claude to emit a structured read proposal instead of opening paths directly. A deterministic Action Selector should resolve the requested path under an approved repository root, reject traversal and sibling-prefix escapes, validate the action against a role allowlist, and dispatch only registered tools. This directly rejects /proc/self/environ. The mapped howTo does not make validation and file opening atomic, so production code must separately resist symlink-swap and TOCTOU races.
AID-H-017.007
Dual-LLM Isolation Pattern
Very High
Parse raw issue, pull request, and comment text with a quarantined model that has no repository, filesystem, network, or credential access. A validating broker may release only allowlisted repository-task fields and opaque GitHub object identifiers in a signed envelope; generic free text is not a security boundary. Every privileged proposal still requires executor authorization.
AID-D-003.002
Sensitive Information & Data Leakage Detection
High
Build a signed tenant rule pack that contains a protected literal for the exact prefix-stripped Anthropic key, or another bounded RE2 rule that matches the organization's reconstructable key material. Scan each complete canonical output field and emit signed, response-bound evidence. This detects only configured representations and does not block release by itself.
AID-H-006.002
Text, Markup & Structured Output Sanitization and Release Gate
High
Hold the complete response or tool argument until the tenant-specific detector above, redaction, and sink policy finish. A finding, timeout, malformed result, evidence failure, or detector error releases nothing. This is a direct boundary only for WebFetch, GitHub MCP, task-output, log, and other channels actually integrated with the gate.
AID-H-018.004
Intent-Based Dynamic Capability Scoping
Medium
Register Read, Bash, WebFetch, GitHub write, and full-output release as distinct tool names or capabilities. Derive the signed set of allowed names, action budget, and expiry from trusted workflow configuration and the authenticated trigger, not issue or comment text. This can exclude external and state-changing tools from triage, but it cannot distinguish /proc from repository paths inside an allowed Read tool.
AID-I-001.004
Sandbox Network Egress Restrictions
Medium
Default-deny outbound traffic from the Action's execution sandbox and allow only exact required model and GitHub endpoints through an external enforcement point. This removes arbitrary WebFetch and Bash callback paths after a tool-policy failure, but it does not govern allowed GitHub APIs or workflow logs.

What Defenders Should Do Now

  • Update every Claude Code runner and Action image to version 2.1.128 or later. In an isolated repository, verify that Read and every other filesystem-capable tool reject direct and canonical variants of sensitive /proc paths, traversal, and sibling-prefix escapes.
  • Review workflow triggers and trust conditions. Do not expose secrets and external or state-changing tools to a job that automatically consumes issue, pull request, or comment text from an untrusted actor.
  • Put all model-proposed file actions through one deterministic selector. Resolve paths under an approved checkout root. Open files relative to a trusted root descriptor with openat2(RESOLVE_BENEATH|RESOLVE_NO_SYMLINKS), O_NOFOLLOW, or a platform-equivalent atomic mechanism, then pass that same descriptor to Read instead of checking and reopening by path. Test symlink swaps and TOCTOU races.
  • Use a no-tool quarantined model plus a validating broker to parse untrusted GitHub content. Give the privileged model only allowlisted repository-task fields and opaque object IDs, and derive its signed tool scope from workflow policy rather than the text being analyzed.
  • Keep outbound access default-deny and disable show_full_output for secret-bearing jobs. Separately test prefix-stripped and otherwise transformed values at WebFetch, Bash, GitHub MCP, task-output, and log release gates.
  • If exposure is possible, preserve workflow input, tool-call, output, network, and audit evidence; revoke and rotate the Anthropic key; inspect provider usage; and review any GitHub actions the job could perform.

2 additional considerations

Derived-secret lineage across transformations and allowed sinks

The current value-level sink howTo looks up labels through a server-side content identifier; it does not implement substring lineage, prefix-removal propagation, or implicit-flow tracking. Network egress controls also cannot protect an allowed GitHub API, task output, or workflow log.
Recommendation: Keep secrets opaque and server-side whenever possible. Add transformation-aware secret detection and release gates at WebFetch, Bash, GitHub MCP, task-output, and log sinks, then test prefix removal, slicing, encoding, formatting, chunk boundaries, and approved-destination abuse.

Anthropic API-key revocation adapter

The mapped controls cover the preventive read, isolation, capability, and network boundaries. A possibly exposed Anthropic API key still requires the vendor's authoritative key-management workflow. The framework's concrete long-lived-credential guidance is an AWS IAM access-key pattern for Secrets Manager and ECS, so this brief keeps Anthropic key handling as a separate product-specific procedure rather than mapping it above.
Recommendation: Use Anthropic's authoritative key-management path to revoke or rotate the affected key, update every known consumer, verify the old value no longer authenticates, and preserve issuer and consumer evidence. Keep this action as a product-specific response until a matching framework adapter exists.

Conclusion

The reported defect was not that Claude Code had no sandbox. It was that Bash and Read crossed the same secret boundary through different enforcement paths. The patch closes the documented /proc read, while the broader engineering lesson remains: untrusted CI text must be separated from privileged planning, every proposed path must pass one deterministic selector, and sensitive values must stay protected after transformation and through every output channel.