Skip to content

fix: restore authorization check on Claude workflow caller#46

Merged
danielewood merged 1 commit intomainfrom
fix/claude-workflow-auth
Feb 17, 2026
Merged

fix: restore authorization check on Claude workflow caller#46
danielewood merged 1 commit intomainfrom
fix/claude-workflow-auth

Conversation

@danielewood
Copy link
Copy Markdown
Collaborator

Summary

  • Restore OWNER/MEMBER/COLLABORATOR authorization gate on the Claude workflow caller — prevents OAuth token secret from being transmitted to the reusable workflow for unauthorized users
  • Add missing CHANGELOG entry for ci: centralize CI workflows and pre-commit hooks #45 (CI centralization)

Flagged by Claude code review on #45.

Test plan

  • Workflow syntax validates (no CI startup failure)
  • @claude mention from org member still triggers Claude

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings February 16, 2026 20:08
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restores authorization checks on the Claude workflow to prevent unauthorized users from triggering workflows that expose OAuth token secrets. It also adds a missing CHANGELOG entry for PR #45 which centralized CI workflows.

Changes:

  • Add authorization gate checking for OWNER/MEMBER/COLLABORATOR roles in the Claude workflow
  • Add CHANGELOG entry and reference link for PR #45

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
.github/workflows/claude.yml Adds authorization condition to restrict Claude workflow to repository owner, members, and collaborators
CHANGELOG.md Adds missing entry for PR #45 (CI centralization) and corresponding reference link

Comment thread .github/workflows/claude.yml Outdated
Comment on lines +30 to +32
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authorization check does not properly handle all event types that trigger this workflow. The condition references github.event.comment.author_association but this field is not available for all event types:

  • For issues events, the sender is in github.event.issue.user and there is no comment object
  • For pull_request_review events, the review author association should be checked via github.event.review.author_association

This means the authorization check will always evaluate to false for issues and pull_request_review events (where there's no github.event.comment object), potentially blocking legitimate users while still exposing the OAuth token through the workflow execution context.

The condition should check the appropriate author_association field for each event type, or use a more robust authorization mechanism.

Suggested change
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'
(
(github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment') &&
(
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'
)
) ||
(
github.event_name == 'pull_request_review' &&
(
github.event.review.author_association == 'OWNER' ||
github.event.review.author_association == 'MEMBER' ||
github.event.review.author_association == 'COLLABORATOR'
)
) ||
(
github.event_name == 'issues' &&
(
github.event.issue.author_association == 'OWNER' ||
github.event.issue.author_association == 'MEMBER' ||
github.event.issue.author_association == 'COLLABORATOR'
)
)

Copilot uses AI. Check for mistakes.
@claude

This comment has been minimized.

@danielewood danielewood force-pushed the fix/claude-workflow-auth branch from cba2da8 to e29978a Compare February 17, 2026 20:37
Defense-in-depth: gate secret transmission behind OWNER/MEMBER/
COLLABORATOR check at the caller level, not just the reusable
workflow. Check author_association on the correct event object for
each trigger type (comment, review, issue) — previously only
comment-based events were checked, silently blocking members on
review and issue events.

Also adds missing CHANGELOG entries for #45 and #46.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 17, 2026 20:42
@danielewood danielewood force-pushed the fix/claude-workflow-auth branch from e29978a to f09f3b4 Compare February 17, 2026 20:42
@claude
Copy link
Copy Markdown

claude Bot commented Feb 17, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Notes (non-blocking):

  • github.event.sender.login == github.repository_owner is always false for org-owned repos (github.repository_owner returns "sensiblebit", never an individual user's login). This arm is dead code, but since it's in an OR chain with the working author_association checks, it doesn't affect correctness or security. Consider removing it to avoid confusion.

@danielewood danielewood merged commit 2c77c2f into main Feb 17, 2026
19 checks passed
@danielewood danielewood deleted the fix/claude-workflow-auth branch February 17, 2026 20:45
@claude
Copy link
Copy Markdown

claude Bot commented Feb 17, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment on lines +36 to +38
github.event.issue.author_association == 'OWNER' ||
github.event.issue.author_association == 'MEMBER' ||
github.event.issue.author_association == 'COLLABORATOR'
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authorization check for the issues event type assigned is incorrect. When an issue is assigned (not opened), github.event.sender is the person performing the assignment, but the code checks github.event.issue.author_association, which is the association of the person who originally created the issue. This means an unauthorized user could assign an existing issue that contains @claude in its body/title and trigger the workflow with the OAuth token.

To fix this security issue, you should check github.event.sender's authorization directly. However, GitHub Actions doesn't expose sender.author_association directly. The safest approach is to either:

  1. Remove the assigned trigger type from the issues event, keeping only opened
  2. Use a separate API call to check the sender's association (more complex)
  3. Rely only on the github.event.sender.login == github.repository_owner check combined with explicit allowlist checking

Alternatively, if the assigned trigger is not actually needed for the Claude workflow functionality (since Claude is typically triggered by opening issues or commenting, not by assignment), remove it entirely.

Copilot uses AI. Check for mistakes.
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
) && (
github.event.sender.login == github.repository_owner ||
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check github.event.sender.login == github.repository_owner may not work as intended for organization-owned repositories. For repositories owned by an organization (like sensiblebit/certkit), github.repository_owner is the organization name (e.g., "sensiblebit"), not a user login. A user's login will never equal the organization name, so this check will always evaluate to false for organization repositories.

If the intent is to check if the sender is the repository owner (for user-owned repos) OR an organization member/owner (for org-owned repos), this check only handles the first case. For organization repositories, you should rely on the author_association checks (OWNER, MEMBER, COLLABORATOR) which correctly identify organization members and owners.

Consider removing this redundant check, or document that it's only for potential user-owned forks and has no effect on the main organization repository.

Suggested change
github.event.sender.login == github.repository_owner ||

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants