Run GitHub Copilot CLI in GitHub Actions Without PATs or Runaway AI Costs
AI automation in CI has always had two awkward questions: which long-lived token do you give the agent, and how do you stop an unattended run from spending more than expected?
GitHub has now addressed both. Since 2 July 2026, GitHub Copilot CLI can authenticate inside GitHub Actions with the workflow's built-in GITHUB_TOKEN. No personal access token (PAT) is required. Copilot CLI also supports per-session AI credit limits, so a non-interactive run can stop when it reaches the amount you set.
In this tutorial, we will build a manually triggered repository-review workflow that:
- authenticates without a stored PAT
- uses read-only repository permissions
- caps each Copilot session with
--max-ai-credits - writes the report to the GitHub Actions job summary
- checks that the agent did not modify the checkout
- limits duplicate and long-running jobs
The result is a useful starting point for repository health checks, CI failure analysis, release preparation, and scheduled engineering reports.
Current status: AI credit session limits are in public preview. The syntax and billing behaviour described here were verified against GitHub's documentation on 20 July 2026.
What You Will Build
The finished workflow has a deliberately small trust boundary:
Developer selects Run workflow
|
v
GitHub Actions creates a short-lived GITHUB_TOKEN
|
| contents: read
| copilot-requests: write
v
Copilot CLI reviews the ephemeral checkout
|
| --max-ai-credits 31, 50, or 100
v
Markdown report is written to the job summary
|
v
Workflow verifies that the checkout is unchanged
There is no PAT in repository secrets. The workflow token exists only for the job, and its permissions are declared explicitly. AI credits used in an organisation-owned repository are billed to the organisation.
This tutorial invokes Copilot CLI directly because that makes the authentication, permissions, and cost boundary easy to inspect. GitHub recommends GitHub Agentic Workflows for most production automation because it adds safeguards designed for unattended agents. We will compare the two approaches later.
Prerequisites
You will need:
- an organisation-owned GitHub repository with GitHub Actions enabled
- Copilot CLI enabled for the organisation
- permission to update the organisation's Copilot policies
- the Allow use of Copilot CLI billed to the organization policy enabled
- enough organisation AI credit budget for the test run
The session-limit feature requires Copilot CLI 1.0.66 or later. The workflow installs the latest version so that both GITHUB_TOKEN authentication and --max-ai-credits are available.
No PAT, API key, or custom Actions secret is required.
How AI credits translate to cost
GitHub defines one AI credit as $0.01 USD. A limit of 50 AI credits therefore represents a nominal session boundary of $0.50 USD.
Session limits are soft caps. Copilot only knows the cost of a response after that response completes, so an in-flight response can make the final usage slightly higher than the configured limit. Session limits complement organisation budgets and cost centres; they do not replace them.
GitHub also recommends setting a limit above 30 credits because many model calls cost more than 20 credits. That is why this tutorial offers 31 as the lowest choice rather than using a tiny value that may prevent useful work.
Step 1: Enable Organisation Billing for the Workflow
An organisation owner must allow Actions workflows to bill Copilot CLI usage directly to the organisation.
- Open the organisation settings on GitHub.com.
- Navigate to the organisation's GitHub Copilot policy settings.
- Find the Copilot CLI section.
- Confirm that Allow use of Copilot CLI billed to the organization is selected.
GitHub enables this setting by default when the existing Copilot CLI policy is enabled, but it is worth checking before debugging a failed workflow.
When this policy is active, a workflow can authenticate with GITHUB_TOKEN by declaring one additional permission:
permissions:
contents: read
copilot-requests: write
contents: read lets the checkout action read the repository. copilot-requests: write allows the token to make Copilot requests billed to the organisation. It does not grant write access to repository contents.
Step 2: Add the Bounded Repository Review Workflow
Create .github/workflows/copilot-ci-review.yml in the repository you want Copilot to inspect.
name: Copilot CLI repository review
on:
workflow_dispatch:
inputs:
max_ai_credits:
description: Maximum AI credits for this Copilot session
required: true
default: '50'
type: choice
options:
- '31'
- '50'
- '100'
permissions:
contents: read
copilot-requests: write
concurrency:
group: copilot-ci-review-${{ github.ref }}
cancel-in-progress: true
jobs:
review:
name: Run bounded Copilot review
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Install latest Copilot CLI
run: |
npm install --global @github/copilot@latest
copilot --version
- name: Review repository
id: copilot
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
MAX_AI_CREDITS: ${{ inputs.max_ai_credits }}
REPORT_PATH: ${{ runner.temp }}/copilot-review.md
PROMPT: >-
Perform a read-only review of this repository at the current commit. Do not modify files. Produce a concise Markdown report containing: likely build and test commands based on repository evidence; the top three reliability or security risks with repository-relative file references; missing or weak automated checks; and three prioritised actions. Do not print secrets, tokens, or environment-variable values.
run: |
set -o pipefail
copilot --yolo -p "$PROMPT" \
--max-ai-credits "$MAX_AI_CREDITS" \
| tee "$REPORT_PATH"
- name: Publish Copilot report
if: ${{ always() }}
shell: bash
env:
REPORT_PATH: ${{ runner.temp }}/copilot-review.md
run: |
if [[ -s "$REPORT_PATH" ]]; then
cat "$REPORT_PATH" >> "$GITHUB_STEP_SUMMARY"
else
echo "## Copilot CLI review" >> "$GITHUB_STEP_SUMMARY"
echo "No report was produced. Check the workflow log." >> "$GITHUB_STEP_SUMMARY"
fi
- name: Verify Copilot made no file changes
if: ${{ always() }}
shell: bash
run: |
if [[ -n "$(git status --porcelain)" ]]; then
echo "Copilot changed the checkout unexpectedly:"
git status --short
exit 1
fi
You can also find the complete sample in code/copilot-ci-review.yml.
Let us unpack the controls that matter.
Manual trigger and bounded choices
The workflow only runs through workflow_dispatch. That avoids automatically feeding code from untrusted pull requests into an agent with broad local tool access.
The credit limit is a choice rather than free text. Users can select 31, 50, or 100 credits, but cannot inject arbitrary shell content through the workflow input.
Short-lived authentication
This line exposes the job's automatically generated token to Copilot CLI:
env:
GITHUB_TOKEN: ${{ github.token }}
The token is created for the workflow job, constrained by the permissions block, and expires when the job ends. There is no secret to rotate and no individual developer identity tied to the automation.
Non-interactive execution
GitHub's direct-invocation example uses --yolo so Copilot does not pause for interactive tool approvals in Actions:
copilot --yolo -p "$PROMPT" --max-ai-credits "$MAX_AI_CREDITS"
The name is memorable because the risk is real. --yolo gives Copilot broad access to the workflow environment. A prompt saying "do not modify files" is guidance, not a security boundary.
The actual boundaries are the manual trigger, read-only repository permission, ephemeral runner, timeout, credit cap, and final clean-worktree check. Do not add deployment credentials or production secrets to this job.
Report outside the checkout
The report is written to ${{ runner.temp }} instead of the repository workspace. This lets the final step use git status --porcelain to detect any tracked or untracked file created by the agent.
The report step uses if: ${{ always() }}. If Copilot reaches the credit limit or exits with an error after producing partial output, the workflow still attempts to publish that output to the job summary.
Two independent limits
The workflow combines:
-
--max-ai-credits, which bounds model usage for the Copilot session -
timeout-minutes: 10, which bounds total job runtime
The concurrency group also cancels an older run on the same branch when a replacement starts. This reduces accidental duplicate spend.
Step 3: Run the Workflow
Commit the workflow to the repository's default branch, then:
- Open the repository on GitHub.com.
- Select Actions.
- Select Copilot CLI repository review.
- Select Run workflow.
- Keep the first run at 50 AI credits.
- Select Run workflow again to confirm.
The job should:
- check out the repository
- install the latest Copilot CLI package
- print the installed version
- authenticate with
GITHUB_TOKEN - inspect the repository within the selected credit limit
- publish a Markdown report
- verify that the checkout remains unchanged
Open the completed run and select Summary. A successful result will resemble:
## Repository review
### Likely build and test commands
- `npm ci`
- `npm test`
- `npm run lint`
### Reliability or security risks
1. The deployment workflow uses a floating third-party action version...
2. Integration tests do not cover the authentication failure path...
3. Dependency updates are not automated...
### Prioritised actions
1. Pin external actions to reviewed commit SHAs.
2. Add an authentication failure integration test.
3. Enable grouped dependency update pull requests.
The exact findings will depend on the repository and model. Treat the report as triage input, not as proof that the repository is secure or production-ready.
Step 4: Prove the Cost Boundary
Run the workflow again and select 31 AI credits. A sufficiently complex repository review may reach the limit before completing.
When a non-interactive session reaches its limit, Copilot stops cleanly and the command ends. Because the cap is soft, a response already in progress completes first and may take the final total slightly above 31 credits.
Do not rely on forcing the limit as a deterministic test. Model selection, token usage, and repository complexity all affect consumption. The repeatable checks are:
- confirm the log shows
--max-ai-creditsreceiving the selected value - confirm an over-limit run stops rather than waiting for human input
- review organisation usage in GitHub's billing and usage dashboards
- apply organisation budgets or cost-centre budgets as the outer spending boundary
User-level budgets are not considered when Actions usage is billed directly to the organisation because the activity is not attributed to an individual user.
Security Hardening Before Reuse
Direct Copilot CLI execution is powerful, but it needs the same threat modelling as any other privileged CI automation.
| Risk | Control in this tutorial | Production recommendation |
|---|---|---|
| Long-lived credential theft | Uses job-scoped GITHUB_TOKEN
|
Do not replace it with a PAT unless there is a documented requirement |
| Repository modification |
contents: read and clean-worktree check |
Keep write operations in a separate reviewed job |
| Untrusted pull request content | Manual trigger only | Never run this pattern on forked PRs with sensitive credentials |
| Unbounded model usage | Selectable --max-ai-credits value |
Add organisation budgets, alerts, and cost-centre attribution |
| Runaway execution | Ten-minute timeout and concurrency cancellation | Tune the timeout to the smallest useful value |
| Secret disclosure | No extra secrets and prompt forbids printing environment values | Keep deployment secrets out of the job entirely |
| Unsafe agent output | Human reads the job summary | Never execute commands copied from the report automatically |
| Dependency drift | CLI version is printed in the log | Pin a tested CLI version after validating new releases |
For high-assurance environments, pin actions/checkout to a reviewed full commit SHA rather than a moving major-version tag. You can also pin @github/copilot after testing a specific release that supports both token authentication and session limits.
Remember that repository content can contain prompt-injection instructions. Read-only GitHub permissions stop a compromised prompt from pushing code, but the agent can still read files available in the checkout and interact with its local runner environment. Keep the environment intentionally sparse.
Direct Copilot CLI or GitHub Agentic Workflows?
GitHub's documentation recommends Agentic Workflows for most automation scenarios. Direct CLI invocation still has a useful place when you need to add one bounded reasoning step to an existing workflow.
| Consideration | Direct Copilot CLI step | GitHub Agentic Workflows |
|---|---|---|
| Definition | Standard Actions YAML | Natural-language Markdown compiled to Actions YAML |
| Existing workflow integration | Straightforward | Better suited to agent-first workflows |
| Authentication |
GITHUB_TOKEN with copilot-requests: write
|
GITHUB_TOKEN by default |
| Guardrails | You design them | Includes agent-focused integrity, firewall, safe-output, and threat-detection controls |
| Best fit | A bounded task inside an established pipeline | Issue triage, reporting, compliance, and change-producing autonomous workflows |
Use the direct pattern when you understand and control the prompt, trigger, tools, and environment. Start with Agentic Workflows when the agent will process untrusted content, propose repository changes, or operate across a broader part of the software delivery lifecycle.
Practical Variations
Once the basic workflow is working, the same pattern can support several read-only DevOps tasks:
CI failure analysis
Download test results or build logs as artifacts, then ask Copilot to identify the likely failure chain and recommend the next diagnostic action. Avoid passing raw secrets or environment dumps into the prompt.
Release-readiness report
Ask Copilot to inspect changelogs, dependency updates, migrations, tests, and deployment definitions, then produce a checklist for a human release owner.
Infrastructure review
Ask Copilot to review Terraform, Bicep, Kubernetes, or workflow files for risky defaults, missing validation, and likely operational gaps. Keep cloud credentials out of the job and do not let the report apply changes automatically.
Scheduled repository health summary
Replace workflow_dispatch with a trusted schedule trigger after the prompt and cost profile are stable. Keep concurrency, timeout, permissions, and AI credit limits in place.
Validate the Result
Use this checklist before adopting the workflow more broadly:
- [ ] The organisation policy allows Copilot CLI usage billed to the organisation.
- [ ] The workflow contains no PAT or custom authentication secret.
- [ ] Permissions are limited to
contents: readandcopilot-requests: write. - [ ] The installed Copilot CLI version is
1.0.66or later. - [ ] The selected credit value appears in the Copilot command.
- [ ] The report appears in the Actions job summary.
- [ ] The final clean-worktree check passes.
- [ ] The run appears in organisation billing and usage data.
- [ ] A human reviews the output before taking action.
For a stronger validation, temporarily add a harmless tracked test file to the prompt's requested output. The clean-worktree step should detect the change and fail. Remove that test immediately afterwards; the production prompt should remain read-only.
Troubleshooting
Copilot returns an authentication or permission error
Check all three layers:
- The organisation policy Allow use of Copilot CLI billed to the organization is enabled.
- The workflow declares
copilot-requests: write. -
GITHUB_TOKEN: ${{ github.token }}is present on the Copilot step.
Also confirm that the repository belongs to the organisation whose policy and billing you configured.
--max-ai-credits is unknown
The installed CLI is too old. Session limits require Copilot CLI 1.0.66 or later. Check the version printed by the installation step and reinstall the latest package:
npm install --global @github/copilot@latest
copilot --version
The run exceeds the selected credit value
This can happen because the session limit is a soft cap. A model response already in progress is allowed to finish. Use the session limit together with organisation budgets and spending limits.
The report step runs after Copilot fails
That is intentional. if: ${{ always() }} preserves partial output and writes a diagnostic message when no report exists. The overall job still retains the Copilot step's failure state.
The clean-worktree check fails
Inspect the git status --short output. The prompt may have caused Copilot to create or edit a file despite the read-only instruction. Tighten the task, remove unnecessary tools or credentials, and consider moving the use case to Agentic Workflows before enabling it again.
Conclusion
Running an AI agent in CI no longer needs to mean storing a developer's PAT or accepting an open-ended model bill. GitHub Actions can issue Copilot CLI a short-lived, narrowly scoped GITHUB_TOKEN, while --max-ai-credits gives every run an explicit session boundary.
The important lesson is that authentication and cost controls are only part of the design. The trigger, repository permissions, runner contents, timeout, prompt, output handling, and human approval path all determine whether the automation is trustworthy.
Start with a manually triggered, read-only report like this one. Measure its output and cost, keep the environment free of sensitive credentials, and only expand its authority when the workflow has earned it.
Author
Like, share, follow me on: 🐙 GitHub | 🐧 X | 👾 LinkedIn
Date: 20-07-2026
Top comments (0)