Skip to content

security: scope safe-outputs write-sink to a distinct bearer token#23928

Closed
Copilot wants to merge 2 commits intomainfrom
copilot/fix-scope-bearer-token-issue
Closed

security: scope safe-outputs write-sink to a distinct bearer token#23928
Copilot wants to merge 2 commits intomainfrom
copilot/fix-scope-bearer-token-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

The MCP gateway issues a single MCP_GATEWAY_API_KEY used as the Authorization header for every server in the agent's mcp-config.json. Any bash process with read access to that file (including prompt-injection payloads or malicious dependencies) can call the safeoutputs write-sink endpoint directly through the gateway with the shared key, queuing GitHub write operations (create_issue, add_comment, etc.) without agent involvement.

Changes

Key generation (mcp_setup_generator.go)

  • Generate GH_AW_WRITE_SINK_API_KEY (360-bit random, masked immediately) alongside MCP_GATEWAY_API_KEY when safe-outputs is enabled
  • Pass it to the gateway container via -e GH_AW_WRITE_SINK_API_KEY

Gateway input config (mcp_config_builtin.go)

Add a clientApiKey field to the safeoutputs server entry, pointing to GH_AW_WRITE_SINK_API_KEY. The gateway uses this per-server token in the output config for the safeoutputs endpoint instead of the shared gateway key — so the agent's mcp-config.json carries different Authorization values for github vs safeoutputs:

"safeoutputs": {
  "type": "http",
  "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
  "headers": { "Authorization": "${GH_AW_SAFE_OUTPUTS_API_KEY}" },
  "clientApiKey": "${GH_AW_WRITE_SINK_API_KEY}",
  ...
}

Env isolation (awf_helpers.go)

Exclude GH_AW_WRITE_SINK_API_KEY from the agent container via --exclude-env; the agent reads it only from the gateway-written mcp-config.json.

MCP Gateway Spec (mcp-gateway.md)

  • Add clientApiKey to the §4.1.2 server config field table
  • Add §7.7 "Per-Server Client API Keys" defining the security model, enforcement rules, and output config behaviour
  • Bump spec to v2.0.0

Gateway enforcement: The compiler side is complete. The gateway container (gh-aw-mcpg) must be updated separately to enforce clientApiKey per §7.7 — rejecting requests that present the gateway key on the safeoutputs endpoint and using clientApiKey in the output config for that server.

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:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw /tmp/go-build356rev-parse 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git -unreachable=falgit /tmp/go-build356rev-parse k/_temp/uv-pytho--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env 5181023/b409/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env 5181023/b407/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name .go .go modules/@npmcli/run-script/lib/node-gyp-bin/sh GitHubMCPRemoteOnode /home/REDACTED/wor/home/REDACTED/.npm/_npx/b388654678d519d9/node_modules/.bin/prettier rgo/bin/bash x_amd64/vet --no�� h ../../../.pret.prettierignore grep 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteOnode /home/REDACTED/wor/home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/.bin/prettier /opt/hostedtoolc--write 64/pkg/tool/linu../../../**/*.json (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel 64/pkg/tool/linuremote.origin.url /usr/bin/git on' --ignore-patgit bash ode_modules/.bin--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x/home/REDACTED/work/gh-aw/gh-aw/pkg/mathutil/mathutil_test.go /usr/bin/git se 1043245/b070/vetrev-parse x_amd64/vet /usr/bin/git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --write ../../../**/*.json /usr/bin/infocmp --ignore-path ../../../.prettirev-parse x_amd64/vet infocmp -1 xterm-color x_amd64/vet /usr/bin/git --noprofile grep x_amd64/vet git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha 6367256/b001/workflow.test -buildtags bash -errorsas -ifaceassert -nilfunc REOS4ESqgWYGZ/Zi^remote\..*\.gh-resolved$ -uns�� 0/001/test-simple-frontmatter.md-errorsas /tmp/go-build3561043245/b199/vet-ifaceassert x_amd64/vet ignore grep 64/bin/bash x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -v 64/pkg/tool/linuconfig /usr/bin/git se 1043245/b213/vetrev-parse ache/go/1.25.0/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x/home/REDACTED/work/gh-aw/gh-aw/pkg/stringutil/identifiers.go /usr/bin/git --noprofile bash .cfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel bash /usr/bin/git rite '../../../*git -tests ache/go/1.25.0/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet 86_64/node ndor/bin/bash bash /home/REDACTED/wor--show-toplevel git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha ts.result 64/pkg/tool/linu-buildtags /usr/bin/git --noprofile .cfg 64/pkg/tool/linu--show-toplevel git add .github/workflows/test.md 64/pkg/tool/linu-tests /usr/bin/git json' --ignore-pgit pkg/workflow/coprev-parse 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha /tmp/go-build522163653/b445/_pkg_.a -trimpath r,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,disp--show-toplevel -p flow -lang=go1.25 git conf�� 0:00Z remote.origin.url /usr/bin/git -c=4 -nolocalimports -importcfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel 6n/cLzQgjXlIjxIo_QUvJx9/udQqw-GTJ_pvEl_0q8G_ /usr/bin/git te '**/*.cjs' '*git bash _.a git rev-�� --show-toplevel bash /usr/bin/git agent-performancgit bash 0/x64/bin/node git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha PDockerOptions g/workflow/prompts.go ep PDockerOptions ssions_validatio--norc de/node/bin/grep--noprofile grep -l PDockerOptions g/workflow/runtime_overrides.go ndor/bin/bash PDockerOptions _test.go tnet/tools/grep grep (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --noprofile grep ache/uv/0.11.2/x86_64/bash PDockerOptions g/workflow/call_-unsafeptr=false nfig/composer/ve-unreachable=false bash --no�� nfig grep bash ATEWAY_API_KEY\|/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet g/workflow/activ-atomic tnet/tools/grep bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -v mcp-gateway.md x_amd64/vet GitHubMCPRemoteOsh (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha /tmp/TestHashConsistency_GoAndJavaScript504361000/001/test-inlined-imports-enabled-with-env-tempgit 64/pkg/tool/linu-buildtags /usr/bin/git --noprofile .cfg 64/pkg/tool/linu--show-toplevel git -C /tmp/gh-aw-test-runs/20260401-170039-15870/test-3009736392 rev-parse /usr/bin/git @{u} bash 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha /tmp/shared-actions-test2620327792 config /usr/bin/git remote.origin.urgit .cfg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linuconfig /usr/bin/git json' --ignore-pgit bash ache/go/1.25.0/x--show-toplevel git (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
  • https://api.github.com/repos/github/gh-aw
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw --jq .visibility -json GO111MODULE r: $owner, name: $name) { hasDiscussionsEnabled } } GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha /tmp/file-tracker-test3382190166/test1.md /tmp/file-tracker-test3382190166/test2.lock.yml /usr/bin/git func buildMCPGatgit pkg/workflow/mcprev-parse 64/pkg/tool/linu--show-toplevel git -C /tmp/gh-aw-test-runs/20260401-170039-15870/test-3009736392 status /usr/bin/git .github/workflowgit ls .cfg git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha 0039-15870/test-3009736392 **/*.cjs /node_modules/.bin/sh **/*.json --ignore-path ../../../.pretti--show-toplevel sh 1636�� "prettier" --write '../../../**/*.json' '!../../../pkg/workflow/js/**/*.json' ---p 163653/b402/_testmain.go 0/x64/bin/node rror grep x_amd64/vet /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linu1 (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha licyMinIntegrityOnlymin-integrity_only_defaults_repo4069419533/001 **/*.cjs 163653/b399/vet.cfg **/*.json --ignore-path ../../../.pretti--show-toplevel sh -c "prettier" --write '../../../**/*.json' '!../../../pkg/workflow/-s x_amd64/vet /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile rror grep run-script/lib/n--show-toplevel /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linu-buildtags (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 1043245/b177/vet.cfg tions/setup/node_modules/.bin/sh --noprofile grep k/gh-aw/gh-aw/gh--show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -c */*.ts' '**/*.json' --ignore-path ../../../.prettierignore log ache/uv/0.11.2/x86_64/bash -n1 --format=format:rev-parse f500c322838b /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linu../../../**/*.json (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 1043245/b226/vet-ifaceassert tions/node_modul-nilfunc --noprofile grep bash ache/go/1.25.0/x-tests -c */*.ts' '**/*.json' --ignore-patremote.origin.url bash /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet --noprofile mcp-gateway.md de/node/bin/bash--get /opt/hostedtoolcremote.origin.url (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 1043245/b224/vet.cfg x_amd64/link --noprofile grep tnet/tools/bash x_amd64/link +x */*.ts' '**/*.json' --ignore-path ../../../.prettierignore bash /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet --noprofile grep 0/x64/bin/bash 0M/1Fap-IuZJNLVp9lBXgZ8/WLtSFBQ1EBh5VjaADAVW (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 1043245/b228/vet.cfg bin/sh --noprofile grep ndor/bin/bash ache/go/1.25.0/x64/pkg/tool/linu-extld=gcc -V=f�� */*.ts' '**/*.json' --ignore-path ../../../.pret.prettierignore bash ndor/bin/sh --noprofile grep 86_64/bash /opt/hostedtoolcache/go/1.25.0/xremote.origin.url (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 1043245/b204/vet.cfg ules/.bin/sh --noprofile grep /usr/local/.ghcu--show-toplevel ache/go/1.25.0/x64/pkg/tool/linu--jq (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 1043245/b185/vet.cfg de_modules/.bin/sh --noprofile grep /home/REDACTED/.co--show-toplevel ache/go/1.25.0/x64/pkg/tool/linuconfig -V=f�� 1160273683/.github/workflows bash bin/bash \|renderJSON grep cal/bin/bash /opt/hostedtoolcache/go/1.25.0/xremote.origin.url (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 1043245/b183/vet.cfg tions/node_modules/.bin/sh --noprofile grep /home/REDACTED/.ca--show-toplevel ache/go/1.25.0/x64/pkg/tool/linurev-parse cat-�� md f500c322838b39e13f514bd9ab2b25e32a6fd0e4:go.mod cal/bin/bash ncludeCopilotFienode grep ache/uv/0.11.2/x/home/REDACTED/work/gh-aw/gh-aw/.github/workflows/ai-moderator.md /opt/hostedtoolcache/go/1.25.0/xremote.origin.url (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --noprofile grep x_amd64/vet GitHubMCPRemoteOnode /home/REDACTED/wor/opt/hostedtoolcache/node/24.14.0/x64/bin/npm ache/node/24.14.run x_amd64/vet --no�� h ../../../.prettierignore ilot_engine.go modules/@npmcli/run-script/lib/node-gyp-bin/node GitHubMCPRemoteObash /home/REDACTED/wor--norc nfig/composer/ve--noprofile 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 /home/REDACTED/wor-atomic 86_64/bash x_amd64/asm /pre�� --noprofile .cfg 64/pkg/tool/linu-nilfunc --noprofile grep rgo/bin/bash 64/pkg/tool/linurev-parse (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 grep /usr/local/sbin//tmp/gh-aw-test-runs/20260401-170039-15870/test-3009736392 ache/go/1.25.0/xstatus -n '**/*.ts' '**/*..github/workflows/test.md docs/src/content/docs/reference/mcp-gateway.md ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet thub/workflows grep bin/bash ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel ache/go/1.25.0/x64/pkg/tool/linurev-parse /usr/bin/git --noprofile bash 0/x64/lib/node_m--show-toplevel git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.0/xremote.origin.url /usr/bin/git .js' --ignore-pagit /tmp/go-build356show-ref tions/setup/js/n--verify git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --noprofile bash At,event,headBranch,headSha,displayTitle --noprofile grep rgo/bin/bash 8A/RFr094xa-M6ehmK-ZS-f/-nXLG8d---json -uns�� rity2668569879/001 /tmp/go-build3561043245/b039/vetnonexistent-workflow-12345 tions/setup/js/node_modules/.bin--limit --noprofile mcp-gateway.md (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha --noprofile .cfg 64/pkg/tool/linux_amd64/vet OUTPUTS_API_KEY\/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/link ecution.go 0/x64/bin/bash 64/pkg/tool/linu-importcfg /pre�� --noprofile .cfg 64/pkg/tool/linu-buildmode=exe --noprofile grep bash 64/pkg/tool/linu-extld=gcc (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha --noprofile .cfg 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteO/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile /home/REDACTED/wor-o cal/bin/bash 64/pkg/tool/linu-trimpath /pre�� --noprofile .cfg 64/pkg/tool/linu-lang=go1.25 --noprofile grep /snap/bin/bash 64/pkg/tool/linuconfig (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha --noprofile grep 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteO/tmp/go-build522163653/b402/console.test /home/REDACTED/wor-test.testlogfile=/tmp/go-build522163653/b402/testlog.txt tnet/tools/bash 64/pkg/tool/linu-test.v=true --no�� --noprofile .cfg 64/pkg/tool/linu-test.short=true --noprofile grep /usr/local/.ghcu/tmp/TestGuardPolicyBlockedUsersExpressionCompiledOutput3438479228/001 64/pkg/tool/linurev-parse (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha --noprofile grep 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteO/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile /home/REDACTED/wor-o ash 64/pkg/tool/linu-trimpath --no�� --noprofile .cfg _modules/.bin/no-lang=go1.25 --noprofile grep k/_temp/uv-pytho--show-toplevel 64/pkg/tool/linu-goversion (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha --noprofile grep 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteO/tmp/go-build522163653/b396/cli.test /home/REDACTED/wor-test.testlogfile=/tmp/go-build522163653/b396/testlog.txt nfig/composer/ve-test.paniconexit0 64/pkg/tool/linu-test.v=true --no�� --noprofile .cfg 64/pkg/tool/linu-test.short=true --noprofile grep -aw 64/pkg/tool/linuconfig (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha 4dte/WU3MsYOXbC6GOINSECURE GO111MODULE $name) { hasDiscussionsEnabled } } GOINSECURE GOMOD GOMODCACHE 5181023/b409/impGOPROXY -c che/go-build/28/GOSUMDB GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go /opt/hostedtoolcrev-parse (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha '**/*.ts' '**/*.go1.25.0 ache/go/1.25.0/x-c=4 cal/bin/bash --noprofile l p/bin/bash /opt/hostedtoolc/tmp/go-build522163653/b442/_testmain.go -uns�� .js' --ignore-path .prettierignore --log-level=error /tmp/go-build3561043245/b041/vet.cfg tions/node_modules/.bin/node pkg/workflow/datgit mcp-gateway.md tnet/tools/bash /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linu-trimpath (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion --noprofile grep (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo de GitHubMCPRemoteOsh /home/REDACTED/wor-c bash bash /pre�� --noprofile grep (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo p/bin/bash GitHubMCPRemoteOsh /home/REDACTED/wor-c /home/REDACTED/.canpx prettier --write '../../../**/*.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path bash /pre�� --noprofile grep 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteO/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile /home/REDACTED/wor-o k/_temp/ghcca-no/tmp/go-build522163653/b457/_pkg_.a 64/pkg/tool/linu-trimpath (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build522163653/b396/cli.test /tmp/go-build522163653/b396/cli.test -test.testlogfile=/tmp/go-build522163653/b396/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GitHubMCPRemoteOnode /home/REDACTED/wor/opt/hostedtoolcache/node/24.14.0/x64/bin/npx rgo/bin/bash x_amd64/vet --no�� ath ../../../.pr--ignore-path grep 64/pkg/tool/linu--log-level=error GitHubMCPRemoteOsh /home/REDACTED/wor-c /opt/hostedtoolc"prettier" --write '../../../**/*.json' '!../../../pkg/workflow/js/**/*.json' ---errorsas 64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name f() { test "$1" = get && echo "p-errorsas f() { test "$1" = get && echo "p-ifaceassert x_amd64/vet GitHubMCPRemoteOnode /home/REDACTED/wor/home/REDACTED/.npm/_npx/b388654678d519d9/node_modules/.bin/prettier cal/bin/bash x_amd64/vet --no�� h ../../../.pret.prettierignore grep 64/pkg/tool/linux_amd64/vet GitHubMCPRemoteOnode flow (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Generate a distinct GH_AW_WRITE_SINK_API_KEY for the safe-outputs
write-sink MCP server endpoint, separate from the shared
MCP_GATEWAY_API_KEY. This scopes the safeoutputs gateway endpoint
to a per-server token so that possessing the gateway key alone no
longer grants access to write-sink operations.

Changes:
- mcp_setup_generator.go: generate + mask GH_AW_WRITE_SINK_API_KEY
  alongside MCP_GATEWAY_API_KEY when safe-outputs is enabled; pass it
  to the gateway container via -e GH_AW_WRITE_SINK_API_KEY
- mcp_config_builtin.go: add clientApiKey field to the safeoutputs
  server config in the gateway input, pointing to
  GH_AW_WRITE_SINK_API_KEY (MCP Gateway Spec §7.7)
- awf_helpers.go: exclude GH_AW_WRITE_SINK_API_KEY from the agent
  container environment via --exclude-env (agent accesses it only
  through the gateway-written mcp-config.json)
- mcp-gateway.md: add clientApiKey field to §4.1.2 server config,
  add §7.7 Per-Server Client API Keys, update config structure
  example, add version 2.0.0 changelog entry
- mcp_api_key_masking_test.go: add three new tests verifying key
  generation/masking, non-generation without safe-outputs, and
  clientApiKey presence in the safeoutputs server config

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/cfc03dc8-400c-4525-bfad-04346a02b4b0

Co-authored-by: szabta89 <1330202+szabta89@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix scoped bearer token for safe-outputs write-sink MCP security: scope safe-outputs write-sink to a distinct bearer token Apr 1, 2026
Copilot AI requested a review from szabta89 April 1, 2026 17:07
@pelikhan pelikhan added the smoke label Apr 2, 2026
@pelikhan pelikhan closed this Apr 2, 2026
@github-actions github-actions Bot deleted the copilot/fix-scope-bearer-token-issue branch April 9, 2026 02:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Safe-outputs write-sink MCP must use a distinct, scoped bearer token not shared with the read GitHub MCP

3 participants