On this page#
- What the integration actually does
- The wiring
- Scope
- Required validation
- Invariants
- Stop conditions
- The two things that break it
- Verifying it works
- Team considerations
- Claude Code GitHub integration
- FAQ
What the integration actually does#
The claude code github integration is not a trusted developer living inside GitHub. It is an event-triggered automation path that gives Claude Code repository context, credentials, and explicitly granted GitHub permissions; the workflow—not the model—determines what it can read, change, and publish.
Claude Code is an agentic coding tool: it can inspect a codebase, plan changes, edit files, and run permitted commands. Connecting it to GitHub adds triggers and repository APIs. It does not automatically add your architectural constraints, review rules, or definition of done.
| What people assume | What the connection actually provides | |---|---| | Claude understands the repository | Claude receives the files and instructions available in that run | | It has normal developer access | It has the workflow token’s exact permissions | | A successful run means a correct change | It means the workflow completed | | GitHub approval makes the output safe | Approval controls merging, not reasoning quality | | The next developer gets the same behavior | Only committed configuration is shared |
That distinction matters in a real repository. If invariants exist only in a senior engineer’s head, the integration cannot preserve them reliably. Put operational rules in version control before enabling write access.
The official Claude Code documentation explains product operation. Your repository still needs its own contract covering allowed commands, protected paths, validation steps, and escalation conditions.
Photo by cottonbro studio on Pexels.
The wiring#
Wire the integration in four layers: repository instructions, a narrowly triggered workflow, minimum GitHub permissions, and ownership controls. Keep all four in the repository so another developer can review the connection without relying on whoever originally clicked through the GitHub setup.
1. Commit the repository contract#
Start with CLAUDE.md at the repository root. It should describe enforceable behavior, not offer a tour of the codebase.
# Repository operating contract
## Scope
- Make only changes required by the issue or pull request.
- Do not modify deployment, billing, authentication, or migration files
unless the request explicitly names them.
- Do not add dependencies without maintainer approval.

*Photo by Lukas Blazek on [Pexels](https://www.pexels.com/photo/person-encoding-in-laptop-574071/).*
## Required validation
1. Run the formatter.
2. Run the affected unit tests.
3. Run the repository type checker.
4. Report commands that could not be run.
## Invariants
- Public API behavior must remain backward-compatible.
- Database migrations must be additive.
- Authorization checks must remain server-side.

*Photo by Digital Buggu on [Pexels](https://www.pexels.com/photo/monitor-displaying-computer-application-374559/).*
## Stop conditions
- Stop if requirements conflict with these invariants.
- Stop if validation requires unavailable credentials.
- Ask for review instead of guessing across service boundaries.This file is not a security boundary. It is a reviewable operating contract. Security still comes from GitHub permissions, branch protection, secret scoping, and human approval.
For a more complete repository contract, review the PairFoundry Agent Operating Kit. The important move is committing the rules beside the code rather than keeping them in personal prompts.
2. Add a narrow GitHub Actions workflow#
Use explicit comment-based triggers and pin the action to a reviewed commit SHA. Replace the placeholders before committing; do not silently switch to a floating branch.
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
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Run Claude Code
uses: anthropics/claude-code-action@<PINNED_COMMIT_SHA>
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}This baseline can inspect code and respond through issues or pull requests, but it cannot push repository content because contents is read-only. That is the correct starting point.
Do not grant contents: write merely because an example workflow does. Add it only when the team deliberately wants automated commits, and keep branch protection in place.
3. Make ownership explicit#
Require review for the workflow and repository contract themselves:
# .github/CODEOWNERS
/.github/workflows/claude.yml @repo-maintainers
/CLAUDE.md @repo-maintainersUse your real team or usernames. If security or platform owners exist, add them to the workflow entry. The integration’s control plane deserves stricter review than ordinary application code because changing it can alter permissions and secret exposure.
The broader PairFoundry packs overview is useful when the missing piece is not GitHub wiring alone but a shared operating model for agents across repositories.
The two things that break it#
Two failures dominate: the workflow token cannot perform the requested operation, or the trigger runs in a context where the required secret is unavailable. Treat these as boundary failures. Expanding every permission or exposing secrets to untrusted code is the wrong fix.
1. Resource not accessible by integration#
This error means the GitHub token lacks permission for the API operation. Compare the failed operation with the workflow’s permissions block.
If Claude only needs to comment, retain:
permissions:
contents: read
issues: write
pull-requests: writeIf the approved design requires pushing a branch, change only the necessary capability:
permissions:
contents: write
issues: write
pull-requests: writeDo not add unrelated permissions “to make it work.” A broad token converts a configuration mistake or prompt-level failure into a repository-level incident.
2. The trigger runs, but authentication is missing#
Fork-originated workflows commonly lack repository secrets by design. The visible symptom is an absent ANTHROPIC_API_KEY, an authentication failure, or a step skipped before the agent starts.
Do not solve this by using a privileged event to check out and execute untrusted fork code. Instead:
- Keep secret-bearing execution on trusted repository context.
- Require a maintainer-controlled comment or label before invocation.
- Inspect the proposed fork diff without executing it.
- Separate untrusted validation from the secret-bearing agent job.
The Wiring It In collection covers the larger pattern: event context, credentials, and executable code must be evaluated together.
Verifying it works#
A green workflow is insufficient. Verify four properties separately: the intended user can trigger it, an unauthorized path cannot, the token is constrained as designed, and the output survives normal review. A connection is trustworthy only when both success and refusal behave correctly.
Run these checks on a disposable issue or branch:
- Positive trigger: Ask
@claudefor a read-only repository summary. Confirm the expected workflow starts and posts in the correct thread. - Negative trigger: Post a normal comment without the trigger phrase. No agent job should run.
- Permission boundary: Request a direct protected-branch change while
contents: readis configured. The operation should be refused or fail without modifying the repository. - Invariant check: Request a change that conflicts with
CLAUDE.md. The response should stop, identify the conflict, and ask for direction. - Review path: Request a safe, small edit. Confirm the diff, validation report, authorship, and approval requirements remain visible in GitHub.
Record the expected outcomes in the pull request that introduces the integration. Developers who need the underlying agent concepts first can use the free PairFoundry foundations track.
Team considerations#
The second developer usually inherits credentials, triggers, and unwritten assumptions—not the original installer’s mental model. Make setup reproducible from committed files, document who owns the secret and workflow, and define a rollback that does not require understanding the agent’s internal reasoning.
Keep a short runbook beside the workflow:
## Claude Code GitHub integration
Owner: @repo-maintainers
Secret required: ANTHROPIC_API_KEY
Trigger: A comment containing @claude
Default access: Read repository; write issue and PR comments
Write access: Disabled
Disable procedure: Disable the workflow in GitHub Actions
Review required for: Workflow, CLAUDE.md, permission, or trigger changesThe common handoff traps are predictable:
- The secret exists in one repository but not another.
- A personal GitHub installation is mistaken for an organization-owned integration.
CLAUDE.mdchanges without the workflow owner reviewing it.- The action reference floats instead of staying pinned.
- Write permission is enabled, but branch protection is weakened to accommodate it.
- Developers assume identical behavior despite different event contexts.
Review the integration like production infrastructure. Every permission increase, trigger expansion, secret change, or action update should arrive through a pull request with an explicit reason and rollback plan.
Related reading#
- Linear MCP Claude Code — a setup that survives a second developer
- Getting Jira MCP Claude Code right the first time
FAQ#
These are the questions that matter after the happy-path setup works: where the integration should stop, how its repository contract differs from product documentation, what teams must share, and how to retreat safely when credentials, permissions, or generated changes behave unexpectedly.
When should I avoid enabling Claude Code on a repository?#
Avoid secret-bearing automation when untrusted contributions can control executed code, when the repository lacks meaningful review protection, or when critical invariants remain undocumented. Begin with local Claude Code usage or a read-only GitHub connection until ownership, validation, and approval boundaries are explicit.
How is this different from following the official setup?#
The official setup establishes the product connection. This approach defines the repository-specific trust boundary: committed instructions, narrow triggers, least-privilege permissions, protected secrets, ownership, negative tests, and rollback. Both are necessary, but only the second tells your team whether the connection is safe for this repository.
What must be shared for another developer to get the same behavior?#
Share the workflow, CLAUDE.md, ownership rules, required secret name, trigger convention, and runbook through version control. Repository or organization administrators must provision the actual secret separately. Personal prompts and undocumented installation choices do not constitute a reproducible team setup.
How do we roll back when the integration misbehaves?#
Disable the GitHub Actions workflow first, then revoke or rotate the API secret if exposure is possible. Revert the workflow or instruction change through the normal pull-request path, inspect any generated branches or comments, and restore access only after the failed boundary has a specific explanation.
Should the integration be allowed to push commits?#
Start with no. Commenting with a proposed patch preserves a clean human-controlled boundary. Grant contents: write only when automated commits provide a concrete workflow benefit, protected branches still require review, and the team has tested both successful writes and denied writes.