Skip to content

Conversation

@iaminawe
Copy link
Contributor

@iaminawe iaminawe commented Oct 24, 2025

Summary

This PR updates the Claude Code and OpenCode GPT-5 Codex workflows to automatically allow workflow execution for members of the liatrio-labs GitHub organization without requiring manual approval.

Changes

  • Added check-org-membership job to both workflows
  • Checks author_association first (OWNER, MEMBER, COLLABORATOR)
  • Falls back to checking liatrio-labs organization membership via GitHub API
  • Main workflow jobs now depend on authorization check passing

Benefits

✅ Existing collaborators continue to work without changes
✅ Any member of liatrio-labs organization can trigger workflows automatically
✅ Non-members and non-collaborators are still blocked
✅ No manual approval required for organization members

Implementation Details

The new check-org-membership job:

  1. Runs first and checks if the trigger event contains the appropriate command (@claude or /oc-codex)
  2. Extracts the actor and their author_association from the event
  3. If they are OWNER, MEMBER, or COLLABORATOR, authorizes immediately
  4. Otherwise, checks if the user is a member of liatrio-labs org using gh api "orgs/liatrio-labs/members/$ACTOR"
  5. Sets an output variable is-authorized that the main job depends on

Testing

To test this PR:

  1. Have an organization member (who is not a direct collaborator) comment with @claude or /oc-codex on an issue or PR
  2. Verify that the workflow runs automatically without requiring manual approval

Files Changed

  • .github/workflows/claude.yml
  • .github/workflows/opencode-gpt-5-codex.yml

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a reusable organization-membership authorization check that emits an "is-authorized" flag for workflows.
  • Chores
    • Workflows now run the authorization check first and gate downstream jobs on the "is-authorized" output.
    • Removed inline auth checks and consolidated authorization into the shared action.
    • One workflow's job permissions and runtime steps were expanded to support token-based and checkout operations for approved runs.

This commit updates the Claude Code and OpenCode GPT-5 Codex workflows to
automatically allow workflow execution for members of the liatrio-labs
GitHub organization without requiring manual approval.

Changes:
- Added check-org-membership job to both workflows
- Checks author_association first (OWNER, MEMBER, COLLABORATOR)
- Falls back to checking liatrio-labs organization membership via GitHub API
- Main workflow jobs now depend on authorization check passing

This ensures that:
1. Existing collaborators continue to work without changes
2. Any member of liatrio-labs organization can trigger workflows
3. Non-members and non-collaborators are still blocked

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 24, 2025

Walkthrough

Extracted inline authorization checks into a reusable check-org-membership job and composite action; claude and opencode jobs now depend on that job and run only when its is-authorized output is 'true'.

Changes

Cohort / File(s) Summary
New action: check-org-membership
\.github/actions/check-org-membership/action.yml``
Added a composite GitHub Action that computes AUTHOR_ASSOC from event inputs, allows immediate pass for OWNER/MEMBER/COLLABORATOR, falls back to gh api orgs/$ORGANIZATION/members/$ACTOR, and emits is-authorized output.
Workflow: claude gating
\.github/workflows/claude.yml``
Added check-org-membership job, made claude depend on it (needs) and gated it with if: needs.check-org-membership.outputs.is-authorized == 'true'; removed inline owner/membership checks.
Workflow: opencode gating & run
\.github/workflows/opencode-gpt-5-codex.yml``
Replaced inline gating with check-org-membership job, made opencode depend on it and gate via is-authorized; added id-token: write permission, preserved contents: read, and added checkout + opencode action steps.

Sequence Diagram(s)

sequenceDiagram
    participant Event as GitHub Event
    participant Action as check-org-membership (composite)
    participant Job as claude / opencode

    Event->>Action: workflow triggered (event payload + inputs)
    rect rgb(230,245,255)
    Action->>Action: derive AUTHOR_ASSOC from EVENT_NAME
    Action->>Action: if AUTHOR_ASSOC in (OWNER,MEMBER,COLLABORATOR) -> set is-authorized=true
    end
    alt AUTHOR_ASSOC not sufficient
        rect rgb(255,245,230)
        Action->>Action: call gh api orgs/$ORGANIZATION/members/$ACTOR
        Action->>Action: set is-authorized based on API result
        end
    end

    Action-->>Job: outputs.is-authorized
    alt is-authorized == 'true'
        Job->>Job: run job steps (checkout, run action)
    else
        Job--x Job: job skipped (gated)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus on:
    • .github/actions/check-org-membership/action.yml — correctness of event-to-author_association mapping and gh api usage.
    • Conditional wiring and outputs between check-org-membership job and claude / opencode workflows.
    • Permissions (id-token) and secrets usage in updated workflows.

Possibly related PRs

Suggested reviewers

  • jguice

Poem

🐇 I hop through workflows, nose to the breeze,
I check who you are with minimal sleaze.
A quick little query, a stamp and a wink,
Gates open gently — now go build and think! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "Enable automatic workflow approval for Liatrio Labs organization members" is fully aligned with the main change in the changeset. The title is concise and clearly summarizes the primary objective: allowing automatic workflow execution for members of the liatrio-labs organization. The changeset demonstrates this through the addition of a new check-org-membership job in both workflow files that gates the main workflow jobs on organization membership verification, directly implementing what the title describes.
Description Check ✅ Passed The PR description is mostly complete and covers the essential required template sections. The "Summary" section addresses the "Why?" requirement by explaining the motivation for automatic workflow approval for organization members. The "Changes" section covers the "What Changed?" requirement with a clear breakdown of the key updates including the new check-org-membership job, authorization logic, and job dependencies. While the description uses different section headers than the template and lacks an explicit "Additional Notes" section, it provides comprehensive implementation details, testing instructions, and benefits that add value and clarity. The description is well-organized, directly related to the PR objectives, and includes all critical information for understanding the changes.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch workflow-org-member-approval

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
.github/workflows/claude.yml (1)

14-69: Duplicated authorization logic across workflows.

The check-org-membership job in this file is identical to the one in .github/workflows/opencode-gpt-5-codex.yml, differing only in the trigger command (@claude vs /oc-codex). This duplication should be consolidated into a reusable action per the refactor suggestion in the opencode workflow review.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c56308 and fce9ad5.

📒 Files selected for processing (2)
  • .github/workflows/claude.yml (1 hunks)
  • .github/workflows/opencode-gpt-5-codex.yml (1 hunks)
🔇 Additional comments (1)
.github/workflows/claude.yml (1)

71-73: Job dependency and authorization gating are correctly implemented.

The claude job properly depends on check-org-membership and gates execution with the is-authorized output. The conditional at line 73 will correctly skip the job if authorization fails.

This addresses the CodeRabbit review feedback regarding GITHUB_TOKEN
permissions. The default GITHUB_TOKEN does not have org-level "Members"
read permission required to query organization membership.

Changes:
- Updated both workflows to use ORG_MEMBER_CHECK_TOKEN secret
- This token must be a PAT or GitHub App token with read:org scope

Setup Required:
A repository administrator must create and add the ORG_MEMBER_CHECK_TOKEN
secret with appropriate permissions. See PR description for instructions.

Fixes: Critical permission issue identified in CodeRabbit review

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
.github/workflows/opencode-gpt-5-codex.yml (1)

14-69: Add explicit permissions block to check-org-membership job.

Same as claude.yml: the job lacks an explicit permissions block. Add minimal permissions for consistency and auditability.

  check-org-membership:
    runs-on: ubuntu-latest
+   permissions:
+     contents: read
    if: |
🧹 Nitpick comments (1)
.github/workflows/claude.yml (1)

14-70: Add explicit permissions block to check-org-membership job.

The check-org-membership job lacks an explicit permissions block. While the job relies on secrets.ORG_MEMBER_CHECK_TOKEN for the API call, it's a security best practice to declare minimal permissions explicitly, even if they're not used by the job itself.

  check-org-membership:
    runs-on: ubuntu-latest
+   permissions:
+     contents: read
    if: |

This ensures the job's token scope is clearly auditable and adheres to the principle of least privilege.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fce9ad5 and 215cc73.

📒 Files selected for processing (2)
  • .github/workflows/claude.yml (1 hunks)
  • .github/workflows/opencode-gpt-5-codex.yml (1 hunks)
🔇 Additional comments (1)
.github/workflows/claude.yml (1)

38-69: I need to verify the technical claims in the review comment about GitHub Actions tokens and organization membership checks.

Now let me search for more details on the specific GitHub API endpoint for organization membership to understand the exact requirements:

Critical: Verify ORG_MEMBER_CHECK_TOKEN is properly scoped and the authorization check is functioning correctly.

GITHUB_TOKEN cannot be given organization-scoped permissions, and the code correctly uses a custom secret ORG_MEMBER_CHECK_TOKEN instead. However, the API endpoint requires a fine-grained token with "Members" organization permissions (read) to verify both public and private organization membership.

The security concern is valid: GH_TOKEN and GITHUB_TOKEN (in order of precedence) are authentication tokens, so the token's permissions determine success or failure. If ORG_MEMBER_CHECK_TOKEN is misconfigured or missing, the silent error suppression (--silent 2>/dev/null) will mask the failure, causing the job to set authorized=false for all non-author-association-privileged users.

To verify and fix:

  1. Confirm that secrets.ORG_MEMBER_CHECK_TOKEN exists in repository/organization settings with a PAT or GitHub App token granting "Members" read access to liatrio-labs.
  2. Test with an organization member to ensure they can trigger the workflow; check Actions logs for the authorization step.
  3. Consider removing 2>/dev/null temporarily to surface any permission errors during testing.
  4. Add explicit logging when the API call fails to help debug authorization issues.

This addresses the CodeRabbit refactoring suggestion to eliminate
duplicated authorization logic across workflows.

Changes:
- Created .github/actions/check-org-membership composite action
- Extracted 45+ lines of duplicated bash logic into single reusable action
- Action accepts trigger-command as input parameter
- Both workflows now use the same authorization logic
- Reduced maintenance burden and ensured consistency

Benefits:
- Single source of truth for authorization logic
- DRY principle compliance
- Future updates apply consistently across all workflows
- Easier to test and maintain

The composite action:
- Checks author_association first (OWNER, MEMBER, COLLABORATOR)
- Falls back to organization membership verification
- Returns is-authorized boolean output
- Supports all event types (issue_comment, pull_request_review, etc.)

Addresses: CodeRabbit refactoring suggestion

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
.github/workflows/opencode-gpt-5-codex.yml (1)

14-57: Add explicit permissions block to check-org-membership job.

The job lacks an explicit permissions block, which defaults to broad GITHUB_TOKEN permissions. Since this job only checks out the repository to access the composite action, it needs minimal permissions.

  check-org-membership:
    runs-on: ubuntu-latest
+   permissions:
+     contents: read
    if: |
🧹 Nitpick comments (1)
.github/actions/check-org-membership/action.yml (1)

1-98: Document required token scope in action description and repository setup instructions.

The action requires secrets.ORG_MEMBER_CHECK_TOKEN to have organization membership read permissions, but this requirement is not clearly communicated. If the token lacks the "Members" read permission, all org member checks silently fail.

Add an input description clarification or include setup documentation linking to the secret configuration requirements. For example:

  github-token:
    description: 'GitHub token with org membership read permissions'
+   description: |
+     GitHub token with organization membership read permissions. 
+     Required scopes: read:org_members or admin:org.
+     See: https://docs.github.com/en/rest/orgs/members
    required: true

Additionally, would you like me to generate a documented setup guide (e.g., .github/WORKFLOWS_SETUP.md) that explains how to configure ORG_MEMBER_CHECK_TOKEN with the correct permissions?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 215cc73 and 4c5cdc9.

📒 Files selected for processing (3)
  • .github/actions/check-org-membership/action.yml (1 hunks)
  • .github/workflows/claude.yml (1 hunks)
  • .github/workflows/opencode-gpt-5-codex.yml (1 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeQL
.github/workflows/claude.yml

[warning] 16-58: Workflow does not contain permissions
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

.github/workflows/opencode-gpt-5-codex.yml

[warning] 16-58: Workflow does not contain permissions
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

🔇 Additional comments (3)
.github/workflows/opencode-gpt-5-codex.yml (1)

58-79: Authorization gating and permissions look good.

The opencode job properly depends on check-org-membership and executes only when authorized. The permissions block correctly includes contents: read and id-token: write for the workflow's functionality.

.github/workflows/claude.yml (1)

58-94: Authorization gating and permissions look good.

The claude job properly depends on check-org-membership and executes only when authorized. The permissions block is comprehensive and appropriate for the Claude Code action's requirements.

.github/actions/check-org-membership/action.yml (1)

75-89: Event type dispatch and early authorization checks look sound.

The logic correctly maps each event type to its corresponding author association field (comment, review, or issue) and efficiently authorizes known-good users (OWNER, MEMBER, COLLABORATOR) without unnecessary API calls.

iaminawe and others added 3 commits October 24, 2025 12:34
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Added minimal 'contents: read' permission to check-org-membership jobs in both
claude.yml and opencode-gpt-5-codex.yml workflows. This follows security best
practices by explicitly limiting GITHUB_TOKEN permissions instead of relying
on broad defaults, adhering to the principle of least privilege.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@iaminawe iaminawe self-assigned this Oct 27, 2025
@iaminawe iaminawe requested a review from ryderstorm October 27, 2025 17:37
@iaminawe
Copy link
Contributor Author

@ryderstorm here is another one to review please - I noticed that the workflows on Grants contribution needed to be manually approved and its because the previous workflow was only working automatically if a person was added individually to the repo with specific permissions. This PR is an attempt to make these permissions broader so that any member of the Liatrio Labs organization will be able to use the @claude command

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
.github/actions/check-org-membership/action.yml (2)

5-7: Remove unused trigger-command input.

The input is defined and set as an environment variable but never used in the authorization script. This was likely carried over from earlier design but should be removed to avoid confusion.

Apply this diff:

inputs:
  trigger-command:
-   description: 'The trigger command to check for (e.g., @claude or /oc-codex)'
-   required: true
  github-token:
    description: 'GitHub token with org membership read permissions'
    required: true

And remove the unused environment variable:

      env:
        GH_TOKEN: ${{ inputs.github-token }}
-       TRIGGER_COMMAND: ${{ inputs.trigger-command }}
        EVENT_NAME: ${{ inputs.event-name }}

Also applies to: 63-63


91-97: Add error logging for organization membership API failures.

When the gh api call fails at line 92, the error output flows to the workflow logs (good—this addresses the prior error suppression issue). However, for better debugging when the token lacks proper permissions or the API endpoint is inaccessible, consider capturing and logging the error message.

Apply this diff to capture and log the error:

        # Check if user is a member of the organization
-       if gh api "orgs/$ORGANIZATION/members/$ACTOR"; then
+       if gh api "orgs/$ORGANIZATION/members/$ACTOR" >/dev/null 2>&1; then
          echo "User is authorized as $ORGANIZATION organization member"
          echo "authorized=true" >> "$GITHUB_OUTPUT"
        else
+         echo "Organization membership check failed for user $ACTOR in $ORGANIZATION" >&2
          echo "User is not authorized"
          echo "authorized=false" >> "$GITHUB_OUTPUT"
        fi

This preserves the existing behavior (denying on API failure) while making it clear why authorization was denied when troubleshooting token or permission issues.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c5cdc9 and 006097d.

📒 Files selected for processing (3)
  • .github/actions/check-org-membership/action.yml (1 hunks)
  • .github/workflows/claude.yml (1 hunks)
  • .github/workflows/opencode-gpt-5-codex.yml (1 hunks)

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