fix: use collaborator check and CLA_ACCESS_TOKEN for membership verification#3
Conversation
…ication - Add repository collaborator check using GITHUB_TOKEN (works for repo collaborators) - Fallback to org membership check using CLA_ACCESS_TOKEN (has org:read scope) - This fixes the issue where GITHUB_TOKEN couldn't verify org membership The previous implementation used GITHUB_TOKEN to check org membership, but the default GITHUB_TOKEN doesn't have read:org scope, so the API returned 404 for actual org members. This caused the CLA assistant to incorrectly request CLA signatures from exempt users. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
- Validate CLA_ACCESS_TOKEN is not empty before using it - Add proper error handling for different API responses: - 204: User is an org member (exempt) - 404/302: User is not a member (requires CLA) - Other: API error, fail open and require CLA as precaution - Add warning messages for missing token or API errors Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a critical issue in the CLA workflow where organization members were incorrectly required to sign the CLA. The root cause was that the standard GITHUB_TOKEN lacks the read:org scope needed to verify organization membership via the /orgs/knitli/members/{user} API, causing it to return 404 even for valid members.
Key Changes:
- Implements a two-tier verification approach: first checking repository collaborator status (using
GITHUB_TOKEN), then falling back to org membership (usingCLA_ACCESS_TOKENwithorg:readscope) - Adds the
CLA_ACCESS_TOKENenvironment variable to enable org membership verification with proper permissions - Improves error handling for different API response scenarios (204/404/302/errors)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Query org membership API | ||
| response=$(curl -s -o /dev/null -w "%{http_code}" \ | ||
| # Check if user is a repository collaborator (works with GITHUB_TOKEN) | ||
| # This API returns 204 if user has push access, 404 otherwise |
There was a problem hiding this comment.
The comment states "This API returns 204 if user has push access, 404 otherwise", but the GitHub collaborators API actually returns 204 if the user has any collaborator permission (read, write, or admin), not just push/write access. Consider updating the comment to: "This API returns 204 if user is a collaborator (read/write/admin), 404 otherwise"
| # This API returns 204 if user has push access, 404 otherwise | |
| # This API returns 204 if user is a collaborator (read/write/admin), 404 otherwise |
| elif [ "$org_response" == "404" ] || [ "$org_response" == "302" ]; then | ||
| # 404 = not a member, 302 = requester is not an org member (can't see membership) | ||
| echo "User $user is NOT a collaborator or org member and may require CLA" | ||
| NEEDS_CLA+=("$user") | ||
| else | ||
| # API error (rate limit, network issue, etc.) - fail open and require CLA |
There was a problem hiding this comment.
The 302 status code typically indicates a redirect and often suggests an authentication issue rather than a definitive "not a member" response. Treating 302 the same as 404 might incorrectly categorize authentication failures as "not a member". Consider treating 302 as an error case (moving it to the else block on line 179) to fail securely when authentication issues occur: elif [ "$org_response" == "404" ]; then
| elif [ "$org_response" == "404" ] || [ "$org_response" == "302" ]; then | |
| # 404 = not a member, 302 = requester is not an org member (can't see membership) | |
| echo "User $user is NOT a collaborator or org member and may require CLA" | |
| NEEDS_CLA+=("$user") | |
| else | |
| # API error (rate limit, network issue, etc.) - fail open and require CLA | |
| elif [ "$org_response" == "404" ]; then | |
| # 404 = not a member | |
| echo "User $user is NOT a collaborator or org member and may require CLA" | |
| NEEDS_CLA+=("$user") | |
| else | |
| # API error (rate limit, network issue, 302 redirect, etc.) - fail open and require CLA |
| EXEMPT_USERS+=("$user (org member)") | ||
| continue | ||
| elif [ "$org_response" == "404" ] || [ "$org_response" == "302" ]; then | ||
| # 404 = not a member, 302 = requester is not an org member (can't see membership) |
There was a problem hiding this comment.
This comment should be updated to clarify that 302 indicates an authentication/redirect issue rather than membership visibility. If the logic is changed to treat 302 as an error case, update to: # 404 = not a member or membership is concealed
| # 404 = not a member, 302 = requester is not an org member (can't see membership) | |
| # 404 = not a member or membership is concealed, 302 = authentication/redirect issue (requester is not an org member, cannot see membership) |
The CLA workflow incorrectly required org members to sign the CLA because
GITHUB_TOKENlacksread:orgscope, causing the/orgs/knitli/members/{user}API to return 404 for valid members.Changes
/repos/{owner}/{repo}/collaborators/{user}withGITHUB_TOKEN(works for repo-level permissions)CLA_ACCESS_TOKEN(hasorg:readscope) for the org membership APIBefore
After
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.