Claude Code GitHub Actions: Authentication & Permissions Analysis

Date: 2025-12-04
Status: Root Cause Identified
Severity: Configuration Issue (Not a Bug)

Executive Summary

The perceived “approval requirement” for GitHub CLI commands in Claude Code workflows is NOT a bug but a deliberate security feature. Claude Code, when invoked via anthropics/claude-code-action@v1, operates with GitHub authentication automatically provided by the action itself - not through environment variables like GH_TOKEN. The workflows are correctly configured, but understanding the authentication mechanism is critical for proper usage.

Root Cause Analysis

Issue Description

Users may expect Claude Code to automatically have access to GitHub CLI (gh) commands within workflows, similar to how workflow shell steps can use GH_TOKEN: $. However, Claude Code’s authentication mechanism is fundamentally different.

Core Problem: Authentication Context Separation

There are two distinct authentication contexts in these workflows:

1. Workflow Shell Steps Authentication

- name: Update issue labels based on outcome
  run: |
    gh issue view $
  env:
    GH_TOKEN: $  # ← Shell environment variable

Characteristics:

  • Uses GITHUB_TOKEN secret as an environment variable
  • GitHub CLI (gh) automatically detects GH_TOKEN environment variable
  • Works immediately in shell scripts
  • Scoped by workflow permissions: block

2. Claude Code Execution Authentication

- uses: anthropics/claude-code-action@v1
  with:
    claude_code_oauth_token: $
    claude_args: '--allowed-tools "Bash(gh pr comment:*)"'

Characteristics:

  • Uses GitHub App authentication (installed via /install-github-app in Claude CLI)
  • Authentication is managed internally by the action
  • Does NOT use GH_TOKEN environment variable
  • Requires explicit tool permission grants via --allowed-tools

How Claude Code Action Handles Authentication

Based on the action documentation and source code analysis:

  1. GitHub App Installation:
    • When you run /install-github-app in Claude CLI, it installs the official “Claude Code” GitHub App
    • The app requests permissions: contents, pull-requests, issues, discussions, actions, checks, workflows
    • The app generates a short-lived, repository-scoped token
  2. Token Injection:
    • The anthropics/claude-code-action@v1 action automatically obtains a GitHub App token
    • This token is injected into Claude Code’s execution environment
    • Claude Code uses this token for all GitHub API/CLI operations
  3. Permission Verification:
    • The action verifies that the triggering user has write access to the repository (security feature)
    • Bots are blocked by default (can be enabled with allowed_bots input)
    • The GitHub App token respects the workflow’s permissions: block
  4. Tool Access Control:
    • By default, Claude Code has NO access to arbitrary Bash commands
    • Must explicitly grant access via claude_args: '--allowed-tools "Bash(...)"
    • GitHub CLI commands (gh) must be explicitly allowed

Why You Don’t See Approval Prompts

The authentication “just works” because:

  1. You ran /install-github-app in Claude CLI (one-time setup)
  2. The GitHub App is installed on the cloudnnj/momentum repository
  3. The CLAUDE_CODE_OAUTH_TOKEN secret is configured in repository settings
  4. The action automatically uses the GitHub App token for Claude Code execution
  5. No additional github_token input is needed (only for custom GitHub Apps)

Workflow-by-Workflow Analysis

1. claude-auto-fix.yml

Status: ✅ Correctly Configured

Authentication Setup:

permissions:
  contents: write        # Push branches
  pull-requests: write   # Create PRs
  issues: write          # Comment & label issues
  id-token: write
  actions: read

steps:
  - uses: anthropics/claude-code-action@v1
    with:
      claude_code_oauth_token: $
      claude_args: '--allowed-tools "Bash(*),Read,Write,Edit,Glob,Grep,Task"'

Analysis:

  • ✅ Uses CLAUDE_CODE_OAUTH_TOKEN for Claude authentication
  • ✅ Grants Bash(*) - allows ALL Bash commands including gh
  • ✅ Workflow shell steps correctly use GH_TOKEN: $
  • ✅ Permissions are appropriate for creating PRs and commenting

Why GitHub CLI Works for Claude:

  • Bash(*) wildcard allows all Bash commands
  • GitHub App authentication is automatically injected by the action
  • Claude can run gh pr create, gh issue comment, etc. without approval

Potential Issue:

  • Bash(*) is VERY permissive - allows unrestricted command execution
  • Consider restricting to: Bash(gh *),Bash(git *),Bash(npm test)

2. claude-clarification-response.yml

Status: ✅ Correctly Configured (Same as claude-auto-fix.yml)

Authentication Setup:

permissions:
  contents: write
  pull-requests: write
  issues: write
  id-token: write
  actions: read

steps:
  - uses: anthropics/claude-code-action@v1
    with:
      claude_code_oauth_token: $
      claude_args: '--allowed-tools "Bash(*),Read,Write,Edit,Glob,Grep,Task"'

Analysis: Same as claude-auto-fix.yml - correctly configured with broad Bash permissions.

3. claude-code-review.yml

Status: ⚠️ Restrictive Configuration (May Need Adjustment)

Authentication Setup:

permissions:
  contents: read          # ← Read-only!
  pull-requests: read     # ← Read-only!
  issues: read            # ← Read-only!
  id-token: write

steps:
  - uses: anthropics/claude-code-action@v1
    with:
      claude_code_oauth_token: $
      claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'

Analysis:

  • ✅ Uses CLAUDE_CODE_OAUTH_TOKEN for Claude authentication
  • ✅ Explicitly allows specific gh commands (secure pattern!)
  • ⚠️ PROBLEM: Permissions are read-only but allows gh pr comment!
  • gh pr comment will FAIL because workflow has pull-requests: read (not write)

Issue:

claude_args: '--allowed-tools "Bash(gh pr comment:*)"'  # ← Requires pull-requests: write!

Why This Fails:

  1. Claude attempts to run gh pr comment ...
  2. GitHub App token respects workflow permissions: block
  3. Token only has pull-requests: read permission
  4. GitHub API rejects the comment creation (403 Forbidden)

Fix Required:

permissions:
  contents: read
  pull-requests: write   # ← Change from read to write
  issues: read
  id-token: write

OR remove gh pr comment from allowed tools:

claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'

4. claude.yml

Status: ✅ Minimal Configuration (Read-Only)

Authentication Setup:

permissions:
  contents: read
  pull-requests: read
  issues: read
  id-token: write
  actions: read

steps:
  - uses: anthropics/claude-code-action@v1
    with:
      claude_code_oauth_token: $
      # NO claude_args specified - uses defaults

Analysis:

  • ✅ Uses CLAUDE_CODE_OAUTH_TOKEN for Claude authentication
  • ✅ No claude_args means NO Bash access (secure!)
  • ✅ Claude can only use built-in file operations and read GitHub context
  • ✅ Cannot run gh commands (not in default allowed tools)

Default Allowed Tools (when claude_args not specified):

  • File operations: Read, Write, Edit, Glob, Grep
  • Git operations: Read-only git commands
  • Comment management: Creating/updating comments (if permissions allow)

Why This Works:

  • This workflow is for interactive @claude mentions
  • Users ask questions, Claude responds with analysis
  • No need for Bash/gh commands - just file reading and analysis

Key Insights

1. GitHub Token vs OAuth Token

Aspect GITHUB_TOKEN (Shell) CLAUDE_CODE_OAUTH_TOKEN (Claude)
Purpose Authenticate shell commands Authenticate Claude Code execution
Scope Workflow steps only Claude Code internal operations
Usage env: GH_TOKEN: $ with: claude_code_oauth_token: $
Permissions Defined by workflow permissions: Defined by GitHub App + workflow permissions:
Setup Automatic (GitHub provides) Manual (via /install-github-app)

2. The --allowed-tools Flag is Critical

Default Behavior:

# Without claude_args, Claude CANNOT run Bash commands
- uses: anthropics/claude-code-action@v1
  with:
    claude_code_oauth_token: $

Granting Bash Access:

# Allow specific gh commands (SECURE)
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh pr list:*)"'

# Allow all Bash commands (DANGEROUS)
claude_args: '--allowed-tools "Bash(*)"'

3. Permissions Hierarchy

Authentication flows through this hierarchy:

  1. GitHub App Installation (organization/repository level)
    • Installed via /install-github-app in Claude CLI
    • Defines maximum possible permissions
  2. Workflow Permissions Block (workflow level)
    permissions:
      contents: write
      pull-requests: write
    
    • Restricts what the GitHub App token can do in this workflow
  3. Allowed Tools Configuration (action level)
    claude_args: '--allowed-tools "Bash(gh pr comment:*)"'
    
    • Controls what commands Claude can execute

Result: Most restrictive permission wins.

Answers to Original Questions

1. What is the root cause of any permission/approval issues?

Answer: There is no “approval issue” in the traditional sense. The workflows are configured correctly. Any perceived approval prompts would be due to:

  • Missing GitHub App Installation: If /install-github-app wasn’t run, the GitHub App isn’t installed
  • Missing OAuth Token Secret: If CLAUDE_CODE_OAUTH_TOKEN secret isn’t configured
  • Permission Mismatch: When claude_args allows a command but workflow permissions: doesn’t grant the required permission (e.g., claude-code-review.yml)

2. How does anthropics/claude-code-action handle GitHub authentication for Claude?

Answer: The action uses GitHub App authentication:

  1. User runs /install-github-app in Claude CLI (one-time setup)
  2. This installs the “Claude Code” GitHub App on the repository
  3. The action obtains a short-lived, repository-scoped token from the GitHub App
  4. This token is automatically injected into Claude Code’s execution environment
  5. Claude Code uses this token for all GitHub API/CLI operations
  6. The token respects the workflow’s permissions: block

No manual token passing required - it’s automatic!

3. Are the --allowed-tools arguments sufficient for GitHub CLI access?

Answer: Yes, BUT you must ensure:

  1. claude_args includes Bash(gh ...) patterns
  2. ✅ Workflow permissions: grants required permissions
  3. CLAUDE_CODE_OAUTH_TOKEN secret is configured
  4. ✅ GitHub App is installed on the repository

Example Patterns:

# Allow all gh commands (broad)
--allowed-tools "Bash(gh *)"

# Allow specific gh subcommands (secure)
--allowed-tools "Bash(gh issue view:*),Bash(gh pr comment:*)"

# Allow all Bash commands (dangerous)
--allowed-tools "Bash(*)"

4. What alternative approaches exist for enabling Claude to interact with GitHub?

Alternatives:

  1. Current Approach (Recommended): GitHub App + CLAUDE_CODE_OAUTH_TOKEN
    • ✅ Most secure (scoped tokens)
    • ✅ Automatic token management
    • ✅ No token expiration issues
  2. Custom GitHub App: Use github_token input ```yaml
    • uses: anthropics/claude-code-action@v1 with: github_token: $ claude_args: ‘–allowed-tools “Bash(gh *)”’ ```
    • ⚠️ Only for advanced use cases
    • ⚠️ Requires managing your own GitHub App
  3. Personal Access Token (NOT RECOMMENDED): ```yaml
    • uses: anthropics/claude-code-action@v1 with: anthropic_api_key: $ claude_args: ‘–allowed-tools “Bash(*)”’ env: GH_TOKEN: $ ```
    • ❌ Less secure (long-lived tokens)
    • ❌ Broader permissions than needed
    • ❌ Harder to audit

5. Is there a difference between workflow shell steps using GH_TOKEN vs Claude Code using gh commands?

Answer: Yes, fundamentally different mechanisms:

Aspect Workflow Shell Steps Claude Code Bash Tool
Authentication env: GH_TOKEN: $ GitHub App token (automatic)
Token Type Workflow-generated token GitHub App installation token
Scope Shell environment only Claude Code execution context
Command Execution Direct shell execution Executed through Claude Code’s tool system
Permission Check Workflow permissions: block Workflow permissions: + --allowed-tools
Token Lifetime Duration of workflow run Duration of Claude Code execution

Example:

jobs:
  test:
    permissions:
      issues: write

    steps:
      # Shell step - uses GITHUB_TOKEN
      - name: Comment via shell
        run: gh issue comment 123 --body "Hello"
        env:
          GH_TOKEN: $  # ← Shell env var

      # Claude Code - uses GitHub App token (automatic)
      - uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: $
          prompt: "Comment on issue #123 with 'Hello'"
          claude_args: '--allowed-tools "Bash(gh issue comment:*)"'
          # ↑ GitHub App token automatically available, NO env var needed

Recommendations

1. Fix claude-code-review.yml Permission Mismatch

Current Problem:

permissions:
  pull-requests: read  # ← Read-only but allows gh pr comment!

Solution Option A (Grant write permission):

permissions:
  contents: read
  pull-requests: write  # ← Change to write
  issues: read
  id-token: write

Solution Option B (Remove comment tool):

claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
# Removed: Bash(gh pr comment:*)

Recommended: Option A - code review should be able to comment

2. Tighten Bash Permissions in Auto-Fix Workflows

Current:

claude_args: '--allowed-tools "Bash(*),Read,Write,Edit,Glob,Grep,Task"'
# ↑ VERY PERMISSIVE - allows ANY Bash command

Recommended:

claude_args: '--allowed-tools "Bash(gh *),Bash(git *),Bash(npm test),Bash(npm run *),Read,Write,Edit,Glob,Grep,Task"'
# ↑ Restricted to specific command patterns

Why This Matters:

  • Bash(*) allows execution of ANY shell command
  • If Claude is compromised or makes an error, it could run dangerous commands
  • Principle of least privilege: only grant what’s needed

3. Add Additional Permissions for CI/CD Integration (Optional)

If you want Claude to analyze CI/CD failures:

permissions:
  contents: write
  pull-requests: write
  issues: write
  actions: read        # ← Add this
  id-token: write

steps:
  - uses: anthropics/claude-code-action@v1
    with:
      claude_code_oauth_token: $
      additional_permissions: |
        actions: read   # ← Add this

This enables Claude to use:

  • gh run list - View workflow runs
  • gh run view - View workflow run details
  • gh run watch - Monitor workflow progress

4. Document Tool Permissions

Create a comment in each workflow explaining why specific tools are allowed:

# Tool Permissions Explanation:
# - Bash(gh *): Required for creating PRs, commenting, and labeling issues
# - Bash(git *): Required for branch management and commits
# - Bash(npm test): Required for running tests to verify fixes
# - Read,Write,Edit: Required for file operations
# - Glob,Grep: Required for code analysis
# - Task: Required for multi-step workflows
claude_args: '--allowed-tools "Bash(gh *),Bash(git *),Bash(npm test),Read,Write,Edit,Glob,Grep,Task"'

Security Best Practices

1. Never Commit Secrets

WRONG:

claude_code_oauth_token: "oauth_abc123..."  # EXPOSED!

CORRECT:

claude_code_oauth_token: $

2. Use Principle of Least Privilege

TOO PERMISSIVE:

permissions:
  contents: write
  pull-requests: write
  issues: write
  actions: write
  checks: write
  workflows: write  # Overkill!

MINIMAL PERMISSIONS:

permissions:
  contents: write        # Only what's needed
  pull-requests: write
  issues: write

3. Restrict Allowed Tools

TOO BROAD:

claude_args: '--allowed-tools "Bash(*)"'  # ANY command!

SPECIFIC PATTERNS:

claude_args: '--allowed-tools "Bash(gh issue *),Bash(gh pr *),Bash(npm test)"'

4. Verify User Access

Current workflows correctly check that triggering user has write access:

jobs:
  auto-fix:
    # Only runs if user has write access (automatic check by action)
    runs-on: ubuntu-latest
    permissions:
      contents: write

No additional configuration needed - the action automatically verifies user permissions.

5. Review Workflow Logs

Monitor workflow logs for unexpected behavior:

# View recent workflow runs
gh run list --workflow=claude-auto-fix.yml --limit 10

# View specific run details
gh run view 12345

# Download logs
gh run download 12345

Testing & Verification

Test Checklist

  • Verify GitHub App is installed on repository
  • Verify CLAUDE_CODE_OAUTH_TOKEN secret is configured
  • Test each workflow with a sample issue/PR
  • Verify Claude can create PRs (auto-fix workflows)
  • Verify Claude can comment on issues (clarification workflow)
  • Check that unauthorized users cannot trigger workflows
  • Monitor workflow logs for authentication errors

Verification Commands

# Check GitHub App installation
gh api /repos/cloudnnj/momentum/installation

# Check repository secrets (names only, not values)
gh secret list

# Test gh commands with workflow permissions
gh auth status

# List workflow runs
gh run list --workflow=claude-auto-fix.yml

# View workflow configuration
gh workflow view claude-auto-fix.yml

Troubleshooting

Issue: “GraphQL: Resource not accessible by integration”

Cause: Workflow permissions don’t grant required access

Solution: Check permissions: block matches required operations

# If Claude needs to comment:
permissions:
  issues: write        # Required for issue comments
  pull-requests: write # Required for PR comments

Issue: “The operation requires elevated permissions”

Cause: Triggering user doesn’t have write access to repository

Solution:

  • Verify user has write/admin role in repository settings
  • Or use allowed_non_write_users (RISKY - see security docs)

Issue: “Command not found: gh”

Cause: gh command not allowed in claude_args

Solution: Add to allowed tools:

claude_args: '--allowed-tools "Bash(gh *)"'

Issue: “Authentication failed”

Cause: CLAUDE_CODE_OAUTH_TOKEN not configured or expired

Solution:

  1. Run /install-github-app in Claude CLI
  2. Follow prompts to generate new token
  3. Update secret in GitHub repository settings

Conclusion

The Claude Code GitHub Actions workflows are correctly configured and do not require approval for GitHub CLI commands. Authentication is handled automatically through the GitHub App integration. The key points:

  1. Authentication is automatic - no manual token management needed
  2. Workflows use correct authentication method - CLAUDE_CODE_OAUTH_TOKEN
  3. ⚠️ One permission mismatch found - claude-code-review.yml needs pull-requests: write
  4. ⚠️ Overly permissive Bash access - Consider restricting Bash(*) to specific patterns
  5. Security model is sound - GitHub App + least privilege permissions

Next Steps

  1. Fix claude-code-review.yml permission mismatch
  2. Tighten Bash permissions in auto-fix workflows
  3. Document tool permissions in workflow comments
  4. Monitor workflow logs for any authentication issues
  5. Consider adding CI/CD integration permissions if needed

The workflows are production-ready with minor recommended improvements.


References:


Back to top

Momentum LMS © 2025. Distributed under the MIT license.