Skip to content

Add cross-repo allowlist validation to close_entity_helpers (SEC-005)#25715

Merged
pelikhan merged 2 commits intomainfrom
copilot/sec-005-add-allowlist-validation
Apr 11, 2026
Merged

Add cross-repo allowlist validation to close_entity_helpers (SEC-005)#25715
pelikhan merged 2 commits intomainfrom
copilot/sec-005-add-allowlist-validation

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 10, 2026

close_entity_helpers.cjs references target repositories in its createCloseEntityHandler pipeline but never validates them against an allowlist, failing the SEC-005 conformance check.

Changes

  • Import validateTargetRepo and resolveTargetRepoConfig from repo_helpers.cjs
  • Parse target-repo / allowed_repos config at handler creation via resolveTargetRepoConfig()
  • Validate resolved owner/repo against the allowlist as step 4b, after callbacks.resolveTarget() and before any API calls:
// 4b. Cross-repository allowlist validation (SEC-005)
const resolvedRepo = `${owner}/${repoName}`;
const repoValidation = validateTargetRepo(resolvedRepo, defaultTargetRepo, allowedRepos);
if (!repoValidation.valid) {
  core.warning(`Skipping ${entityConfig.itemType}: cross-repo check failed for "${resolvedRepo}": ${repoValidation.error}`);
  return { success: false, error: repoValidation.error };
}
  • Tests for rejection of non-allowlisted cross-repo targets, same-repo passthrough, and explicit allowlist match

This reuses the same validateTargetRepo pattern established in dispatch_repository.cjs and other SEC-005-compliant handlers.

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-build327rev-parse .cfg git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git -bool l /opt/hostedtoolc--show-toplevel git (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 123287728/001' 123287728/001' -importcfg /tmp/go-build3274410599/b411/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 1.5.0/internal/jsonrpc2/conn.go 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 --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git 339741/b220/_pkggit SZyr/UNQkpBpW_Ivrev-parse x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git 339741/b083/imponode -Eee/499QsILxkBj/opt/hostedtoolcache/node/24.14.1/x64/bin/npm .cfg 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 /tmp/gh-aw-test-runs/20260410-232448-37646/test-2383275090/.github/workflows config /tmp/go-build3274410599/b435/stringutil.test remote.origin.urgit GO111MODULE x_amd64/vet /tmp/go-build3274410599/b435/stringutil.test -tes�� -test.paniconexit0 -test.v=true ache/node/24.14.1/x64/bin/node -test.timeout=10git -test.run=^Test -test.short=true--show-toplevel node (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 g_.a 4410599/b134/vet.cfg .cfg -I erutil -I ache/go/1.25.8/x^remote\..*\.gh-resolved$ (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel ache/go/1.25.8/x64/pkg/tool/linutest@example.com /usr/bin/git report.md -trimpath .cfg ROOT" ] && expo rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linuTest User /usr/bin/git /tmp/go-build412git -trimpath 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel git /usr/bin/git /tmp/gh-aw-test-git t om/owner/repo.gi--show-toplevel git rev-�� --show-toplevel git /usr/bin/git p/TestGetNpmBinPgit remote.origin.urrev-parse /usr/bin/git 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 --show-toplevel 64/pkg/tool/linuremote /usr/bin/git LsRemoteWithRealgit LsRemoteWithRealrev-parse 64/pkg/tool/linu--show-toplevel /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git md .cfg 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 --show-toplevel 64/pkg/tool/linu-trimpath /usr/bin/docker 339741/b059/_pkggit .cfg 64/pkg/tool/linu--show-toplevel docker pull�� test/race-image:v1.0.0 64/pkg/tool/linuother /usr/bin/docker ut1982376229/001git .cfg 64/pkg/tool/linu--show-toplevel docker (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel x_amd64/compile /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel x_amd64/compile mple.com/org/rep--show-toplevel 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 -json GO111MODULE x_amd64/asm GOINSECURE GOMOD GOMODCACHE x_amd64/asm env -json GO111MODULE 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 -json gset/set.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 -json nal.go x_amd64/compile GOINSECURE GOMOD bytealg/compare_HEAD:.github/workflows/test.lock.yml 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 --show-toplevel x_amd64/compile /usr/bin/git rtcfg .cfg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linuupstream /usr/bin/git 339741/b112/_pkggit .cfg 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 /home/REDACTED/work/gh-aw/gh-aw/.github/workflows/approach-validator.md 64/pkg/tool/linu-buildtags /usr/bin/infocmp rtcfg .cfg 64/pkg/tool/linu--show-toplevel infocmp -1 xterm-color 64/pkg/tool/linuremote.origin.url /usr/bin/git y_with_repos_arrgit .cfg 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 4410599/b438/_pkg_.a --format=%(objectname) 1/x64/bin/node -json GO111MODULE x_amd64/asm 1/x64/bin/node -C XdPK/4_gG8mNLC_w4L8SzXdPK rev-parse /usr/bin/git -json GO111MODULE x_amd64/compile 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 --git-dir 64/pkg/tool/linux_amd64/vet /usr/bin/git ba-vTFQEj .cfg 64/pkg/tool/linu--show-toplevel /usr/bin/git remo�� -v 64/pkg/tool/linux_amd64/vet /usr/bin/git 2149141275/.githgit .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 sistency_GoAndJavaScript3500912663/001/test-inlined-imports-enabled-with-body-content.md --format=%(objectname) epo.git -c=4 -nolocalimports -importcfg git rev-�� --show-toplevel cB-MrgPZhxrn /usr/bin/git -json GO111MODULE x_amd64/compile 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 --pack_header=2,3 -q /usr/bin/git cli/install.sh..git GO111MODULE x_amd64/compile git -C /tmp/TestGuardPolicyBlockedUsersApprovalLabelsCov1.0.0 remote /usr/bin/git -json 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 om/modelcontextp-ifaceassert 64/pkg/tool/linu-nilfunc GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu-tests env 3574567048 gNV_/-ERQMY_tDmUJytyNgNV_ ck GOINSECURE contextprotocol//tmp/js-hash-test-715757440/test-hash.js GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (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/nistec/frev-parse ache/go/1.25.8/x--git-dir 64/pkg/tool/linux_amd64/vet env 339741/b246/_pkg_.a .cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/message/catalorev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-trimpath (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 (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE randutil GOMODCACHE 64/pkg/tool/linux_amd64/vet env 339741/b220/_pkg_.a SZyr/UNQkpBpW_IvLZuHOSZyr x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (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 x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env 339741/b178/_pkg_.a d2UJ/DbmGN00V4XBV3gqgd2UJ x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE 339741/b092/ GOMODCACHE 64/pkg/tool/linux_amd64/vet env 339741/b222/_pkg_.a GO111MODULE .cfg GOINSECURE g/x/net/http2/hprev-parse 339741/b092/syma--show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (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 om/modelcontextp-c=4 64/pkg/tool/linu-nolocalimports GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/tmp/go-build3274410599/b444/_testmain.go env 3574567048 oYmy/n_pwg_VDfKQLamLkoYmy 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/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 339741/b012/equainit ache/go/1.25.8/x-pack 64/pkg/tool/linu/tmp/go-build3274410599/b449/_testmain.go env 339741/b248/_pkg_.a BHdz/-6z_QJDvZKLbBouUBHdz ger.test GOINSECURE t/internal/formarev-parse GOMODCACHE ger.test (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 om/modelcontextprotocol/go-sdk@v1.5.0/internal/x-ifaceassert 64/pkg/tool/linux_amd64/vet GOINSECURE l/buffer GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3574567048 pRaw/gwkwek_UF5vdtNyzpRaw .cfg GOINSECURE g/x/net/idna GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE sysrand ache/go/1.25.8/xuser.name 64/pkg/tool/linuTest User env 339741/b238/_pkg_.a REzZ/UVSmm-gThuyfG0BeREzZ ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/feature/pluralrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-importcfg (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 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuTest User env 3574567048 3zY_/HcUWNrRjpCKdAR9m3zY_ x_amd64/compile GOINSECURE a95/uritemplate/rev-parse GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 .cfg 64/pkg/tool/linu-importcfg GOINSECURE GOMOD 339741/b007/syma/home/REDACTED/work/gh-aw/gh-aw/pkg/typeutil/convert.go 64/pkg/tool/linu/home/REDACTED/work/gh-aw/gh-aw/pkg/typeutil/convert_test.go env 339741/b254/_pkg_.a fWCy/na03iXLzDBM34i--fWCy 64/pkg/tool/linux_amd64/vet GOINSECURE /semver GOMODCACHE 64/pkg/tool/linux_amd64/vet (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/linu-importcfg GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com env 339741/b232/_pkg_.a taK6/ikh7gQ1RReQdq87ptaK6 ache/go/1.25.8/x64/pkg/tool/linu-nilfunc GOINSECURE contextprotocol/rev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-trimpath (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE fips140hash 339741/b015/syma--show-toplevel 64/pkg/tool/linux_amd64/vet env 339741/b244/_pkg_.a _cnJ/4Be12s2Y-OeyZeOx_cnJ ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/internal/numberev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path -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)
    • 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 bfee668ea3df50ba4 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 339741/b006/ GOMODCACHE 64/pkg/tool/linuremote2 env 339741/b184/_pkg_.a GO111MODULE util.test GOINSECURE GOMOD 339741/b006/symabis util.test (http block)
  • https://api.github.com/repos/github/gh-aw/contents/.github%2Fworkflows%2Faudit-workflows.md
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --experimental-import-meta-resolve --require /home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/vitest/suppress-warnings.cjs --conditions node --conditions development /home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/vitest/dist/workers/forks.js . 86_64/git forks.js rev-�� --reverse origin/fallback-branch..HEAD t -m Initial commit ndor/bin/git /usr/lib/git-cor--stdout (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.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git 4016675352 -trimpath /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linuremote.origin.url /usr/bin/git /v2.0.0 /tmp/go-build327rev-parse 1/x64/bin/node 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 b/workflows llzq/kleu3xr21GcpMTTxllzq x_amd64/vet GOINSECURE contextprotocol/rev-parse GOMODCACHE x_amd64/vet (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 -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/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env Gitmaster_branch601570199/001' Gitmaster_branch601570199/001' 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 -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 -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/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 b/workflows GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuremote.origin.url estl�� se 4410599/b010/vet.cfg x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link (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 /go-yaml/ast ache/go/1.25.8/x--show-toplevel 64/pkg/tool/linux_amd64/vet env fq9m/dOvw0liy9-ZbDdQ2fq9m GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (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 ag.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • 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 gset/set.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build3274410599/b397/cli.test /tmp/go-build3274410599/b397/cli.test -test.testlogfile=/tmp/go-build3274410599/b397/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (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)
  • 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 comm�� -m Initial commit bin/git ranch main odules/npm/node_-b git conf�� user.email test@test.com /git -b feature-branch git git (dns block)

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

Copilot AI changed the title [WIP] Add allowlist validation for cross-repository operations Add cross-repo allowlist validation to close_entity_helpers (SEC-005) Apr 10, 2026
Copilot AI requested a review from pelikhan April 10, 2026 23:38
@pelikhan pelikhan marked this pull request as ready for review April 10, 2026 23:43
Copilot AI review requested due to automatic review settings April 10, 2026 23:43
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

Adds SEC-005 cross-repository allowlist enforcement to the shared createCloseEntityHandler pipeline so that resolved owner/repo targets are validated before any GitHub API interactions, with accompanying unit tests to cover allow/deny behavior.

Changes:

  • Import and use resolveTargetRepoConfig() to parse target-repo / allowed_repos once at handler creation.
  • Add a new validation step (4b) using validateTargetRepo() to block non-allowlisted cross-repo targets before API calls.
  • Add tests covering rejection of non-allowlisted cross-repo targets, same-repo passthrough, and explicit allowlist match.
Show a summary per file
File Description
actions/setup/js/close_entity_helpers.cjs Adds SEC-005 cross-repo allowlist validation into createCloseEntityHandler prior to API calls.
actions/setup/js/close_entity_helpers.test.cjs Adds unit tests validating new cross-repo allowlist behavior for the handler factory.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

@github-actions github-actions bot mentioned this pull request Apr 10, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 70/100

⚠️ Acceptable, with suggestions

Metric Value
New/modified tests analyzed 3
✅ Design tests (behavioral contracts) 3 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 1 (33%)
Duplicate test clusters 0
Test inflation detected ✅ YES — 5:1 ratio (50 test lines / 10 production lines)
🚨 Coding-guideline violations None

Test Classification Details

Test File Classification Issues Detected
should reject cross-repo target not in allowlist actions/setup/js/close_entity_helpers.test.cjs ✅ Design Covers the rejection/error path; asserts result.error content + mockCore.warning
should allow same-repo target actions/setup/js/close_entity_helpers.test.cjs ✅ Design Happy-path only; only asserts result.success === true
should allow cross-repo target when in allowlist actions/setup/js/close_entity_helpers.test.cjs ✅ Design Happy-path only; only asserts result.success === true

Flagged Tests — Requires Review

⚠️ Test inflation — close_entity_helpers.test.cjs

Issue: The test file grew 5× faster than the production file (50 new test lines vs 10 new production lines), exceeding the 2:1 threshold.
Context: The production change in close_entity_helpers.cjs is a thin integration wrapper; the core validation logic lives in repo_helpers.cjs. This is a reasonable split, and the extra test boilerplate (makeCallbacks helper) is reused across all three cases. The flag is noted but is not a concern given the architectural context.
Suggested action: No change needed — the inflation is structural, not indicative of padding.


⚠️ should allow same-repo target — shallow behavioral assertion

Classification: Design test
Issue: Only asserts result.success === true. It doesn't verify that closeEntity was called (i.e., the entity was actually processed), which would confirm the handler didn't silently short-circuit.
What design invariant does this test enforce? That the same-repo case is not rejected by the cross-repo guard.
What would break if deleted? A regression allowing same-repo cases to be incorrectly rejected would go undetected.
Suggested improvement: Consider adding expect(makeCallbacks(...).closeEntity).toHaveBeenCalled() (or assert on callback invocation) to verify the full flow ran, not just that it didn't return { success: false }.


⚠️ should allow cross-repo target when in allowlist — shallow behavioral assertion

Classification: Design test
Issue: Only asserts result.success === true. The allowlist feature's key behavioral promise is that an explicitly permitted cross-repo target proceeds to actual entity processing.
What design invariant does this test enforce? That allowlisted repos are permitted through the security gate.
What would break if deleted? A bug that ignores the allowed_repos field would not be caught.
Suggested improvement: Same as above — add an assertion that closeEntity (or another callback) was invoked, confirming the allowlisted repo proceeded to actual processing.


i️ Missing edge case: allowed_repos present but target not in it

Issue: There is no test for the scenario where allowed_repos is explicitly configured but the resolved target does not match any entry. This is a distinct code path from "no allowlist at all" (Test 1).
Impact: If validateTargetRepo has its own tests in repo_helpers.test.cjs, this gap is less critical. But the integration path in createCloseEntityHandler is untested for this case.
Suggested addition:

it("should reject cross-repo target not matching allowlist entries", async () => {
  const config = { "target-repo": "testowner/testrepo", allowed_repos: ["other-org/approved-repo"], comment: "closing" };
  const handler = createCloseEntityHandler(
    config,
    ISSUE_CONFIG,
    makeCallbacks(() => ({ success: true, entityNumber: 1, owner: "other-org", repo: "unapproved-repo" })),
    {}
  );
  const result = await handler({ body: "test", type: "close_issue" });
  expect(result.success).toBe(false);
  expect(result.error).toContain("not in the allowed-repos list");
});

Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 0 tests — no Go test files modified
  • 🟨 JavaScript (*.test.cjs): 3 tests (vitest)

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). All 3 new tests verify observable behavioral contracts of the SEC-005 cross-repo allowlist feature. Score is reduced from the maximum due to shallow assertions in the two happy-path tests and the test inflation ratio.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

🧪 Test quality analysis by Test Quality Sentinel · ● 395K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 70/100. Test quality is acceptable — 0% of new tests are implementation tests (threshold: 30%). All 3 new vitest tests cover behavioral contracts of the SEC-005 cross-repo allowlist feature. Minor suggestions posted in the comment above (shallow happy-path assertions, one missing edge case).

@pelikhan pelikhan merged commit 6d651e2 into main Apr 11, 2026
189 checks passed
@pelikhan pelikhan deleted the copilot/sec-005-add-allowlist-validation branch April 11, 2026 00:54
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.

[Safe Outputs Conformance] SEC-005: close_entity_helpers.cjs supports target-repo but lacks cross-repository allowlist validation

3 participants