Claude Code GitHub Actions: Setup and Safe Uses
The official Claude Code action runs Claude inside your own GitHub workflows, answering @claude mentions or running a prompt on any event. How to set it up, what the three layers of permissions are, what it costs in words, and which uses are safe to leave running.
8 min read
Claude Code GitHub Actions is Anthropic’s official action, anthropics/claude-code-action@v1, which runs Claude Code on your repository’s GitHub Actions runners. Set it up by running /install-github-app inside Claude Code, or by installing the Claude GitHub App, adding a secret and committing a workflow file yourself. Once it is in place, anyone with write access can mention @claude in an issue or pull request and Claude replies, answers questions or pushes commits to a branch. Give the workflow a prompt and it runs on any event instead, such as a schedule. You pay for two things: GitHub Actions minutes, and Claude usage through an API key or your Claude subscription. The safe pattern is Claude proposing on a branch and a person merging.
What it is, and the products it is not
The Claude Code GitHub Actions documentation (opens in a new tab) is careful to separate products that share the Claude Code name. The action is a workflow integration you configure with files in your repository, and it is built on the Claude Agent SDK. Code Review is a separate managed service that reviews pull requests without a workflow file; how it compares for review is covered in using AI agents for PR review. Claude Code on the web runs sessions in Anthropic’s cloud rather than on your runners. If you only want automatic reviews, Code Review may be the simpler choice; if you want Claude to act on requests or run on a schedule, it is the action.
Setup: the quick way
- Install the GitHub CLI and sign in with
gh auth login. You need admin access to the repository. - Open
claudein the repository and run/install-github-app. It works only for repositories on github.com. - Claude Code installs the Claude GitHub App, then stores a credential as a repository secret:
ANTHROPIC_API_KEYfor an API key, orCLAUDE_CODE_OAUTH_TOKENfor a long-lived token tied to your Claude subscription. - It pushes a branch with the workflow files you picked and opens GitHub with a pull request ready. Merge it and
@claudeworks.
Choose Skip for now after the app installs if you only want the app, and run the command again later for the rest. Quick setup works with the Claude API and Claude subscriptions; Amazon Bedrock, Google Cloud and Microsoft Foundry have their own setup, selected with use_bedrock, use_vertex or use_foundry. The documentation now calls Google’s service “Google Cloud’s Agent Platform”, while the input keeps the use_vertex name.
Setup by hand
Install the Claude GitHub App on the repository, add one of the two secrets, and copy the example workflow into .github/workflows/. The documented mention workflow is short; this version adds a timeout, a concurrency group and a turn cap, all of which the documentation recommends for cost control:
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
claude:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
timeout-minutes: 30
concurrency:
group: claude-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: "--max-turns 15"The if line stops a runner from starting on comments that do not mention Claude. id-token: write is needed for the action’s default GitHub App authentication, and actions: read lets Claude read CI results on pull requests. The action’s own example adds triggers for new issues and submitted reviews, so @claude in an issue’s title or body works too.
Using @claude
With no prompt input, the action runs in interactive mode: it waits for the trigger phrase, @claude unless you change trigger_phrase, and replies in a comment that it updates as it works.
@claude how should I add rate limiting to the login endpoint? @claude fix the TypeError in the cart summary component @claude implement this feature based on the issue description
When it changes code, the action’s security notes (opens in a new tab) say it commits to a new branch and replies with a link to GitHub’s pull request page; a person clicks the link to open the pull request. That is a good default to keep. Claude follows your repository’s CLAUDE.md, and it reads the file on every run, so keep it short.
Permissions: three layers
What Claude can do in a run is the narrowest of three separate settings, and it is worth checking each one.
- The GitHub App. The action relies on its Contents, Issues and Pull requests permissions, all read and write. The app is shared with Code Review and other Claude features, and GitHub does not let you accept part of an app’s permissions, so the full set is wider. Anthropic’s two pages disagree on detail: the Claude Code docs list Actions, Checks and Workflows as read and write, while the action’s security notes list Actions and Checks as read and describe them as not yet used. If your organization wants only the three the action uses, the docs describe creating a custom GitHub App instead.
- The workflow token. The
permissions:block sets what the job’s GITHUB_TOKEN (opens in a new tab) may do. A read-only job, such as a daily report, should grantcontents: readand nothing that writes. - Claude’s tools.
claude_argsaccepts any Claude Code flag. With aprompt, a plain-text instruction has no shell or GitHub access until you grant tools with--allowedTools, so grant the narrowest set:Bash(npm test *), notBash.
Before Claude starts, the action checks who triggered it. On issue and pull request events the person needs write access, and bot accounts are refused unless listed in allowed_bots, which stops two bots from triggering each other in a loop. allowed_non_write_users relaxes the first check; the security notes call it a significant risk, suitable only for workflows with very limited permissions.
What it costs, in words
- Runner time. The action runs on GitHub-hosted runners, which use your account’s GitHub Actions minutes (opens in a new tab). A run that spends minutes thinking spends minutes of runner time too.
- Claude usage. With an API key, each run is billed by tokens, which grow with the prompt, the task and the size of the codebase Claude reads. With
CLAUDE_CODE_OAUTH_TOKEN, runs draw on your Claude subscription instead. - Using a subscription. Generate the token locally with
claude setup-token; the authentication docs describe a one-year token that needs a Pro, Max, Team or Enterprise plan. It is tied to the subscription of the person who created it, so for a secret shared across an organization the docs recommend an API key.
To keep both down: write specific requests so Claude needs fewer turns, cap turns with --max-turns, set timeout-minutes on the job, and use GitHub’s concurrency groups to stop parallel runs piling up. The documentation lists all four.
Safe uses, and uses to avoid
Good first uses, each low risk because a person reads the output before it matters:
- Questions about the code in an issue thread: where something lives, how a module works.
- Small, well-described fixes that arrive as a branch for a person to open and review.
- A daily or weekly summary of commits and open issues, written to the run log with read-only permissions.
- Explaining a failing CI run on a pull request, without permission to change anything.
Uses to avoid, or to lock down hard first:
- Letting Claude merge, or approving a pull request an agent wrote with an agent’s review alone. Keep a required human approval on the default branch.
- Running on untrusted content in public repositories. Issue and comment text can carry hidden instructions; the action strips HTML comments and invisible characters, but its notes say new bypasses may appear. Use
include_comments_by_actorto limit whose comments reach Claude. - Checking out a fork’s code at the workspace root in
pull_request_targetorworkflow_runworkflows, which run with your repository’s secrets. The security notes show the safe pattern. - Setting
allowed_botsto*, or granting all ofBash.
When @claude does not respond
- Check that the Claude GitHub App is installed on this repository and that Actions is enabled.
- Check that the secret exists and its name matches the input:
anthropic_api_keyorclaude_code_oauth_token. - Write
@claudeas a whole word./claudeand@claude-botdo not trigger it. - Check the commenter has write access to the repository.
- Still using
@beta? Change it to@v1, remove themodeinput, renamedirect_prompttoprompt, and move options such asmax_turnsintoclaude_args. - If you also use Code Review, remember its
@claude reviewcommand contains the action’s trigger phrase too, so a workflow that matches any@claudecomment will run as well. A differenttrigger_phraseavoids the double run.
If CI does not run on Claude’s commits, the cause is usually passing the default GITHUB_TOKEN; how to automate Claude Code tasks explains that trap and the other guardrails for unattended runs.
Keep the record on the task
A GitHub thread records the conversation; it does not tell the rest of the team whether a piece of work is finished and tested. If your work lives on a fenbs board, put the task’s ref (BUG-042, say) in the issue title, and when Claude’s branch is merged, comment the pull request and how it was tested on the task and move it to Completed. The action can also write to the board itself through --mcp-config in claude_args, using a hand-issued fenbs token with a name, only the scopes it needs, and an expiry; the automation post linked above shows the snippet. The board checks that token’s scopes on every call, whatever the prompt says, and revoking it ends the job’s access.
Related
Running Claude Code outside GitHub: Claude Code headless mode. GitHub’s own agent, compared: the GitHub Copilot coding agent. What a token’s scopes allow: assistant tokens and scopes.