Skip to content

docs: document Claude bypassPermissions/--allowed-tools security boundary#28174

Merged
pelikhan merged 2 commits intomainfrom
copilot/deep-report-document-bypasspermissions-allowed-too
Apr 24, 2026
Merged

docs: document Claude bypassPermissions/--allowed-tools security boundary#28174
pelikhan merged 2 commits intomainfrom
copilot/deep-report-document-bypasspermissions-allowed-too

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 23, 2026

Claude Code silently ignores --allowed-tools when running in --permission-mode bypassPermissions (triggered by unrestricted bash: bash: "*", bash: [":*"], or bash: null). The MCP gateway's allowed: filter is the sole effective tool boundary in that mode — but this was undocumented, leaving workflow authors with a false sense of security from their tool allowlists.

Changes

  • AGENTS.md — New "Claude Engine Tool Enforcement Security Model" section for contributors: explains the acceptEdits/bypassPermissions mode split, which functions control the selection (hasBashWildcardInTools, computeAllowedClaudeToolsString, convert_gateway_config_claude.sh), and why neither enforcement layer should be weakened.

  • docs/reference/engines.md — New "Claude Tool Enforcement Security Model" section documenting both permission modes, a [!WARNING] callout against relying on tool allowlists when unrestricted bash is granted, gateway-side enforcement as the sole boundary in bypassPermissions mode, and a summary table:

    Workflow config Permission mode --allowed-tools enforced? Gateway allowed: enforced?
    No unrestricted bash acceptEdits ✅ Yes ✅ Yes
    bash: "*" / bash: [":*"] / bash: null bypassPermissions ❌ No ✅ Yes
  • docs/guides/mcps.md — Added gateway-level enforcement note to "MCP Tool Filtering" with an [!IMPORTANT] callout for Claude workflows using unrestricted bash and a cross-reference to the new security model section.

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 gh repo view --json owner,name --jq .owner.login + "/" + .name 64/pkg/tool/linux_amd64/compile GOINSECURE ntio/encoding/jsconfig ache/go/1.25.8/xuser.email 64/pkg/tool/linutest@example.com (http block)
    • Triggering command: /usr/bin/gh gh repo view owner/repo env 4131872055 wDwi/8TvZlM4P0nfuVfRvwDwi 64/pkg/tool/linux_amd64/link GOINSECURE l/ascii GOMODCACHE 64/pkg/tool/linux_amd64/link -c ger.test -ZkR/Y5KUpR6ZrQZn8hJV-ZkR ortcfg.link -n1 b/gh-aw/pkg/acti/tmp/test-import-3211997244.js --end-of-options 9Ym34G_sfJyM6o-Ioz/mT-tLcfK0hMgk-tests (http block)
    • Triggering command: /usr/bin/gh gh repo view owner/repo env 4131872055 aMu6/n6X7R7Av3bGkLZAPaMu6 util.test GOINSECURE contextprotocol/rev-parse GOMODCACHE util.test 4992�� 9296529/b395/_pkg_.a GOPROXY .cfg GOSUMDB GOWORK 64/bin/go ache/go/1.25.8/x64/pkg/tool/linu-buildtags (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 -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (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, .object.type] | @tsv xterm-color 71/KDaUrle63TPPPremote.origin.url /usr/bin/git y_with_explicit_git .cfg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git 2082431/b002/_pknode .cfg ache/go/1.25.8/xinstall 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, .object.type] | @tsv GOMODCACHE x_amd64/compile /opt/hostedtoolcache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/vet node /tmp�� /tmp/TestHashConsistency_GoAndJavaScript2181841935/001/test-inlined-imports-enabled-with-env-temgit x_amd64/vet /usr/bin/git -json GO111MODULE 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, .object.type] | @tsv 7831/001/stability-test.md -trimpath ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -p internal/oserrordiff -lang=go1.25 ache/go/1.25.8/x--name-only -o 3066911659 -trimpath ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile -p vendor/golang.orrev-parse -lang=go1.25 ache/go/1.25.8/x64/pkg/tool/linutest@example.com (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel 64/pkg/tool/linux_amd64/compile /usr/bin/git g_.a 9296529/b055/vet\n ache/go/1.25.8/x: git rev-�� --show-toplevel ache/go/1.25.8/x2 /usr/bin/git or.md 9296529/b238/vetrev-parse ache/go/1.25.8/x--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel /bin/sh /usr/bin/git git-upload-pack 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, .object.type] | @tsv ithub/workflows/archie.md x_amd64/asm /usr/bin/git -json n/codec.go x_amd64/compile git -C /tmp/gh-aw-test-runs/20260423-220410-35045/test--s l /usr/bin/git remote.origin.urgit GO111MODULE x_amd64/vet 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, .object.type] | @tsv --show-toplevel x_amd64/compile /usr/bin/git se 9296529/b318/vetcommit 9296529/b185/vet-m git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linuorigin /usr/bin/git /v3.0.0 /tmp/go-build249rev-parse sv git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json 8601/parse.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json ag.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json g/catmsg.go x_amd64/compile GOINSECURE GOMOD bytealg/indexbyt--show-toplevel x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (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, .object.type] | @tsv --show-toplevel x_amd64/link /usr/bin/gh ortcfg .cfg 64/pkg/tool/linu--show-toplevel gh run list --json /usr/bin/git --workflow nonexistent-workrev-parse --limit 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, .object.type] | @tsv /tmp/TestGuardPolicyMinIntegrityOnlymin-integrity_only_defaults_repo3734894949/001 remote /usr/bin/gh -json GO111MODULE x_amd64/compile gh api /repos/actions/github-script/git/ref/tags/v9 --jq ache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/vet git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel F6buppr/4AZU-IsIremote.origin.url /opt/hostedtoolcache/node/24.14.1/x64/bin/node aw.test 0kiaYELPw 64/pkg/tool/linu--show-toplevel /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� Value: ${{ github.actor }} 64/pkg/tool/linu--auto /usr/bin/git ortcfg GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel x_amd64/asm /usr/bin/infocmp -json GO111MODULE x_amd64/compile infocmp -1 xterm-color x_amd64/compile 9296529/b461/vet.cfg -json r/common.go x_amd64/compile /tmp/go-build2499296529/b441/sliceutil.test (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, .object.type] | @tsv 60e22676ae2f6237ed12748f ings.cjs git -m Auth cleanup fai-V=full modules/@npmcli/run-script/lib/nfeature | cat /etc/passwd forks.js k/gh�� -u st/suppress-warnings.cjs ache/node/24.14.1/x64/bin/node e/git t t st/dist/workers//home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/vitest/suppress-warnings.cjs (http block)
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv c93036ed..HEAD git $name) { hasDiscussionsEnabled } } user.name Test User /opt/hostedtoolc-m git show�� --verify c93036ed..HEAD ode_modules/.bin/git --bare commit _modules/.bin/gi/home/REDACTED/work/gh-aw/gh-aw/.github/workflows git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv c93036ed..HEAD git p/bin/git user.name Test User ules/.bin/git git show�� --verify c93036ed..HEAD n-dir/node --bare gin/token-optionapi .git git (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, .object.type] | @tsv --get remote.origin.url /usr/bin/infocmp ortcfg CLJOlIPxV 64/pkg/tool/linu--show-toplevel infocmp -1 xterm-color XFDo5AA/4Ab4WdaLtest@example.com /usr/bin/git ortcfg .cfg 64/pkg/tool/linu--show-toplevel 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, .object.type] | @tsv ons-test1605944752 remote /usr/bin/git h2258916453/001'git h2258916453/001'rev-parse x_amd64/compile git -C /tmp/gh-aw-test-runs/20260423-220410-35045/test-4131872055 l /usr/bin/git -json GO111MODULE x_amd64/link git (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, .object.type] | @tsv ons-test1605944752 rev-parse /usr/bin/git go1.25.8 -c=4 -nolocalimports git -C /tmp/gh-aw-test-runs/20260423-220410-35045/test-4131872055 rev-parse /usr/bin/git 01 GO111MODULE x_amd64/compile git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 2082431/b241/_pkg_.a GO111MODULE ache/go/1.25.8/x64/pkg/tool/linu-buildmode=exe GOINSECURE t/internal/langurev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-extld=gcc (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE fips140/aes/gcm GOMODCACHE 64/pkg/tool/linux_amd64/vet env 2082431/b237/_pkg_.a ho52/RILG8Ja3npv64jHUho52 ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/message GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-importcfg (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 2082431/b218/_pkg_.a 3cxW/IBlaqeSprCJhOYFQ3cxW .cfg GOINSECURE g/x/text/unicoderev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 om/modelcontextprotocol/go-sdk@v1.5.0/internal/m-ifaceassert 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 4131872055 aMu6/n6X7R7Av3bGkLZAPaMu6 util.test GOINSECURE contextprotocol/rev-parse GOMODCACHE util.test (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE fips140 GOMODCACHE 64/pkg/tool/linu/tmp/go-build2499296529/b113/vet.cfg env 2082431/b178/_pkg_.a i2Jk/kxQktkbJrdZm0O72i2Jk .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/pkg/tool/linu-nolocalimports GOINSECURE fips140/check GOMODCACHE 64/pkg/tool/linu/tmp/go-build2499296529/b112/vet.cfg env 4131872055 wDwi/8TvZlM4P0nfuVfRvwDwi 64/pkg/tool/linux_amd64/link GOINSECURE l/ascii GOMODCACHE 64/pkg/tool/linux_amd64/link (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name rg/x/text@v0.36.0/internal/langu-c=4 64/pkg/tool/linux_amd64/vet GOINSECURE hlite 2082431/b007/sym--show-toplevel 64/pkg/tool/linux_amd64/vet env 2082431/b245/_pkg_.a _zAe/m6K4S-499xrKjIdi_zAe .cfg GOINSECURE t/internal/strinrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 .cfg 64/pkg/tool/linu-nolocalimports GOINSECURE /cpu 2082431/b029/sym--show-toplevel 64/pkg/tool/linu/tmp/go-build2499296529/b462/_testmain.go env 2082431/b225/_pkg_.a 2082431/b029/importcfg k GOINSECURE ce GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linu-test.short=true GOINSECURE GOMOD 2082431/b013/sym--show-toplevel 64/pkg/tool/linux_amd64/vet env 4140735190/.github/workflows r73k/ZR15bOYtzO_sNGC5r73k ache/go/1.25.8/x64/pkg/tool/linu-lang=go1.25 GOINSECURE b/gh-aw/pkg/giturev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-dwarf=false (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE fips140only 2082431/b029/sym--show-toplevel 64/pkg/tool/linux_amd64/vet env 2082431/b236/_pkg_.a wyMD/ZnqvKWWFy1YdeRMpwyMD ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE osh-tekuri/jsonsrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 4140735190/.github/workflows GO111MODULE ache/go/1.25.8/x64/pkg/tool/linu-buildmode=exe GOINSECURE g/x/net/http/httinit GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 .cfg 64/pkg/tool/linu-nolocalimports GOINSECURE fips140/bigmod ache/go/1.25.8/x--show-toplevel 64/pkg/tool/linu/tmp/go-build2499296529/b459/_testmain.go env 2797759290/.github/workflows til_test.go ck GOINSECURE t/internal/catmsrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-tests (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 4140735190/.github/workflows 7Ps3/Xuna8G_bMUX3GMM57Ps3 ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE g/x/net/http/httrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linurev-parse (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE 2082431/b021/atorev-parse ache/go/1.25.8/x--show-toplevel Vgol9MA/jtMHmSR1PwQ4sKWnT8ry env 2082431/b235/_pkg_.a .cfg 64/pkg/tool/linux_amd64/compile GOINSECURE osh-tekuri/jsonsrev-parse GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path -c=4 -nolocalimports -importcfg /tmp/go-build2499296529/b419/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/fileutil/fileutil.go /home/REDACTED/work/gh-aw/gh-aw/pkg/fileutil/tar.go env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD cpu/cpu.s x_amd64/compile (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 GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_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 6 GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env b/workflows .cfg 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/link (http block)
  • https://api.github.com/repos/github/gh-aw/contents/.github/workflows/shared/reporting.md
    • Triggering command: /tmp/go-build2499296529/b404/cli.test /tmp/go-build2499296529/b404/cli.test -test.testlogfile=/tmp/go-build2499296529/b404/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (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, .object.type] | @tsv --show-toplevel ache/go/1.25.8/x64/pkg/tool/linuTest User /usr/bin/git 0410-35045/test-git 9296529/b204/vetrev-parse ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git /tmp/go-build307ls -trimpath (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, .object.type] | @tsv se 9296529/b007/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (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, .object.type] | @tsv adata/main.go GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE SLlQ1ZG/V_z3kiodtest@example.com (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, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env g_.a GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (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, .object.type] | @tsv bytealg/indexbyte_wasm.s GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env Gitmain_branch2965613694/001' Gitmain_branch2965613694/001' x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (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, .object.type] | @tsv g_.a 9296529/b006/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE ole 2082431/b133/sym--show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -o oMM2kMrQi 2082431/b133/importcfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -p github.com/githu-1 -lang=go1.25 ortcfg (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 GOINSECURE 2082431/b047/florev-parse ache/go/1.25.8/x--show-toplevel 64/pkg/tool/linux_amd64/compile (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 x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh workflow list --repo owner/repo --json name,path,state ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-buildtags buil�� t112341908/.github/workflows -Eee/499QsILxkBjFfa_H-Eee .cfg ./cmd/gh-aw-wasminfocmp GOWORK 64/bin/go ache/go/1.25.8/x64/pkg/tool/linu-tests (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 -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
  • https://api.github.com/repos/test/repo
    • Triggering command: /usr/bin/gh gh api /repos/test/repo --jq .default_branch 2082431/b235/_pkg_.a .cfg 64/pkg/tool/linux_amd64/compile GOINSECURE osh-tekuri/jsonsrev-parse GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
  • invalid.example.invalid
    • Triggering command: /usr/lib/git-core/git-remote-https /usr/lib/git-core/git-remote-https origin https://invalid.example.invalid/nonexistent-repo.git git conf�� --local --get ode_modules/.bin/git /home/REDACTED/.lo/usr/lib/git-core/git git /git git add . git tions/setup/node_modules/.bin/git -M main bin/git git (dns block)

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

…for Claude engine

Add explicit documentation explaining that --allowed-tools has no enforcement
effect in bypassPermissions mode (unrestricted bash), and that the MCP gateway
allowed: filter is the sole effective tool boundary in that case.

- AGENTS.md: Add Claude Engine Tool Enforcement Security Model section
- docs/reference/engines.md: Add Claude Tool Enforcement Security Model section
- docs/guides/mcps.md: Add gateway-side enforcement note for MCP tool filtering
- Add changeset for documentation update

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/17ba2d42-4fed-4f67-91ee-88e9c871e902

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Document bypassPermissions and --allowed-tools security boundary and add enforcement docs: document Claude bypassPermissions/--allowed-tools security boundary Apr 23, 2026
Copilot AI requested a review from pelikhan April 23, 2026 22:10
@github-actions github-actions Bot mentioned this pull request Apr 23, 2026
@github-actions

This comment has been minimized.

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

Hey @Copilot 👋 — great work documenting the Claude bypassPermissions / --allowed-tools security boundary! This fills a real gap for workflow authors who might otherwise have a false sense of security from their tool allowlists.

One minor note for completeness:

  • No test files changed — this is a docs-only PR so it's entirely expected, but the checklist technically flags it. No action needed unless there's a doc-test or link-checker suite that should be validated.

Overall this PR looks well-scoped, clearly described, and ready for maintainer review. 🚀

Generated by Contribution Check · ● 1.6M ·

@pelikhan pelikhan marked this pull request as ready for review April 24, 2026 02:14
Copilot AI review requested due to automatic review settings April 24, 2026 02:14
@pelikhan pelikhan merged commit b93ebc3 into main Apr 24, 2026
14 checks passed
@pelikhan pelikhan deleted the copilot/deep-report-document-bypasspermissions-allowed-too branch April 24, 2026 02:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Documents the security boundary for Claude workflows when --permission-mode bypassPermissions is selected, clarifying that --allowed-tools is not enforced in that mode and that gateway-side allowed: filtering remains the effective MCP tool boundary.

Changes:

  • Added a “Claude Tool Enforcement Security Model” section to the engines reference, including warnings and a summary table.
  • Updated the MCP guide to emphasize gateway-level allowed: enforcement and cross-reference the engines security model section.
  • Added contributor-facing guidance in AGENTS.md and a patch changeset entry.
Show a summary per file
File Description
docs/src/content/docs/reference/engines.md Adds a detailed Claude permission-mode/tool-enforcement explanation, warning callout, and summary table.
docs/src/content/docs/guides/mcps.md Notes gateway-level enforcement for allowed: and adds a Claude-specific IMPORTANT callout with a link to the engines reference.
AGENTS.md Adds contributor guidance on Claude permission modes and which parts of the codebase influence tool boundaries.
.changeset/patch-document-bypasspermissions-security-boundary.md Adds a patch changeset describing the documentation update.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/4 changed files
  • Comments generated: 6

Comment thread AGENTS.md
**Implication for code changes:**
- `hasBashWildcardInTools()` in `claude_tools.go` determines which mode is selected — changes here affect the security boundary
- `computeAllowedClaudeToolsString()` builds the `--allowed-tools` string — only effective in `acceptEdits` mode
- `convert_gateway_config_claude.sh` preserves the `tools` field from gateway output — this is what enforces restrictions in `bypassPermissions` mode
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The converter referenced here appears to be outdated/misnamed: the workflow gateway conversion for Claude is implemented in actions/setup/js/convert_gateway_config_claude.cjs (and invoked by actions/setup/sh/start_mcp_gateway.sh), not convert_gateway_config_claude.sh. Consider updating this bullet to point at the .cjs converter (or explicitly mention both, if both are still supported), so contributors look at the code path that actually runs in CI.

Suggested change
- `convert_gateway_config_claude.sh` preserves the `tools` field from gateway output — this is what enforces restrictions in `bypassPermissions` mode
- `actions/setup/js/convert_gateway_config_claude.cjs` (invoked by `actions/setup/sh/start_mcp_gateway.sh`) preserves the `tools` field from gateway output — this is what enforces restrictions in `bypassPermissions` mode

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md

1. **`acceptEdits` (default)** — Claude Code honors `--allowed-tools` as the effective tool boundary. Workflow `tools:` and `mcp-servers: allowed:` restrictions are enforced client-side.

2. **`bypassPermissions`** — Claude Code silently ignores `--allowed-tools`. Every tool exposed by the MCP gateway is reachable regardless of the workflow's declared tool configuration. This mode is only used when the workflow grants unrestricted bash access (e.g., `bash: "*"`, `bash: [":*"]`, or `bash: null`).
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list of unrestricted bash examples should include bash: true (documented elsewhere as equivalent to allowing all bash commands). As written, it suggests bash: true would not trigger bypassPermissions, which conflicts with the documented bash formats and the runtime behavior described in hasBashWildcardInTools.

Suggested change
2. **`bypassPermissions`** — Claude Code silently ignores `--allowed-tools`. Every tool exposed by the MCP gateway is reachable regardless of the workflow's declared tool configuration. This mode is only used when the workflow grants unrestricted bash access (e.g., `bash: "*"`, `bash: [":*"]`, or `bash: null`).
2. **`bypassPermissions`** — Claude Code silently ignores `--allowed-tools`. Every tool exposed by the MCP gateway is reachable regardless of the workflow's declared tool configuration. This mode is only used when the workflow grants unrestricted bash access (e.g., `bash: true`, `bash: "*"`, `bash: [":*"]`, or `bash: null`).

Copilot uses AI. Check for mistakes.
When the workflow grants unrestricted bash access — `bash: "*"`, `bash: [":*"]`, or `bash: null` — gh-aw switches to `--permission-mode bypassPermissions`. **In this mode, Claude Code silently ignores `--allowed-tools`.** Every tool exposed by the MCP gateway is reachable regardless of the workflow's declared tool configuration.

> [!WARNING]
> Do not rely on `tools:` or `mcp-servers: allowed:` for security guarantees when unrestricted bash is granted. In `bypassPermissions` mode, the agent can already run arbitrary shell commands, so `--allowed-tools` provides no meaningful additional boundary.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WARNING contradicts the rest of this new section: it says not to rely on mcp-servers: allowed: for security guarantees, but the following “Gateway-side enforcement” subsection states that the gateway allowed: filter is the sole effective tool boundary in bypassPermissions mode. Suggest rewriting the warning to specifically warn against relying on Claude-side tools:/--allowed-tools enforcement when unrestricted bash is granted, while clarifying that gateway allowed: remains the enforced boundary for MCP tools.

Suggested change
> Do not rely on `tools:` or `mcp-servers: allowed:` for security guarantees when unrestricted bash is granted. In `bypassPermissions` mode, the agent can already run arbitrary shell commands, so `--allowed-tools` provides no meaningful additional boundary.
> Do not rely on Claude-side `tools:` / `--allowed-tools` enforcement for security guarantees when unrestricted bash is granted. In `bypassPermissions` mode, the agent can already run arbitrary shell commands, so the Claude CLI allowlist provides no meaningful additional boundary. However, `mcp-servers: allowed:` remains enforced by the MCP gateway for MCP tools and is still the effective boundary there.

Copilot uses AI. Check for mistakes.
Comment on lines +350 to +353
### `bypassPermissions` mode (unrestricted bash)

When the workflow grants unrestricted bash access — `bash: "*"`, `bash: [":*"]`, or `bash: null` — gh-aw switches to `--permission-mode bypassPermissions`. **In this mode, Claude Code silently ignores `--allowed-tools`.** Every tool exposed by the MCP gateway is reachable regardless of the workflow's declared tool configuration.

Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list of “unrestricted bash” configurations is incomplete relative to the documented bash: formats elsewhere in the docs (e.g., bash: true is described as equivalent to ['*'] in docs/src/content/docs/reference/tools.md and frontmatter-full.md). Since bash: true also grants unrestricted bash, it should be included here (and in the summary table) as another case that triggers bypassPermissions.

Copilot uses AI. Check for mistakes.
The `allowed:` filter is enforced at the **MCP gateway level** — the gateway only exposes the listed tools to the agent. This enforcement applies regardless of which AI engine or permission mode is in use.

> [!IMPORTANT]
> For Claude workflows that grant unrestricted bash access (`bash: "*"` or `bash: [":*"]`), Claude runs in `bypassPermissions` mode and its `--allowed-tools` flag is silently ignored. In that case, the `allowed:` gateway filter is the **sole effective tool boundary**. Always specify `allowed:` on each `mcp-servers:` entry when tool restrictions matter. See [Claude Tool Enforcement Security Model](/gh-aw/reference/engines/#claude-tool-enforcement-security-model) for details.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This IMPORTANT callout enumerates unrestricted bash as only bash: "*" or bash: [":*"], but the docs also describe bash: true (and bash: null) as “allow all commands”. To avoid misleading workflow authors, please expand this list to include the other equivalent unrestricted forms (at least bash: true and bash: null), matching the engines reference section.

Suggested change
> For Claude workflows that grant unrestricted bash access (`bash: "*"` or `bash: [":*"]`), Claude runs in `bypassPermissions` mode and its `--allowed-tools` flag is silently ignored. In that case, the `allowed:` gateway filter is the **sole effective tool boundary**. Always specify `allowed:` on each `mcp-servers:` entry when tool restrictions matter. See [Claude Tool Enforcement Security Model](/gh-aw/reference/engines/#claude-tool-enforcement-security-model) for details.
> For Claude workflows that grant unrestricted bash access (`bash: "*"` or `bash: [":*"]`, as well as equivalent allow-all forms like `bash: true` and `bash: null`), Claude runs in `bypassPermissions` mode and its `--allowed-tools` flag is silently ignored. In that case, the `allowed:` gateway filter is the **sole effective tool boundary**. Always specify `allowed:` on each `mcp-servers:` entry when tool restrictions matter. See [Claude Tool Enforcement Security Model](/gh-aw/reference/engines/#claude-tool-enforcement-security-model) for details.

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md

**Two permission modes are used at runtime:**

1. **`acceptEdits` (default)** — Claude Code honors `--allowed-tools` as the effective tool boundary. Workflow `tools:` and `mcp-servers: allowed:` restrictions are enforced client-side.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In acceptEdits mode, --allowed-tools is enforced client-side by Claude, but mcp-servers: allowed: is enforced gateway-side (server-side), not client-side. The current wording implies both tools: and mcp-servers: allowed: are client-side restrictions, which is inaccurate and could confuse contributors making security-sensitive changes.

Suggested change
1. **`acceptEdits` (default)** — Claude Code honors `--allowed-tools` as the effective tool boundary. Workflow `tools:` and `mcp-servers: allowed:` restrictions are enforced client-side.
1. **`acceptEdits` (default)** — Claude Code honors `--allowed-tools` as the effective client-side tool boundary. Workflow `tools:` restrictions are reflected in that `--allowed-tools` setting, while `mcp-servers: allowed:` restrictions are enforced gateway-side by the MCP server configuration.

Copilot uses AI. Check for mistakes.
github-actions Bot added a commit that referenced this pull request Apr 24, 2026
Add acceptEdits and bypassPermissions mode terms introduced in
docs: document Claude bypassPermissions/--allowed-tools security
boundary (#28174).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[deep-report] Document bypassPermissions + --allowed-tools security boundary and add gateway-side enforcement

3 participants