Skip to content

feat: Allow ${{ needs.JOB.outputs.OUTPUT }} expressions in github-token fields#24215

Merged
pelikhan merged 4 commits intomainfrom
copilot/support-expression-based-safe-outputs
Apr 3, 2026
Merged

feat: Allow ${{ needs.JOB.outputs.OUTPUT }} expressions in github-token fields#24215
pelikhan merged 4 commits intomainfrom
copilot/support-expression-based-safe-outputs

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

The github-token schema only accepted ${{ secrets.NAME }} expressions, blocking short-lived tokens minted by upstream jobs (e.g. Octo STS, actions/create-github-app-token) from being used with built-in safe outputs.

Changes

  • pkg/parser/schemas/main_workflow_schema.json — Extends the github_token $def pattern to accept ${{ needs.JOB.outputs.OUTPUT }} in addition to the existing ${{ secrets.NAME }} / ${{ secrets.A || secrets.B }} forms
  • specs/security-architecture-spec.md — Updates OI-10, PM-13, PM-15 to reflect the expanded valid token formats
  • pkg/workflow/github_token_validation_test.go — Adds integration test cases for the new expression form across all four token validation test functions

Example — now compiles without error

jobs:
  auth:
    outputs:
      token: ${{ steps.octo-sts.outputs.token }}
    steps:
      - uses: McK-Internal/octo-sts-action@v1
        id: octo-sts
        with:
          scope: owner/repo
          identity: workflow-name

safe-outputs:
  github-token: ${{ needs.auth.outputs.token }}  # ← previously rejected
  create-issue:
    target-repo: owner/repo
    github-token: ${{ needs.auth.outputs.token }}  # ← and here

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 yAsi/qvt4s3DH3O9rev-parse ck git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linu-extld=gcc /usr/bin/git 19/001/test-inligit GOPROXY .cfg 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 -json GO111MODULE x_amd64/asm GOINSECURE GOMOD GOMODCACHE x_amd64/asm env -json go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name echo "��� Code fGOINSECURE git 64/bin/go --ignore-path ..node /bin/sh ache/node/24.14.--check go env ath ../../../.pr**/*.json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/McK-Internal/octo-sts-action/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/McK-Internal/octo-sts-action/git/ref/tags/v1 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/McK-Internal/octo-sts-action/git/ref/tags/v1 --jq .object.sha tHubToken (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 --git-dir x_amd64/vet /usr/bin/git ub/workflows @v1.1.3/ascii/asrev-parse x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/infocmp ions-build/main.git fMTeOyAsi 64/pkg/tool/linu--show-toplevel infocmp (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 -bool l /usr/bin/gh -errorsas -ifaceassert -nilfunc gh api /orgs/test-owner/actions/secrets --jq /usr/bin/git -json GO111MODULE x_amd64/asm 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 1189642/b162/_pkg_.a GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha GOMODCACHE 64/pkg/tool/linutest@example.com /usr/bin/git pjyIj9rjT .cfg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linutest@example.com /usr/bin/git 1189642/b110/_pkgit 64/src/net/addrsrev-parse 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 ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git /tmp/go-build146git -trimpath les.test git rev-�� --show-toplevel les.test /usr/bin/git t0 /tmp/go-build359rev-parse (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 -stringintconv -tests /usr/bin/git -json @v1.1.3/cpu/cpuirev-parse x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /opt/hostedtoolcache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/vet node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha /tmp/shared-actions-test274224729 config /usr/bin/git remote.origin.urgit GO111MODULE x_amd64/vet git rev-�� --git-dir x_amd64/vet /usr/bin/git -json GO111MODULE x_amd64/vet git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git 3584944316 8148173/b226/vetrev-parse ache/go/1.25.0/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git /tmp/go-build146git -trimpath 8148173/b417/log--show-toplevel 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 -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/v8 --jq .object.sha -json GO111MODULE 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/v8 --jq .object.sha -json n/codec.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE 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 ub.actor }} -extld=gcc /usr/bin/git -json GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE x_amd64/vet git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha OKEN }} GO111MODULE epo.git l GOMOD GOMODCACHE sh -c 3756-45438/test-4007452530 GOPROXY ache/node/24.14.1/x64/bin/node GOSUMDB GOWORK 64/bin/go node (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 --show-toplevel x_amd64/vet /usr/bin/git -json @v1.1.3/internalrev-parse x_amd64/vet git rev-�� --show-toplevel 5Rz_Fi7/cvl8_o9RIBhv1XvdZbOo /usr/bin/unpigz g_.a GO111MODULE x_amd64/vet /usr/bin/unpigz (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -json GO111MODULE 1/x64/bin/node GOINSECURE GOMOD GOMODCACHE sh t-ha�� ithub/workflows/blog-auditor.md GOPROXY 1/x64/bin/node l GOWORK 64/bin/go 1/x64/bin/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 --show-toplevel -goversion /usr/bin/git -c=4 -nolocalimports -importcfg git conf�� --get remote.origin.url /opt/hostedtoolcache/node/24.14.1/x64/bin/node -json ibility.go x_amd64/vet node (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 licyBlockedUsersApprovalLabelsCompiledOutput4170969995/001 /tmp/go-build3598148173/b232/vet.cfg 1/x64/bin/node l tions.go 64/bin/go ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile -has�� ithub/workflows/agent-persona-explorer.md -buildtags 1/x64/bin/node -errorsas b/gh-aw/pkg/slicrev-parse -nilfunc 1/x64/bin/node (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 -unreachable=false /tmp/go-build3598148173/b229/vet.cfg 8148173/b431/semverutil.test /tmp/go-build494git -trimpath 64/bin/go 8148173/b431/semverutil.test e=/t�� t0 -buildtags 1/x64/bin/node m0s -ifaceassert (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 VdHLw0zmJ 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env ortcfg GO111MODULE 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 1 --dir test-logs/run-1 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE bin/node GOINSECURE GOMOD GOMODCACHE go (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 YpQfbFkYb 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env ortcfg .cfg 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 12345 --dir test-logs/run-12345 GO111MODULE 64/bin/go lidation GOMOD GOMODCACHE go env LsRemoteWithRealGitbranch_with_hyphen2424597506/001' LsRemoteWithRealGitbranch_with_hyphen2424597506/001' ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 911_xIhzC 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env ortcfg GO111MODULE 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 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go itbr�� -json GO111MODULE tions/setup/js/node_modules/.bin/prettier GOINSECURE GOMOD GOMODCACHE go (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 QraydWafo 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env ortcfg GO111MODULE 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 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ode GOINSECURE GOMOD GOMODCACHE go (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 KQZakYfc4 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com env 3111827750/.github/workflows GO111MODULE 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 3 --dir test-logs/run-3 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 EePVvpLjG 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3111827750/.github/workflows GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE 1189642/b078/ GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go eWit�� -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3111827750/.github/workflows GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 1/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin/node GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path 367258522/001' 367258522/001' x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json cii.go 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/compile 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/linuremote.origin.url env ortcfg .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE b/gh-aw/pkg/type/tmp/js-hash-test-713865998/test-hash.js GOMODCACHE 64/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 64/pkg/tool/linu.github/workflows/test.md /usr/bin/git ty-test.md .cfg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git 1189642/b125/_pkgit .cfg 64/pkg/tool/linu--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 g_.a .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE vJGN38w/NUYLNsKqoXnbZM4oOc9d env b/workflows .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_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)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha re GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 5Rz_Fi7/cvl8_o9RIBhv1XvdZbOo (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 -json 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 -json GO111MODULE x_amd64/vet GOINSECURE GOMOD nts.s x_amd64/vet env -json 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 -json GO111MODULE x_amd64/vet GOINSECURE GOMOD reempt_wasm.s 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 MEyT6qO/ilPel1urx6TpxZ0rej1L (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha re GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 ty-test.md .cfg At,event,headBranch,headSha,displayTitle GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE 1189642/b129/ GOMODCACHE 64/pkg/tool/linux_amd64/vet (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 GOMOD GOMODCACHE 64/pkg/tool/linu/tmp/go-build3598148173/b440/_testmain.go env y_only_defaults_repo287384869/001 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 --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)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ath ../../../.pr--ignore-path GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build3598148173/b396/cli.test /tmp/go-build3598148173/b396/cli.test -test.testlogfile=/tmp/go-build3598148173/b396/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env gh-aw.wasm ./cmd/gh-aw-wasm GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /tmp/go-build1190760463/b396/cli.test /tmp/go-build1190760463/b396/cli.test -test.testlogfile=/tmp/go-build1190760463/b396/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true --show-toplevel /opt/hostedtoolc/opt/hostedtoolcache/node/24.14.1/x64/bin/npm /usr/bin/git go env -json GO111MODULE modules/@npmcli/run-script/lib/node-gyp-bin/node GOINSECURE GOMOD GOMODCACHE go (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 go1.25.0 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name --write ../../../**/*.jsGOMOD 64/bin/go --ignore-path ../../../.pretti/home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/.bin/pre�� /usr/bin/git go env ath ../../../.pr**/*.json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)

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

Relax the JSON schema validation for `github-token` fields to also
allow `${{ needs.JOB.outputs.OUTPUT }}` expressions in addition to
the existing `${{ secrets.NAME }}` pattern.

This enables secure short-lived credential flows (e.g. Octo STS or
actions/create-github-app-token) without requiring a custom
safe-outputs.jobs wrapper.

Updated files:
- pkg/parser/schemas/main_workflow_schema.json: extend github_token
  pattern to accept needs.*.outputs.* expressions
- specs/security-architecture-spec.md: update OI-10, PM-13, PM-15
  to mention job output expressions as valid token formats
- pkg/workflow/github_token_validation_test.go: add integration test
  cases for ${{ needs.auth.outputs.token }}

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/9fb17f81-0912-417c-914b-268bc1098fb3

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Support expression-based safe-outputs github-token from auth job outputs feat: Allow ${{ needs.JOB.outputs.OUTPUT }} expressions in github-token fields Apr 3, 2026
Copilot AI requested a review from pelikhan April 3, 2026 02:42
@pelikhan pelikhan marked this pull request as ready for review April 3, 2026 03:41
Copilot AI review requested due to automatic review settings April 3, 2026 03:41
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

Extends github-token validation to accept GitHub Actions needs.<job>.outputs.<output> expressions (in addition to secrets.*) so short-lived tokens minted by upstream jobs can be used in github-token fields.

Changes:

  • Updated the JSON schema pattern for github_token to allow needs.<job>.outputs.<output> expressions.
  • Updated the security architecture spec to reflect the expanded accepted token expression formats.
  • Added integration test cases covering the new token expression form across multiple validation locations.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
pkg/parser/schemas/main_workflow_schema.json Broadens the github_token regex to include needs.*.outputs.* expressions.
specs/security-architecture-spec.md Documents that github-token may reference secrets or job outputs.
pkg/workflow/github_token_validation_test.go Adds integration tests asserting needs.*.outputs.* is accepted in all github-token validation sites.

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

Comment on lines +9654 to +9655
"pattern": "^\\$\\{\\{\\s*(secrets\\.[A-Za-z_][A-Za-z0-9_]*(\\s*\\|\\|\\s*secrets\\.[A-Za-z_][A-Za-z0-9_]*)*|needs\\.[A-Za-z_][A-Za-z0-9_-]*\\.outputs\\.[A-Za-z_][A-Za-z0-9_-]*)\\s*\\}\\}$",
"description": "GitHub token expression. Accepts a secrets expression (e.g., `${{ secrets.NAME }}` or `${{ secrets.NAME1 || secrets.NAME2 }}`) or a job output expression (e.g., `${{ needs.auth.outputs.token }}`). Pattern details: secret names match `[A-Za-z_][A-Za-z0-9_]*`; job IDs and output names match `[A-Za-z_][A-Za-z0-9_-]*`.",
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The schema allows hyphens in needs.<job>.outputs.<name> via [A-Za-z0-9_-]*, and the examples imply ${{ needs.mint-token.outputs.access_token }} is valid. In GitHub Actions expressions, property access using dot notation only supports identifier-like names; job IDs (and output names) containing - generally require bracket syntax (e.g., needs['mint-token']...). As-is, this pattern will accept expressions that will compile here but fail when evaluated by Actions. Consider either (a) restricting job/output identifiers in the dot form to [A-Za-z_][A-Za-z0-9_]*, or (b) extending the pattern to explicitly support bracket notation for hyphenated IDs (and updating examples accordingly).

Suggested change
"pattern": "^\\$\\{\\{\\s*(secrets\\.[A-Za-z_][A-Za-z0-9_]*(\\s*\\|\\|\\s*secrets\\.[A-Za-z_][A-Za-z0-9_]*)*|needs\\.[A-Za-z_][A-Za-z0-9_-]*\\.outputs\\.[A-Za-z_][A-Za-z0-9_-]*)\\s*\\}\\}$",
"description": "GitHub token expression. Accepts a secrets expression (e.g., `${{ secrets.NAME }}` or `${{ secrets.NAME1 || secrets.NAME2 }}`) or a job output expression (e.g., `${{ needs.auth.outputs.token }}`). Pattern details: secret names match `[A-Za-z_][A-Za-z0-9_]*`; job IDs and output names match `[A-Za-z_][A-Za-z0-9_-]*`.",
"pattern": "^\\$\\{\\{\\s*(secrets\\.[A-Za-z_][A-Za-z0-9_]*(\\s*\\|\\|\\s*secrets\\.[A-Za-z_][A-Za-z0-9_]*)*|needs\\.[A-Za-z_][A-Za-z0-9_]*\\.outputs\\.[A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}$",
"description": "GitHub token expression. Accepts a secrets expression (e.g., `${{ secrets.NAME }}` or `${{ secrets.NAME1 || secrets.NAME2 }}`) or a job output expression (e.g., `${{ needs.auth.outputs.token }}`). Pattern details: secret names match `[A-Za-z_][A-Za-z0-9_]*`; job IDs and output names in dot notation match `[A-Za-z_][A-Za-z0-9_]*`.",

Copilot uses AI. Check for mistakes.
},
{
name: "valid job output expression - hyphenated job name",
token: "${{ needs.mint-token.outputs.access_token }}",
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This test treats ${{ needs.mint-token.outputs.access_token }} as valid. In GitHub Actions expressions, a job ID with - typically can’t be accessed via dot notation (it’s parsed as a subtraction); you need bracket syntax like needs['mint-token'].outputs.access_token (and similarly for hyphenated output keys). To avoid validating an expression that will fail at runtime, either change this case to use a job id without hyphens or update it to the bracket-access form (and ensure the schema accepts that form).

Suggested change
token: "${{ needs.mint-token.outputs.access_token }}",
token: "${{ needs['mint-token'].outputs.access_token }}",

Copilot uses AI. Check for mistakes.
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Apr 3, 2026

@copilot review comments

…hyphens in dot notation)

Job IDs and output names with hyphens cannot be reliably accessed via
dot notation in GitHub Actions expressions (they require bracket syntax
like `needs['job-id'].outputs.name`). Restrict the github_token pattern
to `[A-Za-z_][A-Za-z0-9_]*` for both job IDs and output names to avoid
accepting expressions that would fail at runtime.

Remove the hyphenated job ID integration test case that would have
validated an expression that fails at Actions evaluation time.

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b92b7d32-d754-414f-8528-cb10edf68454

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 3, 2026

@copilot review comments

Addressed in d31b3ab — restricted the needs.*.outputs.* pattern to [A-Za-z_][A-Za-z0-9_]* for both job IDs and output names (no hyphens), matching what dot-notation access supports in GitHub Actions expressions. Removed the hyphenated-job-name test case that would have accepted an expression that fails at runtime.

Copilot AI requested a review from pelikhan April 3, 2026 04:42
@pelikhan pelikhan merged commit 90fd1ca into main Apr 3, 2026
58 checks passed
@pelikhan pelikhan deleted the copilot/support-expression-based-safe-outputs branch April 3, 2026 04:47
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.

Support expression-based safe-outputs github-token from auth job outputs

3 participants