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

  1. Install the GitHub CLI and sign in with gh auth login. You need admin access to the repository.
  2. Open claude in the repository and run /install-github-app. It works only for repositories on github.com.
  3. Claude Code installs the Claude GitHub App, then stores a credential as a repository secret: ANTHROPIC_API_KEY for an API key, or CLAUDE_CODE_OAUTH_TOKEN for a long-lived token tied to your Claude subscription.
  4. It pushes a branch with the workflow files you picked and opens GitHub with a pull request ready. Merge it and @claude works.

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:

.github/workflows/claude.yml
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.

Comments on an issue or pull request
@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 grant contents: read and nothing that writes.
  • Claude’s tools. claude_args accepts any Claude Code flag. With a prompt, a plain-text instruction has no shell or GitHub access until you grant tools with --allowedTools, so grant the narrowest set: Bash(npm test *), not Bash.

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_actor to limit whose comments reach Claude.
  • Checking out a fork’s code at the workspace root in pull_request_target or workflow_run workflows, which run with your repository’s secrets. The security notes show the safe pattern.
  • Setting allowed_bots to *, or granting all of Bash.

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_key or claude_code_oauth_token.
  • Write @claude as a whole word. /claude and @claude-bot do not trigger it.
  • Check the commenter has write access to the repository.
  • Still using @beta? Change it to @v1, remove the mode input, rename direct_prompt to prompt, and move options such as max_turns into claude_args.
  • If you also use Code Review, remember its @claude review command contains the action’s trigger phrase too, so a workflow that matches any @claude comment will run as well. A different trigger_phrase avoids 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.

Questions people ask.

How do I set up Claude Code GitHub Actions?

Run /install-github-app inside Claude Code in the repository, with the GitHub CLI signed in and admin access to the repository. It installs the Claude GitHub App, stores your credential as a secret and opens a pull request with the workflow. Or do the same three steps by hand.

Can I use Claude Code GitHub Actions with my Claude subscription?

Yes. Run claude setup-token locally to create a long-lived OAuth token, store it as the CLAUDE_CODE_OAUTH_TOKEN secret, and pass it to the claude_code_oauth_token input. It needs a Pro, Max, Team or Enterprise plan, and runs then draw on that subscription rather than API billing.

Why is Claude not responding to @claude in my repository?

Check that the Claude GitHub App is installed, workflows are enabled, the secret is set with the right name, the comment uses @claude as a whole word, and the person commenting has write access to the repository.

Does the Claude Code action open pull requests by itself?

In its default configuration it commits to a new branch and replies with a link to create the pull request, so a person opens it. Keep branch protection with a required human approval so nothing it writes merges without review.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.