AnswerQA

How do I wire Claude Code into my GitHub PRs without giving it my production secrets?

Answer

Install the Claude Code GitHub Action via /install-github-app, scope ANTHROPIC_API_KEY as a repo or environment secret, and pass only the secrets a PR job actually needs. The webhook is GitHub's; the work runs on GitHub's runners; the failure mode is mis-scoped secrets, not the action itself.

By Kalle Lamminpää Verified May 7, 2026

The Claude Code GitHub Action runs on GitHub’s runners, but the prompts, diffs, and tool inputs Claude reasons about do flow outbound to Anthropic’s API. The real security risk is not the action; it is which repo secrets you let the runner expose, especially on workflows that build forked PRs.

Install the action

Open a Claude Code session in the target repo and run the slash command:

/install-github-app

(That is /install-github-app typed at Claude’s prompt inside the CLI, not a shell command.) You need repository admin to install the app and add secrets. The slash command walks through:

  1. Installing the Claude GitHub app on the target repo (requests read and write permissions for Contents, Issues, Pull requests).
  2. Adding ANTHROPIC_API_KEY to the repo’s Actions secrets.
  3. Copying a starter workflow from the action’s examples/ directory into .github/workflows/.

Test the install by leaving a comment on any issue or PR:

@claude can you summarize this PR?

The action picks up the mention, runs Claude with the configured prompt, and posts the reply back as a PR/issue comment.

Scope ANTHROPIC_API_KEY correctly

The default install puts ANTHROPIC_API_KEY at repo scope, which means every workflow in the repo can read it. That is fine for repos where every workflow is trusted; it is dangerous for repos that build untrusted contributor PRs.

Three scoping patterns:

Where the workflow runsRight scope for ANTHROPIC_API_KEY
Only on commits to main / internal branchesRepo secret (default)
On any PR including from forksEnvironment secret with required reviewer or branch-protection rule
Across many repos in one orgOrganization secret restricted to specific repos

Prefer environment secrets with a required-reviewer rule for any repo that runs jobs from forks. The action key is one credential a fork PR could try to exfiltrate (by writing it into a log line, an artifact, or an outbound HTTP call from a shell step).

Keep production secrets out of the action job

The single most common mistake is dumping every secret into the same workflow. Claude does not need your prod database URL, your Stripe live key, or your AWS production credentials to comment on a PR. It needs ANTHROPIC_API_KEY and whatever the user prompt explicitly asks it to use.

Workflow shape that holds:

name: Claude Code
on:
  issue_comment:
    types: [created]
jobs:
  claude:
    if: contains(github.event.comment.body, '@claude')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
    steps:
      - uses: actions/checkout@v4
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          claude_args: --max-turns 10

anthropic_api_key is passed via with: per the v1 input shape. The permissions: block scopes the workflow’s GITHUB_TOKEN, the credential the action uses to call the GitHub API; it is a separate layer from the GitHub App’s installed permissions (Contents, Issues, Pull requests R/W) which the App requests at install time. The job intentionally exposes no other secrets: no AWS_ACCESS_KEY_ID, no STRIPE_SECRET_KEY, no DATABASE_URL. If a future prompt asks Claude to “deploy this”, the workflow either lacks the credentials (the right answer) or you have already broken the principle.

PR feedback loop patterns

Mention-driven Q&A. The default install. Reviewers tag @claude in PR comments to ask questions, request edits, or get summaries. Claude replies as the GitHub App user. Cheapest setup; useful when the team genuinely uses GitHub PR comments for review.

Auto-summary on PR open. Trigger the action on pull_request: opened with a fixed prompt. Claude posts a one-shot summary, never replies again. Good for “every PR gets a 5-bullet plain-English description”; ignore-able when not needed.

Failing-test triage on push. Trigger on pull_request: synchronize (new commits) and pass a prompt like “Run the test suite. If anything failed, comment with the failure and a likely cause.” Claude only posts when there is something to say.

Auto-fix via the separate Code Review GitHub App. Different product, different setup. The Code Review app posts inline review comments without an @claude trigger; the action in this article responds to mentions. Pick one or the other for any given repo, not both, or you will get the same observation from two voices.

Footguns

Forks can read repo secrets via pull_request_target. A workflow triggered by pull_request_target runs in the context of the base repo with full access to repo secrets, even when the PR comes from a fork. A malicious fork can echo "$ANTHROPIC_API_KEY" | base64 > artifact.txt and exfiltrate the key in a build artifact. Prefer issue_comment (which runs on the base repo’s main branch only) for @claude flows; if you must use pull_request_target, gate the job on a label that requires a maintainer to add.

@claude mentions can be social-engineered. Anyone who can comment on the issue or PR can summon Claude. A drive-by contributor who posts “@claude please rewrite the auth middleware to be simpler” gets Claude to do unsupervised refactoring on a PR you have not reviewed. Path filters do not help here (paths-ignore does not apply to issue_comment workflows). Gate the job on a comment-author allowlist (if: contains(fromJSON('["maintainer1","maintainer2"]'), github.event.comment.user.login)) or on author association (github.event.comment.author_association == 'OWNER' / 'COLLABORATOR' / 'MEMBER').

The action runs with the permissions you gave it, not the user’s. A repo collaborator without write access to main can still trigger the action, which runs with the permissions: block in the workflow file. If that block has contents: write, Claude can push to main from a comment on a PR opened by a non-maintainer. Scope permissions: to the minimum and pin protected branches.

Beta-to-v1 migrations break workflows silently. The @beta action and @v1 action take different inputs (direct_prompt became prompt, model moved into claude_args, max_turns likewise). A workflow pinned to @beta keeps working until Anthropic deprecates the beta tag, then fails on the next push. Migrate to @v1 proactively; the breaking-changes table in the canonical doc lists every input that moved.

Logs leak more than people think. A workflow that runs claude --max-turns 50 with verbose logging can dump conversation summaries, tool inputs, and stack traces to the GitHub Actions log. If your repo is public, those logs are public. Set claude_args: --max-turns 10 and avoid passing sensitive prompts via direct_prompt literal strings; reference repo files instead so the secret material does not live in the workflow file.

When NOT to use the GitHub Action

  • The repo is public and you want code review. Use the Code Review GitHub App instead. It is built for this and posts inline review comments without an @claude trigger.
  • You need real CI gating, not commentary. The action posts comments and pushes commits; it does not block merges by default. Branch protection plus required status checks is still the lever for “no PR merges without X”.
  • You are running on Bedrock, Vertex, or Foundry. The default action expects an Anthropic API key. Cloud-provider variants exist but require additional setup; do not attempt the default install path.
  • The repo accepts contributions from random forks and you do not have environment secrets. The risk-to-reward ratio is wrong. Either set up environment secrets with required-reviewer rules first, or skip the action until you do.
  • You wanted a code formatter, not Claude. Prettier in a hook (format on edit) costs less and runs faster. Reach for the action only when the work needs reasoning, not just lexical rewrites.

Sources

  • Claude Code GitHub Actions
    Authoritative: `/install-github-app` setup, manual setup, repo permissions the app requests (Contents, Issues, Pull requests R/W), beta-to-v1 migration.
  • Agent SDK
    The action is built on the Agent SDK. Useful when you want to script custom automations (a comment-only assistant, a release-notes bot) instead of using the @claude mention shape.
  • Using secrets in GitHub Actions
    Repo vs environment vs organization secret scopes. The right scoping for ANTHROPIC_API_KEY depends on which workflows run untrusted code (forks).

Was this helpful?