Security: exclude all secret-bearing env vars from agent container via AWF --exclude-env#23360
Security: exclude all secret-bearing env vars from agent container via AWF --exclude-env#23360
Conversation
…om agent container env via AWF --exclude-env flag Agent-Logs-Url: https://github.com/github/gh-aw/sessions/f77df111-2010-4960-b0c4-805f269dc54c Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
|
Hey A few small observations worth addressing before this is promoted out of draft:
|
|
@copilot make sure that the compiler is very strict about which environment variables are passed to awf |
There was a problem hiding this comment.
Pull request overview
This PR hardens AWF container execution by ensuring sensitive GitHub tokens are not exposed to the agent container environment when --env-all is used.
Changes:
- Bump default AWF version to
v0.26.0(to pick up--exclude-envsupport). - Add an exclusion list for sensitive env vars and emit
--exclude-envflags after--env-allin AWF command construction. - Update tests and golden/lock outputs to assert the new flags are present.
Reviewed changes
Copilot reviewed 116 out of 186 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
pkg/constants/constants.go |
Bumps default AWF version and introduces the excluded env var list. |
pkg/workflow/awf_helpers.go |
Appends --exclude-env flags to AWF args generation. |
pkg/workflow/gh_cli_mount_test.go |
Adds assertions that both sensitive env vars are excluded. |
pkg/workflow/firewall_args_integration_test.go |
Adds assertions that compiled workflows include --exclude-env (currently only for one token). |
pkg/workflow/testdata/wasm_golden/** |
Updates wasm golden outputs for AWF version and new flags. |
.github/workflows/*.lock.yml |
Recompiled workflows reflecting AWF version bump and --exclude-env additions. |
.changeset/patch-exclude-secret-env-vars-from-agent-container.md |
Adds release note for the security change and version bump. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pkg/workflow/awf_helpers.go
Outdated
| // Pass all environment variables to the container, but exclude sensitive tokens. | ||
| // AWF's API proxy (--enable-api-proxy) handles authentication for COPILOT_GITHUB_TOKEN | ||
| // and GITHUB_MCP_SERVER_TOKEN transparently, so the container does not need the raw | ||
| // values. Excluding them via --exclude-env prevents a prompt-injected agent from | ||
| // exfiltrating tokens through bash tools such as `env` or `printenv`. | ||
| // Requires AWF v0.26.0+ for --exclude-env support. | ||
| awfArgs = append(awfArgs, "--env-all") | ||
| for _, excludedVar := range constants.AWFExcludedEnvVars { | ||
| awfArgs = append(awfArgs, "--exclude-env", excludedVar) | ||
| } |
There was a problem hiding this comment.
BuildAWFArgs always appends --exclude-env flags, but the AWF version can be overridden via network.firewall.version (and the install step uses that version). If a workflow pins an older AWF (< v0.26.0), the compiled command will include an unsupported flag and fail at runtime. Consider gating --exclude-env emission on the effective AWF version (e.g., default or firewallConfig.Version), only adding it for v0.26.0+ (and possibly latest).
| // Verify sensitive token vars are excluded | ||
| if !strings.Contains(lockYAML, "--exclude-env COPILOT_GITHUB_TOKEN") { | ||
| t.Error("Compiled workflow should exclude COPILOT_GITHUB_TOKEN via --exclude-env") | ||
| } | ||
|
|
There was a problem hiding this comment.
This test asserts --exclude-env COPILOT_GITHUB_TOKEN but does not assert --exclude-env GITHUB_MCP_SERVER_TOKEN, even though the implementation adds both exclusions. Adding the second assertion would prevent regressions where only one token remains excluded.
This issue also appears in the following locations of the same file:
- line 148
- line 242
pkg/constants/constants.go
Outdated
| // AWFExcludedEnvVars lists the environment variable names that must be excluded from the | ||
| // agent container's visible environment via AWF's --exclude-env flag (requires AWF v0.26.0+). | ||
| // | ||
| // These are sensitive GitHub tokens that the agent process should never be able to read | ||
| // directly. AWF's API proxy handles authentication for these tokens transparently, so the | ||
| // container does not need the raw values. Excluding them prevents a prompt-injection attack | ||
| // from exfiltrating tokens via bash tools such as `env` or `printenv`. | ||
| var AWFExcludedEnvVars = []string{ | ||
| "COPILOT_GITHUB_TOKEN", | ||
| "GITHUB_MCP_SERVER_TOKEN", | ||
| } |
There was a problem hiding this comment.
AWFExcludedEnvVars is an exported, mutable slice. Any importing package could append/modify it at runtime, which could inadvertently weaken the intended security behavior. Consider making it unexported and exposing a function that returns a copy, or otherwise ensuring callers can’t mutate the underlying slice.
|
@copilot apply changes based on the comments in this thread |
… AWF container Agent-Logs-Url: https://github.com/github/gh-aw/sessions/264a9d15-b1ac-4e0d-b588-e0d926b90034 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Done in 922df6f. The compiler now dynamically computes the exact
The hardcoded Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
…R_TOKEN assertions Agent-Logs-Url: https://github.com/github/gh-aw/sessions/ce30b6f6-2d89-4cd0-b64d-2a863bdd9854 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Done in c63ab88. Applied all three review changes:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
When
--env-allpasses the full runner environment into the AWF container, sensitive tokens are visible to any bash tool the agent runs — creating a prompt-injection exfiltration vector inpull_request_targetworkflows. AWF v0.26.0 adds--exclude-envto strip specific vars from the container's visible environment while the API proxy continues to handle auth transparently.Changes
pkg/constants/constants.go: BumpDefaultFirewallVersion→v0.26.0; addAWFExcludeEnvMinVersion = "v0.26.0"constant marking the minimum AWF version that supports--exclude-envpkg/workflow/awf_helpers.go:ExcludeEnvVarNames []stringfield toAWFCommandConfigComputeAWFExcludeEnvVarNames(workflowData, coreSecretVarNames)helper that dynamically computes the exact exclude list per workflow by scanning for actual${{ secrets.* }}references across: engine core tokens, MCP gateway key, GitHub MCP server token, HTTP MCP header secrets, mcp-scripts env vars,engine.env, andagent.envawfSupportsExcludeEnv(firewallConfig)helper that gates--exclude-envemission on the effective AWF version being ≥ v0.26.0 (latestand default/unset are treated as ≥ the minimum)BuildAWFArgs, emit sorted--exclude-envflags only when the effective AWF version supports it — workflows pinning an older version (e.g.v0.25.0) compile without the flag to avoid runtime failuresComputeAWFExcludeEnvVarNameswith its core secret var names so the exclude list is workflow-specific and completeGITHUB_MCP_SERVER_TOKENis excluded whentools.githubis configured, and that--exclude-envis absent when an old AWF version is pinned;TestAWFSupportsExcludeEnvunit tests cover all version edge cases--exclude-envlists, e.g.:Non-secret mcp-scripts vars (e.g.
GH_DEBUG: "1") are not excluded — only vars whose configured values contain a${{ secrets.* }}reference are excluded.Requires the companion AWF change (gh-aw-firewall#1482) to land before this takes effect at runtime.
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.