{"slug": "run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs", "title": "Run GitHub Copilot CLI in GitHub Actions Without PATs or Runaway AI Costs", "summary": "GitHub has updated Copilot CLI to authenticate inside GitHub Actions using the built-in GITHUB_TOKEN, eliminating the need for personal access tokens. The tool also now supports per-session AI credit limits via the --max-ai-credits flag, allowing developers to cap costs during unattended runs. A developer can set up a repository-review workflow that uses these features for tasks like health checks and CI failure analysis.", "body_md": "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?\n\nGitHub has now addressed both. Since 2 July 2026, GitHub Copilot CLI can authenticate inside GitHub Actions with the workflow's built-in `GITHUB_TOKEN`\n\n. 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.\n\nIn this tutorial, we will build a manually triggered repository-review workflow that:\n\n`--max-ai-credits`\n\nThe result is a useful starting point for repository health checks, CI failure analysis, release preparation, and scheduled engineering reports.\n\nCurrent 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.\n\nThe finished workflow has a deliberately small trust boundary:\n\n```\nDeveloper selects Run workflow\n             |\n             v\nGitHub Actions creates a short-lived GITHUB_TOKEN\n             |\n             | contents: read\n             | copilot-requests: write\n             v\nCopilot CLI reviews the ephemeral checkout\n             |\n             | --max-ai-credits 31, 50, or 100\n             v\nMarkdown report is written to the job summary\n             |\n             v\nWorkflow verifies that the checkout is unchanged\n```\n\nThere 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.\n\nThis tutorial invokes Copilot CLI directly because that makes the authentication, permissions, and cost boundary easy to inspect. GitHub recommends [GitHub Agentic Workflows](https://github.com/github/gh-aw) for most production automation because it adds safeguards designed for unattended agents. We will compare the two approaches later.\n\nYou will need:\n\nThe session-limit feature requires Copilot CLI `1.0.66`\n\nor later. The workflow installs the latest version so that both `GITHUB_TOKEN`\n\nauthentication and `--max-ai-credits`\n\nare available.\n\nNo PAT, API key, or custom Actions secret is required.\n\nGitHub defines one AI credit as $0.01 USD. A limit of 50 AI credits therefore represents a nominal session boundary of $0.50 USD.\n\nSession 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.\n\nGitHub 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.\n\nAn organisation owner must allow Actions workflows to bill Copilot CLI usage directly to the organisation.\n\nGitHub enables this setting by default when the existing Copilot CLI policy is enabled, but it is worth checking before debugging a failed workflow.\n\nWhen this policy is active, a workflow can authenticate with `GITHUB_TOKEN`\n\nby declaring one additional permission:\n\n```\npermissions:\n  contents: read\n  copilot-requests: write\n```\n\n`contents: read`\n\nlets the checkout action read the repository. `copilot-requests: write`\n\nallows the token to make Copilot requests billed to the organisation. It does not grant write access to repository contents.\n\nCreate `.github/workflows/copilot-ci-review.yml`\n\nin the repository you want Copilot to inspect.\n\n```\nname: Copilot CLI repository review\n\non:\n  workflow_dispatch:\n    inputs:\n      max_ai_credits:\n        description: Maximum AI credits for this Copilot session\n        required: true\n        default: '50'\n        type: choice\n        options:\n          - '31'\n          - '50'\n          - '100'\n\npermissions:\n  contents: read\n  copilot-requests: write\n\nconcurrency:\n  group: copilot-ci-review-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  review:\n    name: Run bounded Copilot review\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    steps:\n      - name: Check out repository\n        uses: actions/checkout@v6\n\n      - name: Install latest Copilot CLI\n        run: |\n          npm install --global @github/copilot@latest\n          copilot --version\n\n      - name: Review repository\n        id: copilot\n        shell: bash\n        env:\n          GITHUB_TOKEN: ${{ github.token }}\n          MAX_AI_CREDITS: ${{ inputs.max_ai_credits }}\n          REPORT_PATH: ${{ runner.temp }}/copilot-review.md\n          PROMPT: >-\n            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.\n\n        run: |\n          set -o pipefail\n          copilot --yolo -p \"$PROMPT\" \\\n            --max-ai-credits \"$MAX_AI_CREDITS\" \\\n            | tee \"$REPORT_PATH\"\n\n      - name: Publish Copilot report\n        if: ${{ always() }}\n        shell: bash\n        env:\n          REPORT_PATH: ${{ runner.temp }}/copilot-review.md\n        run: |\n          if [[ -s \"$REPORT_PATH\" ]]; then\n            cat \"$REPORT_PATH\" >> \"$GITHUB_STEP_SUMMARY\"\n          else\n            echo \"## Copilot CLI review\" >> \"$GITHUB_STEP_SUMMARY\"\n            echo \"No report was produced. Check the workflow log.\" >> \"$GITHUB_STEP_SUMMARY\"\n          fi\n\n      - name: Verify Copilot made no file changes\n        if: ${{ always() }}\n        shell: bash\n        run: |\n          if [[ -n \"$(git status --porcelain)\" ]]; then\n            echo \"Copilot changed the checkout unexpectedly:\"\n            git status --short\n            exit 1\n          fi\n```\n\nYou can also find the complete sample in [ code/copilot-ci-review.yml](https://./code/copilot-ci-review.yml).\n\nLet us unpack the controls that matter.\n\nThe workflow only runs through `workflow_dispatch`\n\n. That avoids automatically feeding code from untrusted pull requests into an agent with broad local tool access.\n\nThe credit limit is a `choice`\n\nrather than free text. Users can select 31, 50, or 100 credits, but cannot inject arbitrary shell content through the workflow input.\n\nThis line exposes the job's automatically generated token to Copilot CLI:\n\n```\nenv:\n  GITHUB_TOKEN: ${{ github.token }}\n```\n\nThe token is created for the workflow job, constrained by the `permissions`\n\nblock, and expires when the job ends. There is no secret to rotate and no individual developer identity tied to the automation.\n\nGitHub's direct-invocation example uses `--yolo`\n\nso Copilot does not pause for interactive tool approvals in Actions:\n\n```\ncopilot --yolo -p \"$PROMPT\" --max-ai-credits \"$MAX_AI_CREDITS\"\n```\n\nThe name is memorable because the risk is real. `--yolo`\n\ngives Copilot broad access to the workflow environment. A prompt saying \"do not modify files\" is guidance, not a security boundary.\n\nThe 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.\n\nThe report is written to `${{ runner.temp }}`\n\ninstead of the repository workspace. This lets the final step use `git status --porcelain`\n\nto detect any tracked or untracked file created by the agent.\n\nThe report step uses `if: ${{ always() }}`\n\n. 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.\n\nThe workflow combines:\n\n`--max-ai-credits`\n\n, which bounds model usage for the Copilot session`timeout-minutes: 10`\n\n, which bounds total job runtimeThe concurrency group also cancels an older run on the same branch when a replacement starts. This reduces accidental duplicate spend.\n\nCommit the workflow to the repository's default branch, then:\n\nThe job should:\n\n`GITHUB_TOKEN`\n\nOpen the completed run and select **Summary**. A successful result will resemble:\n\n```\n## Repository review\n\n### Likely build and test commands\n\n- `npm ci`\n- `npm test`\n- `npm run lint`\n\n### Reliability or security risks\n\n1. The deployment workflow uses a floating third-party action version...\n2. Integration tests do not cover the authentication failure path...\n3. Dependency updates are not automated...\n\n### Prioritised actions\n\n1. Pin external actions to reviewed commit SHAs.\n2. Add an authentication failure integration test.\n3. Enable grouped dependency update pull requests.\n```\n\nThe 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.\n\nRun the workflow again and select **31** AI credits. A sufficiently complex repository review may reach the limit before completing.\n\nWhen 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.\n\nDo not rely on forcing the limit as a deterministic test. Model selection, token usage, and repository complexity all affect consumption. The repeatable checks are:\n\n`--max-ai-credits`\n\nreceiving the selected valueUser-level budgets are not considered when Actions usage is billed directly to the organisation because the activity is not attributed to an individual user.\n\nDirect Copilot CLI execution is powerful, but it needs the same threat modelling as any other privileged CI automation.\n\n| Risk | Control in this tutorial | Production recommendation |\n|---|---|---|\n| Long-lived credential theft | Uses job-scoped `GITHUB_TOKEN`\n|\nDo not replace it with a PAT unless there is a documented requirement |\n| Repository modification |\n`contents: read` and clean-worktree check |\nKeep write operations in a separate reviewed job |\n| Untrusted pull request content | Manual trigger only | Never run this pattern on forked PRs with sensitive credentials |\n| Unbounded model usage | Selectable `--max-ai-credits` value |\nAdd organisation budgets, alerts, and cost-centre attribution |\n| Runaway execution | Ten-minute timeout and concurrency cancellation | Tune the timeout to the smallest useful value |\n| Secret disclosure | No extra secrets and prompt forbids printing environment values | Keep deployment secrets out of the job entirely |\n| Unsafe agent output | Human reads the job summary | Never execute commands copied from the report automatically |\n| Dependency drift | CLI version is printed in the log | Pin a tested CLI version after validating new releases |\n\nFor high-assurance environments, pin `actions/checkout`\n\nto a reviewed full commit SHA rather than a moving major-version tag. You can also pin `@github/copilot`\n\nafter testing a specific release that supports both token authentication and session limits.\n\nRemember 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.\n\nGitHub'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.\n\n| Consideration | Direct Copilot CLI step | GitHub Agentic Workflows |\n|---|---|---|\n| Definition | Standard Actions YAML | Natural-language Markdown compiled to Actions YAML |\n| Existing workflow integration | Straightforward | Better suited to agent-first workflows |\n| Authentication |\n`GITHUB_TOKEN` with `copilot-requests: write`\n|\n`GITHUB_TOKEN` by default |\n| Guardrails | You design them | Includes agent-focused integrity, firewall, safe-output, and threat-detection controls |\n| Best fit | A bounded task inside an established pipeline | Issue triage, reporting, compliance, and change-producing autonomous workflows |\n\nUse 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.\n\nOnce the basic workflow is working, the same pattern can support several read-only DevOps tasks:\n\nDownload 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.\n\nAsk Copilot to inspect changelogs, dependency updates, migrations, tests, and deployment definitions, then produce a checklist for a human release owner.\n\nAsk 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.\n\nReplace `workflow_dispatch`\n\nwith a trusted `schedule`\n\ntrigger after the prompt and cost profile are stable. Keep concurrency, timeout, permissions, and AI credit limits in place.\n\nUse this checklist before adopting the workflow more broadly:\n\n`contents: read`\n\nand `copilot-requests: write`\n\n.`1.0.66`\n\nor later.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.\n\nCheck all three layers:\n\n`copilot-requests: write`\n\n.`GITHUB_TOKEN: ${{ github.token }}`\n\nis present on the Copilot step.Also confirm that the repository belongs to the organisation whose policy and billing you configured.\n\n`--max-ai-credits`\n\nis unknown\nThe installed CLI is too old. Session limits require Copilot CLI `1.0.66`\n\nor later. Check the version printed by the installation step and reinstall the latest package:\n\n```\nnpm install --global @github/copilot@latest\ncopilot --version\n```\n\nThis 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.\n\nThat is intentional. `if: ${{ always() }}`\n\npreserves partial output and writes a diagnostic message when no report exists. The overall job still retains the Copilot step's failure state.\n\nInspect the `git status --short`\n\noutput. 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.\n\nRunning 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`\n\n, while `--max-ai-credits`\n\ngives every run an explicit session boundary.\n\nThe 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.\n\nStart 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.\n\nLike, share, follow me on: 🐙 [GitHub](https://github.com/Pwd9000-ML) | 🐧 [X](https://x.com/pwd9000) | 👾 [LinkedIn](https://www.linkedin.com/in/marcel-pwd9000/)\n\nDate: 20-07-2026", "url": "https://wpnews.pro/news/run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs", "canonical_source": "https://dev.to/pwd9000/run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs-3dpf", "published_at": "2026-07-20 16:02:20+00:00", "updated_at": "2026-07-20 16:06:04.150427+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-infrastructure", "mlops", "ai-products"], "entities": ["GitHub", "GitHub Copilot CLI", "GitHub Actions", "GITHUB_TOKEN", "GitHub Agentic Workflows"], "alternates": {"html": "https://wpnews.pro/news/run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs", "markdown": "https://wpnews.pro/news/run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs.md", "text": "https://wpnews.pro/news/run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs.txt", "jsonld": "https://wpnews.pro/news/run-github-copilot-cli-in-github-actions-without-pats-or-runaway-ai-costs.jsonld"}}