fix(wif): preserve GitHub canonical case in attributeCondition and IAM principals#3692
fix(wif): preserve GitHub canonical case in attributeCondition and IAM principals#3692waynesun09 wants to merge 2 commits into
Conversation
…M principals The WIF provisioner lowercased org/repo names before substituting them into CEL attributeCondition literals and IAM principalSet paths. Since GitHub's OIDC token preserves canonical case and Google STS compares claims byte-for-byte, any org/repo with uppercase letters permanently failed authentication with "unauthorized_client". Separate case-insensitive dedup (for internal bookkeeping, provider ID generation) from the values written into security-critical CEL conditions and IAM principal paths — those now preserve the original case. Fixes: #3678 Assisted-by: Claude Signed-off-by: Wayne Sun <gsun@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 5:23 PM UTC · Completed 5:38 PM UTC |
PR Summary by QodoFix WIF: preserve GitHub canonical case in CEL conditions and IAM principals
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Site previewPreview: https://5b5138cf-site.fullsend-ai.workers.dev Commit: |
Code Review by Qodo
Context used✅ Tickets:
🎫 WIF attributeCondition forces lowercase org/repo, rejecting auth for mixed-case GitHub orgs✅ Compliance rules (platform):
54 rules✅ Skills:
writing-user-docs, writing-adrs 1. EnsureOrg flips existing case
|
ReviewOutcome: Approve Re-review: Head advanced from SummaryThis PR fixes a genuine authentication bug (#3678) where the WIF provisioner lowercased org/repo names before substituting them into CEL The fix correctly separates two concerns:
Incremental ChangeThe new commit ( Reviewed Dimensions
Test AssessmentThe prior review's low finding has been fully addressed. Test coverage now includes: case preservation for org-scoped and repo-scoped provisioning, case-insensitive merge dedup, case-insensitive removal, provider ID lowering, and the re-enrollment precedence scenario. The test suite exercises the critical invariants that the provider ID remains lowered (GCP requirement) while CEL conditions and IAM bindings preserve canonical case (GitHub OIDC requirement). Previous runReviewOutcome: Approve SummaryThis PR fixes a genuine authentication bug (#3678) where the WIF provisioner lowercased org/repo names before substituting them into CEL The fix correctly separates two concerns:
Reviewed Dimensions
Findings[low] Merge precedence during re-enrollment could cause condition case change — In Test AssessmentTest coverage is strong: 7 tests updated or added covering case preservation for org-scoped, repo-scoped, merge dedup, case-insensitive removal, and provider ID lowering. The test Labels: PR modifies WIF provisioning in the dispatch component |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Add TestEnsureOrgInWIFCondition_ReEnrollmentInstallingCaseWins covering the case where an org re-enrolls with different casing than the existing WIF condition — verifies the installing org's case replaces the existing one, per review feedback on #3692. Signed-off-by: Wayne Sun <gsun@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 7:50 PM UTC · Completed 7:57 PM UTC |
Summary
Fixes #3678 — WIF
attributeConditionforces lowercase org/repo, rejecting auth for mixed-case GitHub orgs.The WIF provisioner lowercased org/repo names before substituting them into CEL
attributeConditionliterals and IAMprincipalSetpaths. Since GitHub's OIDC token preserves canonical case and Google STS compares claims byte-for-byte, any org/repo with uppercase letters (e.g.RHEcosystemAppEng/sdlc-plugins) permanently failed authentication withunauthorized_client: The given credential is rejected by the attribute condition.Changes
parseConditionOrgs— preserves case from existing CEL conditions instead of lowercasingensureWIFPoolAndProvider— case-insensitive dedup using lowered map keys, preserving canonical-case values; installing orgs take precedence when casing differsProvisionWIFrepo path — split intoparts(original case for CEL/IAM) andpartsLower(forBuildRepoProviderIDand validation)ProvisionWIForg path — preserves original case inorgsslice while deduping case-insensitivelyEnsureOrgInWIFCondition— case-insensitive dedup preserving canonical caseRemoveOrgFromWIFCondition— usesstrings.EqualFoldfor case-insensitive matchingstrings.ToLowersinceattribute.repositorymaps directly from the assertion without normalizationProvision— stopped mutatingp.cfg.GitHubOrgsentries to lowercaseWhat stays lowered (correct behavior)
BuildRepoProviderID— GCP resource IDs require lowercaseEnsureOrgInMint/RegisterPerRepoWIF— env var bookkeeping (ALLOWED_ORGS,PER_REPO_WIF_REPOS)RemoveOrgFromMint/RemoveRepoFromMint— env var bookkeepingTest plan
TestProvisionWIF_PreservesOrgCase— condition preserves original caseTestProvisionWIF_RepoScoped_PreservesRepoCase— condition and IAM binding preserve case, provider ID still loweredTestParseConditionOrgs— mixed case preserved in parsed outputTestEnsureOrgInWIFCondition_AddsOrgAndStripsPlaceholder— preserves caseTestProvisionWIF_OrgScoped_PreservesOrgCase— mixed-case org in condition and IAMTestProvisionWIF_OrgScoped_MergeDedupsCase— installing org case wins on mergeTestRemoveOrgFromWIFCondition_CaseInsensitiveMatch— removes by case-insensitive matchgo test ./internal/dispatch/gcf/passesgo vetclean