Remove the Copilot CLI PAT From GitHub Actions Without Losing Your Rollback
GitHub announced on July 2, 2026 that Copilot CLI no longer needs a personal access token when it runs in GitHub Actions. Primary source: GitHub Changelog, July 2, 2026. Deleting a secret is easy. Proving the workflow
GitHub announced on July 2, 2026 that Copilot CLI no longer needs a personal access token when it runs in GitHub Actions.
Primary source: GitHub Changelog, July 2, 2026.
Deleting a secret is easy. Proving the workflow still worksβand recovering without hurriedly pasting credentials back into YAMLβis the useful part. This is an unexecuted migration template, not a report from a production repository.
Make one reversible change
First find every place the old secret enters the job, including reusable workflows:
git grep -nE 'COPILOT_PAT|COPILOT_GITHUB_TOKEN|GH_TOKEN|github_pat'
Record the workflow, job, pinned CLI version, permissions block, and previous known-good commit. Never print environment variables while debugging.
Then remove only the PAT injection. Do not upgrade the runner and CLI in the same patch.
jobs:
copilot-check:
permissions:
contents: read
- env:
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT }}
steps:
- uses: actions/checkout@<PINNED_COMMIT>
- run: ./scripts/setup-copilot-cli.sh
- run: ./scripts/run-bounded-check.sh
The scripts are placeholders for repository-owned commands. βNo PAT requiredβ does not mean βno identity or permissions existβ; follow the current setup documentation and keep permissions explicit.
Add a canary with two proofs
The canary should show that the legacy token is absent and that the existing bounded task still satisfies its output contract.
name: copilot-cli-auth-canary
on: workflow_dispatch
permissions:
contents: read
jobs:
canary:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@<PINNED_COMMIT>
- name: Verify legacy PAT is absent
run: |
test -z "${COPILOT_PAT:-}"
test -z "${COPILOT_GITHUB_TOKEN:-}"
- run: ./scripts/setup-copilot-cli.sh
- run: copilot --version
- run: ./scripts/run-bounded-check.sh
Use a read-only, cheap task. βFix whatever you findβ is not a canary; it is a small deployment wearing a fake mustache.
Define pass criteria before clicking Run: absent legacy variables, expected CLI version, successful bounded command, valid output, and no authorization warning. Classify failures as install, authentication, permission, output, timeout, or service failure.
Keep the exit ramp
- Change commit: `<sha>`
- Previous workflow commit: `<sha>`
- CLI version: `<version>`
- Legacy PAT injected: `no`
- Canary run: `<url>`
- Result: `pass | fail`
- Rollback owner: `<role>`
- Secret deletion due: `<UTC timestamp>`
If the canary fails, revert the one migration commit and rerun the known-good workflow. Do not widen permissions during rollback. If it passes, rerun from the protected default branch, observe scheduled uses for an agreed window, then delete the obsolete secret at every scope.
One removed credential, two explicit proofs, and one boring rollback path. Boring is excellent when authentication breaks at 2 a.m.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.