Skip to content

safe-outputs: checkout fallback uses empty secrets.GITHUB_TOKEN #47156

Description

@bryanchen-d

This was generated by AI during triage.

Summary

gh-aw v0.82.14 generates safe-output checkout steps with:

token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}

secrets.GITHUB_TOKEN is not the automatic Actions token, so when
GH_AW_GITHUB_TOKEN is unset the expression is empty. Every generated checkout
then fails authentication, including checkout of the workflow's own private
repository.

Version

gh aw version v0.82.14

Reproduction

Use a workflow in a private control-plane repository with:

checkout:
  - sparse-checkout: |
      .github/workflows/example.md
  - repository: owner/public-target
    path: ./target
    current: true

safe-outputs:
  github-app:
    client-id: ${{ steps.app.outputs.client-id }}
    private-key: ${{ steps.app.outputs.private-key }}
    owner: owner
    repositories: [public-target]
  create-pull-request:
    target-repo: owner/public-target

The agent checkouts use the automatic token and succeed. The generated
safe_outputs job emits the secret fallback above for its mirrored checkouts.

Actual result

Both checkout steps fail:

fatal: could not read Username for 'https://github.com': terminal prompts disabled

Concrete run:
https://github.com/microsoft/vscode-engineering/actions/runs/29877683511

The agent and threat-detection model paths completed; safe outputs could not
apply the already-generated patch.

Expected result

When no explicit checkout token is configured, safe-output checkout should use
the automatic repository token:

token: ${{ github.token }}

The GitHub App configured under safe-outputs.github-app should remain the
credential for target-repository write operations. It should not be required to
be installed on the private control-plane repository merely so the trusted
processor can check out its triggering ref.

Security relevance

Working around this requires either a long-lived GH_AW_GITHUB_TOKEN, installing
the public-output App on the private control-plane repository, or manually
editing generated locks. All broaden credentials or bypass the source-of-truth
compiler flow.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions