CNTRLPLANE-2550: Add support for CEL expression claim mappings for username and groups#2719
CNTRLPLANE-2550: Add support for CEL expression claim mappings for username and groups#2719ShazaAldawamneh wants to merge 7 commits intoopenshift:masterfrom
Conversation
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
|
Pipeline controller notification For optional jobs, comment This repository is configured in: LGTM mode |
|
@ShazaAldawamneh: This pull request references CNTRLPLANE-2550 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
Hello @ShazaAldawamneh! Some important instructions when contributing to openshift/api: |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
📝 WalkthroughWalkthroughOptional 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.5.0)Error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml (1)
189-218:⚠️ Potential issue | 🟠 MajorGroups: required
claimblocks CEL-only mapping.
claimis still required while claim+expression is forbidden, soexpressioncan’t be used alone. If CEL mapping is intended here, drop the unconditional requirement and enforce a one‑of rule.Suggested fix
- required: - - claim type: object x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) ? !has(self.expression) : has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml` around lines 189 - 218, The schema currently mandates claim in the required list while also forbidding claim+expression via x-kubernetes-validations, which prevents using expression alone; update the CRD so that claim is not unconditionally required and replace the required: - claim rule with a oneOf (or an equivalent x-kubernetes-validation) that enforces either claim is set XOR expression is set (e.g., a oneOf referencing presence of self.claim or self.expression) and keep the existing mutually-exclusive validation (x-kubernetes-validations rule: '!(has(self.claim) && has(self.expression))') to ensure only one is provided; modify the block around the claim/expression/prefix properties and the required/type definitions to reflect this change.payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml (1)
189-218:⚠️ Potential issue | 🟠 MajorGroups: required
claimblocks CEL-only mapping.
claimis still required while claim+expression is forbidden, soexpressioncan’t be used alone. If CEL mapping is intended here, drop the unconditional requirement and enforce a one‑of rule.Suggested fix
- required: - - claim type: object x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) ? !has(self.expression) : has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml` around lines 189 - 218, Remove the unconditional required: - claim for the mapping object and instead enforce mutual exclusivity and presence by adding a oneOf that requires either claim or expression; specifically, replace the top-level required: [claim] with a oneOf containing two subschemas (one with required: [claim], the other with required: [expression]) so that exactly one is provided, keep the existing x-kubernetes-validations rule or remove it (it becomes redundant) and leave prefix as-is; this targets the schema that defines claim, expression and prefix so look for the object containing those properties and update its required/oneOf accordingly.payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml (1)
189-218:⚠️ Potential issue | 🟠 MajorGroups: required
claimblocks CEL-only mapping.
claimis still required while claim+expression is forbidden, soexpressioncan’t be used alone. If CEL mapping is intended here, drop the unconditional requirement and enforce a one‑of rule.Suggested fix
- required: - - claim type: object x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) ? !has(self.expression) : has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml` around lines 189 - 218, Remove the unconditional required: - claim and instead enforce a mutual-exclusion plus presence rule so CEL-only mapping is possible; keep the existing x-kubernetes-validations rule that forbids both claim and expression (rule: '!(has(self.claim) && has(self.expression))') and add a second validation that requires at least one be set (e.g. message: 'either claim or expression must be set' with rule: '(has(self.claim) || has(self.expression))'), referencing the same object schema containing the claim and expression fields so either can be used alone.
🧹 Nitpick comments (1)
config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml (1)
459-553: Add a negative test forprefixPolicy: Prefixwith expression-only username mapping.There’s new validation requiring
claimwhenprefixPolicyisPrefix. A targeted test here will lock in that behavior for the feature gate.🧪 Suggested test case (adjust expectedError to match validator message)
- name: Cannot set both claim and expression for username mapping initial: | apiVersion: config.openshift.io/v1 kind: Authentication spec: type: OIDC oidcProviders: - name: myoidc issuer: issuerURL: https://meh.tld audiences: ['openshift-aud'] claimMappings: username: claim: "preferred_username" expression: "claims.sub" expectedError: "claim must not be set when expression is provided" + - name: Cannot set prefixPolicy Prefix with username expression + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + expression: "claims.sub" + prefixPolicy: Prefix + prefix: + prefixString: "myoidc:" + expectedError: "claim must be set when prefixPolicy is 'Prefix'"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml` around lines 459 - 553, Add a negative test case that validates the new rule requiring a literal claim when prefixPolicy is set to Prefix: create a YAML test similar to the existing cases but set claimMappings.username.expression (e.g. expression: "has(claims.upn) ? claims.upn : claims.oid") and set prefixPolicy: Prefix in the provider spec, and assert an expectedError like "claim must be provided when prefixPolicy is Prefix" (adjust text to match validator). Place it alongside the other OIDC tests referencing prefixPolicy, Prefix, and claimMappings.username.expression so the validator for prefixPolicy + expression-only username mapping is exercised.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (10)
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDC.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**openapi/generated_openapi/zz_generated.openapi.gois excluded by!openapi/**openapi/openapi.jsonis excluded by!openapi/**
📒 Files selected for processing (8)
config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yamlconfig/v1/types_authentication.goconfig/v1/zz_generated.swagger_doc_generated.gopayload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@config/v1/types_authentication.go`:
- Around line 352-371: The TokenClaimMapping struct currently makes Claim
required which, combined with the mutual-exclusion rule, prevents Expression
from ever being set; change Claim to optional and make the XNOR rule into an
XOR. Remove the +required annotation and change the JSON tag for Claim to
include omitempty (e.g., json:"claim,omitempty"), and update the
openshift:validation rule to an XOR such as rule="has(self.claim) !=
has(self.expression)" so exactly one of Claim or Expression can be provided
(keep Expression's existing omitempty and feature-gate annotations).
- Around line 605-635: Remove the unconditional field-level XValidation on the
Claim field (delete the
+kubebuilder:validation:XValidation:rule="has(self.claim)" annotation) and
instead enforce exclusive-or at the struct level when the feature gate is
enabled: update the existing FeatureGateAwareXValidation (on type
UsernameClaimMapping) to a rule that requires exactly one of claim or expression
when ExternalOIDCWithUpstreamParity is enabled (e.g. rule="has(self.claim) !=
has(self.expression)" with an appropriate message). Keep the MinLength/MaxLength
tags on Claim and Expression but do not require Claim unconditionally.
In `@config/v1/zz_generated.swagger_doc_generated.go`:
- Around line 468-471: The swagger doc for TokenClaimMapping
(map_TokenClaimMapping) incorrectly marks "claim" as required despite supporting
expression-only mappings; update the source Go type comment for
TokenClaimMapping to indicate that "claim" is optional and that "claim" and
"expression" are mutually exclusive (describe that either claim or expression
may be provided, not both), then re-run the swagger generation script to
regenerate zz_generated.swagger_doc_generated.go so the map_TokenClaimMapping
entry reflects the optional claim and mutual exclusion with expression.
- Around line 549-552: The Swagger comment for UsernameClaimMapping (seen in
map_UsernameClaimMapping) is missing the new validation rules: add documentation
that expression has a max length (match the enforced length), and that when
prefixPolicy is "Prefix" the claim field is required and claim itself has a
non-empty/<=256 char constraint; update the source struct/type comment for
UsernameClaimMapping (the comment above its Go type or fields: claim,
expression, prefixPolicy, prefix) to include these sentences and regenerate the
swagger docs so the generated map_UsernameClaimMapping includes the new length
and dependency text.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml`:
- Around line 267-293: The property-level validation on the claim field (the
x-kubernetes-validations entry with message "claim must be set") makes
expression-only configs impossible; remove that per-property required validation
from the claim schema and instead enforce mutual exclusivity/requirement at the
object level with a oneOf/anyOf rule that requires exactly one of claim or
expression (reference the schema object that contains the claim and expression
properties and the expression property itself); apply the same change to the
duplicate block mentioned (the other claim/expression pair).
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml`:
- Around line 267-293: The property-level validation on the 'claim' field (the
x-kubernetes-validations rule with message "claim must be set") makes
'expression' unusable; remove that field-level requirement and replace it with a
single object-level validation that enforces exactly one of 'claim' or
'expression' (e.g., a oneOf / CEL rule at the parent object) so configs can
specify either claim-only or expression-only but not both; update the schema
entries that reference 'claim' and 'expression' (the two sibling properties
shown) to drop the has(self.claim) rule and add the new object-level one-of
validation.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`:
- Around line 267-293: The current property-level x-kubernetes-validations on
claim ("claim must be set") forces claim and prevents expression-only configs;
remove the claim-level "must be set" validation and instead add an object-level
x-kubernetes-validations rule that enforces exactly one of claim or expression
is present (e.g., use a CEL rule like (has(self.claim) + has(self.expression))
== 1 with an appropriate message), and apply the same change for the duplicate
block that appears later for the other mapping. Ensure the claim and expression
property schemas keep their type, minLength and maxLength constraints but no
longer require claim alone.
---
Outside diff comments:
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml`:
- Around line 189-218: Remove the unconditional required: - claim for the
mapping object and instead enforce mutual exclusivity and presence by adding a
oneOf that requires either claim or expression; specifically, replace the
top-level required: [claim] with a oneOf containing two subschemas (one with
required: [claim], the other with required: [expression]) so that exactly one is
provided, keep the existing x-kubernetes-validations rule or remove it (it
becomes redundant) and leave prefix as-is; this targets the schema that defines
claim, expression and prefix so look for the object containing those properties
and update its required/oneOf accordingly.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml`:
- Around line 189-218: The schema currently mandates claim in the required list
while also forbidding claim+expression via x-kubernetes-validations, which
prevents using expression alone; update the CRD so that claim is not
unconditionally required and replace the required: - claim rule with a oneOf (or
an equivalent x-kubernetes-validation) that enforces either claim is set XOR
expression is set (e.g., a oneOf referencing presence of self.claim or
self.expression) and keep the existing mutually-exclusive validation
(x-kubernetes-validations rule: '!(has(self.claim) && has(self.expression))') to
ensure only one is provided; modify the block around the claim/expression/prefix
properties and the required/type definitions to reflect this change.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`:
- Around line 189-218: Remove the unconditional required: - claim and instead
enforce a mutual-exclusion plus presence rule so CEL-only mapping is possible;
keep the existing x-kubernetes-validations rule that forbids both claim and
expression (rule: '!(has(self.claim) && has(self.expression))') and add a second
validation that requires at least one be set (e.g. message: 'either claim or
expression must be set' with rule: '(has(self.claim) || has(self.expression))'),
referencing the same object schema containing the claim and expression fields so
either can be used alone.
---
Nitpick comments:
In
`@config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml`:
- Around line 459-553: Add a negative test case that validates the new rule
requiring a literal claim when prefixPolicy is set to Prefix: create a YAML test
similar to the existing cases but set claimMappings.username.expression (e.g.
expression: "has(claims.upn) ? claims.upn : claims.oid") and set prefixPolicy:
Prefix in the provider spec, and assert an expectedError like "claim must be
provided when prefixPolicy is Prefix" (adjust text to match validator). Place it
alongside the other OIDC tests referencing prefixPolicy, Prefix, and
claimMappings.username.expression so the validator for prefixPolicy +
expression-only username mapping is exercised.
payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml
Show resolved
Hide resolved
payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml
Show resolved
Hide resolved
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
There was a problem hiding this comment.
I don't know if it will help resolve the error, but it might not be a bad idea to check if self.claim exists.
Maybe we could try this rule:
!(size(self.claim) > 0 && size(self.expression) > 0) instead of !(has(self.claim) && has(self.expression))
It seems to follow how other optional strings are checked.
config/v1/types_authentication.go
Outdated
| // +kubebuilder:validation:MinLength=1 | ||
| // +kubebuilder:validation:MaxLength=256 |
There was a problem hiding this comment.
If we are going to add this constraint, we need to make sure we add ratcheting tests like
api/example/v1/tests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml
Lines 902 to 964 in de86ee3
This is to test the scenarios where a user may have already configured this with a value that does not satisfy these new constraints.
There was a problem hiding this comment.
for these ratcheting tests, should we add them in /RedHat/api/config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml? Also, I’m wondering why we need to add them here if similar tests already exist in the API repo — wouldn’t those run by default?
There was a problem hiding this comment.
config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml
They would need to be made in all ExternalOIDC related test files.
Also, I’m wondering why we need to add them here if similar tests already exist in the API repo — wouldn’t those run by default?
The existing ones don't automatically test ratcheting behavior of every changed field. When we ratchet the validations of existing fields we need to add new tests here.
There was a problem hiding this comment.
Thanks for the clarification on the ratcheting tests, that makes sense.
I have another question regarding the MinLength=1 and MaxLength=256 validations. I looked through the existing ExternalOIDC-related test files, and I don’t see any tests that explicitly cover these constraints, even though we’ve had similar validations on other fields before.
Are these length validations being added now for a specific reason? Or are they already enforced/tested in another way that I may have missed?
I just want to make sure I fully understand whether these are new constraints that require additional ratcheting tests, or if there’s existing coverage that I’m not recognizing.
There was a problem hiding this comment.
Are these length validations being added now for a specific reason?
You are the one adding them, so you tell me :).
In general, we strongly encourage the use of minimum and maximum lengths for fields to ensure users are supplying a reasonably valid input. For example, it is highly unlikely that a token has a claim that is more than a certain length because token claim keys are meant to be short due to a limited amount of space available in request headers.
I looked through the existing ExternalOIDC-related test files, and I don’t see any tests that explicitly cover these constraints, even though we’ve had similar validations on other fields before.
In general, we don't enforce a requirement that minimum and maximum length constraints are tested because that is standard OpenAPI schema behavior that we can reasonable assume to be stable. This is a more unique case where a field that has been shipped as GA is having the constraints tightened on what inputs are allowed. In these cases, we want to test these kinds of changes to ensure that they ratchet correctly - regardless of the kind of constraint that is added.
For example, when tightening the validations of a couple of the existing fields (like username.claim) I did this:
api/config/v1/tests/authentications.config.openshift.io/ExternalOIDC.yaml
Lines 452 to 932 in 8713f3f
I just want to make sure I fully understand whether these are new constraints that require additional ratcheting tests, or if there’s existing coverage that I’m not recognizing.
Yes, this PR is adding net-new constraints to this field that would require ratcheting tests. Alternatively, if you feel that we should not be adding these constraints you could remove them.
That being said, I do feel like the addition of a maximum length constraint here is reasonable.
There was a problem hiding this comment.
You are the one adding them, so you tell me :).
oh no I didn't meant the validations themselves but their ratchet tests that you're asking me to add, things are clear now anyway thanks!
That being said, I do feel like the addition of a maximum length constraint here is reasonable.
your POV does make sense to me, I will go ahead and implement tests to cover the max length validations
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml (1)
267-337:⚠️ Potential issue | 🟠 MajorUsername mapping validation allows empty object when it requires exactly one of claim or expression
The current validation rule
!(has(self.claim) && has(self.expression))only prevents both fields from being set simultaneously, but allows neither field to be set (empty object{}). This contradicts the description which states "precisely one of claim or expression must be set if the ExternalOIDCWithUpstreamParity feature gate is enabled."Additionally, the similar
uidfield above uses the stricter rulehas(self.claim) ? !has(self.expression) : has(self.expression)which correctly enforces exactly one field must be set. Theusernamefield should use the same validation logic.Suggested fix
- - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) != has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml` around lines 267 - 337, The username mapping x-kubernetes-validation currently only forbids both claim and expression being set (rule '!(has(self.claim) && has(self.expression))') but allows neither; change the validation to require exactly one of them (mirror the uid rule) by replacing the rule with logic like "has(self.claim) ? !has(self.expression) : has(self.expression)" so the username mapping (fields claim and expression) enforces precisely one is present when ExternalOIDCWithUpstreamParity applies.payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml (1)
267-337:⚠️ Potential issue | 🟠 MajorUsername mapping allows empty config
The current validation rule
!(has(self.claim) && has(self.expression))only forbids both fields being set, allowing an empty{}object to pass despite the description requiring precisely one field to be set.Suggested fix
- - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) != has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml` around lines 267 - 337, The validation currently only forbids both claim and expression being set (x-kubernetes-validations rule '!(has(self.claim) && has(self.expression))'), which still allows neither to be set; change the validation to require exactly one be present by replacing the rule with 'has(self.claim) != has(self.expression)' (or an equivalent XOR) and update the message to reflect "exactly one of claim or expression must be set"; target the x-kubernetes-validations entry that references claim and expression to make this change.
♻️ Duplicate comments (4)
payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml (1)
189-218:⚠️ Potential issue | 🟠 MajorGroups mapping:
claimis still required, soexpressioncan’t be used
required: [claim]plus “cannot both be set” means expression-only configs are invalid even when ExternalOIDCWithUpstreamParity is enabled. That conflicts with the intended expression support.💡 Suggested fix
- required: - - claim type: object x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) != has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml` around lines 189 - 218, The CRD currently forces claim to be mandatory by listing it under required, which prevents expression-only mappings; remove the required: - claim entry (i.e., delete the required array or at least remove "claim" from it) so that the existing x-kubernetes-validations rule ('!(has(self.claim) && has(self.expression))') can still prevent both being set while allowing expression-only configs; update the schema section containing the claim, expression, prefix, required, and x-kubernetes-validations entries accordingly.payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml (1)
189-218:⚠️ Potential issue | 🟠 MajorGroups mapping still requires
claim, soexpressioncan’t be used
required: [claim]plus “cannot both be set” blocks expression-only configs even when enabled.💡 Suggested fix
- required: - - claim type: object x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) != has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml` around lines 189 - 218, The schema currently forces claim via required: [claim], which prevents expression-only mappings; remove the unconditional required: - claim and instead enforce presence rules via x-kubernetes-validations: keep the mutual exclusion validation (rule: '!(has(self.claim) && has(self.expression))') and add a new validation requiring at least one be present (e.g. message: "either claim or expression must be set", rule: 'has(self.claim) || has(self.expression)'). Update the object definition around claim/expression/prefix to drop the required entry and rely on those two validations to allow expression-only configs.payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml (2)
213-218:⚠️ Potential issue | 🟠 Major
expressionfor groups remains unreachable —required: [claim]was not removed.The
required: - claimconstraint (line 214) forcesclaimto always be present. The mutual-exclusion rule!(has(self.claim) && has(self.expression))then preventsexpressionfrom ever being set simultaneously, making the newly-addedexpressionfield permanently unusable. The PR objective states "Applied the same optional/validation behavior to PrefixedClaimMapping for groups," but therequired: - claimwas not removed the way it was forusername. The fix should mirror theuidmapping (lines 257–260): removeclaimfromrequiredand replace the mutual-exclusion rule with a "precisely one" rule.🔧 Proposed fix
- required: - - claim type: object x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) ? !has(self.expression) : has(self.expression)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml` around lines 213 - 218, Remove the mandatory "claim" requirement from the groups PrefixedClaimMapping and change its validation to require exactly one of claim or expression; specifically, delete the required: - claim entry and replace the x-kubernetes-validations mutual-exclusion rule ('!(has(self.claim) && has(self.expression))') with a "precisely one" rule such as 'count([has(self.claim), has(self.expression)]) == 1' (apply this change to the PrefixedClaimMapping for groups where fields "claim" and "expression" are defined).
335-337:⚠️ Potential issue | 🟠 MajorUsername validation rule allows neither
claimnorexpression— violates "precisely one" contract.The rule
!(has(self.claim) && has(self.expression))only blocks having both fields simultaneously. It does not enforce that at least one is present. The field descriptions (lines 271–272 and 286–287) explicitly state:"Precisely one of claim or expression must be set if the ExternalOIDCWithUpstreamParity feature gate is enabled."
Since this is the
DevPreviewNoUpgradeCRD (with that gate active), an object with neitherclaimnorexpressionpasses validation today. Theuidmapping (lines 257–260) uses the correct "exactly one" rule — username should match it.🔧 Proposed fix
x-kubernetes-validations: - - message: claim and expression cannot both be set - rule: '!(has(self.claim) && has(self.expression))' + - message: precisely one of claim or expression must be set + rule: 'has(self.claim) ? !has(self.expression) : has(self.expression)' - message: prefix must be set if prefixPolicy is 'Prefix',🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml` around lines 335 - 337, The x-kubernetes-validations rule for username currently only forbids both fields via '!(has(self.claim) && has(self.expression))' so it permits neither; update the validation to enforce exactly-one semantics by replacing the rule with an expression that requires XOR between self.claim and self.expression (i.e., has(self.claim) != has(self.expression)) or an equivalent "one and only one" boolean expression, keeping the message consistent, and mirror the same exact-one logic already used for the uid mapping to ensure the username validation enforces precisely one of claim or expression.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@config/v1/types_authentication.go`:
- Around line 609-637: The UsernameClaimMapping validation has inverted CEL
rules and malformed kubebuilder markers: update the FeatureGateAwareXValidation
CEL expressions on the UsernameClaimMapping type so the rules require presence
(change rule="!has(self.claim)" to rule="has(self.claim)" for the claim-required
case and change rule="!has(self.claim) && !has(self.expression)" to
rule="has(self.claim) || has(self.expression)" for the claim-or-expression
case), and fix the kubebuilder markers on the Claim and Expression fields by
replacing MinLength:=1 with MinLength=1 (keep MaxLength values unchanged) so
Claim and Expression enforce non-empty lengths as intended.
- Around line 352-374: The feature-gate CEL annotations on TokenClaimMapping are
inverted and Claim lacks omitempty; update the annotations and JSON tag: in the
struct TokenClaimMapping change the first FeatureGateAwareXValidation rule to
require the claim when that gate is active (use rule="has(self.claim)" with the
same message), change the ExternalOIDCWithUpstreamParity rule to require at
least one of claim or expression (use rule="has(self.claim) ||
has(self.expression)", message="claim or expression must be specified"), and add
`omitempty` to the Claim json tag (change `Claim string `json:"claim"` to `Claim
string `json:"claim,omitempty"` ) so Go clients do not serialize empty claims.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml`:
- Around line 269-270: Fix the grammatical error in the CRD description text by
changing "a optional field" to "an optional field" in the description string
found in the CRD manifest (the authentications-DevPreviewNoUpgrade CRD content
where the sentence reads 'claim is a optional field that configures the JWT
token claim...'); update that description line in the YAML so it reads "claim is
an optional field that configures the JWT token claim whose value is assigned to
the cluster identity field associated with this mapping."
---
Outside diff comments:
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml`:
- Around line 267-337: The validation currently only forbids both claim and
expression being set (x-kubernetes-validations rule '!(has(self.claim) &&
has(self.expression))'), which still allows neither to be set; change the
validation to require exactly one be present by replacing the rule with
'has(self.claim) != has(self.expression)' (or an equivalent XOR) and update the
message to reflect "exactly one of claim or expression must be set"; target the
x-kubernetes-validations entry that references claim and expression to make this
change.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`:
- Around line 267-337: The username mapping x-kubernetes-validation currently
only forbids both claim and expression being set (rule '!(has(self.claim) &&
has(self.expression))') but allows neither; change the validation to require
exactly one of them (mirror the uid rule) by replacing the rule with logic like
"has(self.claim) ? !has(self.expression) : has(self.expression)" so the username
mapping (fields claim and expression) enforces precisely one is present when
ExternalOIDCWithUpstreamParity applies.
---
Duplicate comments:
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml`:
- Around line 189-218: The schema currently forces claim via required: [claim],
which prevents expression-only mappings; remove the unconditional required: -
claim and instead enforce presence rules via x-kubernetes-validations: keep the
mutual exclusion validation (rule: '!(has(self.claim) && has(self.expression))')
and add a new validation requiring at least one be present (e.g. message:
"either claim or expression must be set", rule: 'has(self.claim) ||
has(self.expression)'). Update the object definition around
claim/expression/prefix to drop the required entry and rely on those two
validations to allow expression-only configs.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml`:
- Around line 213-218: Remove the mandatory "claim" requirement from the groups
PrefixedClaimMapping and change its validation to require exactly one of claim
or expression; specifically, delete the required: - claim entry and replace the
x-kubernetes-validations mutual-exclusion rule ('!(has(self.claim) &&
has(self.expression))') with a "precisely one" rule such as
'count([has(self.claim), has(self.expression)]) == 1' (apply this change to the
PrefixedClaimMapping for groups where fields "claim" and "expression" are
defined).
- Around line 335-337: The x-kubernetes-validations rule for username currently
only forbids both fields via '!(has(self.claim) && has(self.expression))' so it
permits neither; update the validation to enforce exactly-one semantics by
replacing the rule with an expression that requires XOR between self.claim and
self.expression (i.e., has(self.claim) != has(self.expression)) or an equivalent
"one and only one" boolean expression, keeping the message consistent, and
mirror the same exact-one logic already used for the uid mapping to ensure the
username validation enforces precisely one of claim or expression.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`:
- Around line 189-218: The CRD currently forces claim to be mandatory by listing
it under required, which prevents expression-only mappings; remove the required:
- claim entry (i.e., delete the required array or at least remove "claim" from
it) so that the existing x-kubernetes-validations rule ('!(has(self.claim) &&
has(self.expression))') can still prevent both being set while allowing
expression-only configs; update the schema section containing the claim,
expression, prefix, required, and x-kubernetes-validations entries accordingly.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (8)
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDC.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (7)
config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yamlconfig/v1/types_authentication.gopayload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
- config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml
payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml
Show resolved
Hide resolved
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
config/v1/types_authentication.go (2)
610-612:⚠️ Potential issue | 🔴 CriticalSame inverted
!has(self.claim)rules onUsernameClaimMapping— these block all valid configurations.Identical root cause as
TokenClaimMappinglines 353–355: every valid object that suppliesclaimwill fail validation; every object missingclaimwill pass. This makes theclaimfield effectively unusable for non-parity feature sets.🐛 Proposed fix
-// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="!has(self.claim)",message="claim is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="!has(self.claim)",message="claim is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="!has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="has(self.claim)",message="claim is required"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/types_authentication.go` around lines 610 - 612, The validation tags on UsernameClaimMapping are inverted (they use !has(self.claim)) and therefore accept objects missing claim and reject valid ones; update the three FeatureGateAwareXValidation rules for UsernameClaimMapping to use has(self.claim) (not !has(self.claim)) so the presence of claim is required under the same feature gates as TokenClaimMapping (mirror the behavior of the rules at TokenClaimMapping lines ~353–355) and keep the same messages and featureGate values.
623-623:⚠️ Potential issue | 🟠 MajorFix malformed kubebuilder marker on line 623 — change
MaxLength:=256toMaxLength=256.The
:=syntax is not recognized by controller-gen and the constraint will be silently dropped. Anonymous kubebuilder markers use=as the delimiter (e.g.,+kubebuilder:validation:MaxLength=256). Without this fix, theClaimfield inUsernameClaimMappingwill lack the intended maximum length constraint in the generated CRD, despite the comment correctly stating "must not exceed 256 characters."Proposed fix
- // +kubebuilder:validation:MaxLength:=256 + // +kubebuilder:validation:MaxLength=256🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/types_authentication.go` at line 623, The kubebuilder marker on the UsernameClaimMapping Claim field is malformed—replace the incorrect delimiter `MaxLength:=256` with `MaxLength=256` so controller-gen recognizes the constraint; locate the marker near the UsernameClaimMapping type (the comment referencing "must not exceed 256 characters" / Claim field) in types_authentication.go and update the annotation to `+kubebuilder:validation:MaxLength=256`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@config/v1/types_authentication.go`:
- Line 356: The CEL rule in the
+openshift:validation:FeatureGateAwareXValidation annotation for
TokenClaimMapping contains unescaped double quotes in orValue(""), which breaks
the quoted rule string; update the rule value used by the
FeatureGateAwareXValidation annotation (the annotation name
+openshift:validation:FeatureGateAwareXValidation and the rule referencing
ExternalOIDCWithUpstreamParity) to escape the inner quotes (use orValue(\"\"))
so the outer string remains intact and the validation is emitted.
- Line 613: The CEL validation uses has(self.claim) which is always true because
UsernameClaimMapping.Claim is not omitempty; update the
FeatureGateAwareXValidation rule on UsernameClaimMapping to mirror
TokenClaimMapping by checking non-empty value instead of presence — replace
has(self.claim) with size(self.?claim.orValue("")) > 0 (and keep the existing
expression check logic: size(self.?claim.orValue("")) > 0 ?
!has(self.expression) : has(self.expression)); target the rule string associated
with UsernameClaimMapping in types_authentication.go.
---
Duplicate comments:
In `@config/v1/types_authentication.go`:
- Around line 610-612: The validation tags on UsernameClaimMapping are inverted
(they use !has(self.claim)) and therefore accept objects missing claim and
reject valid ones; update the three FeatureGateAwareXValidation rules for
UsernameClaimMapping to use has(self.claim) (not !has(self.claim)) so the
presence of claim is required under the same feature gates as TokenClaimMapping
(mirror the behavior of the rules at TokenClaimMapping lines ~353–355) and keep
the same messages and featureGate values.
- Line 623: The kubebuilder marker on the UsernameClaimMapping Claim field is
malformed—replace the incorrect delimiter `MaxLength:=256` with `MaxLength=256`
so controller-gen recognizes the constraint; locate the marker near the
UsernameClaimMapping type (the comment referencing "must not exceed 256
characters" / Claim field) in types_authentication.go and update the annotation
to `+kubebuilder:validation:MaxLength=256`.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
config/v1/types_authentication.go
Signed-off-by: Shaza Aldawamneh <shaza.aldawamneh@hotmail.com>
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (7)
payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml (1)
311-312:⚠️ Potential issue | 🔴 CriticalCritical: Same inverted rule on
username— will reject valid configs withclaimset.Same issue as the
groupsvalidation above. The rule!has(self.claim)makesclaimeffectively forbidden rather than required.x-kubernetes-validations: - message: claim is required - rule: '!has(self.claim)' + rule: has(self.claim)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml` around lines 311 - 312, The validation rule for the username/claim field is inverted — the rule currently uses '!has(self.claim)' which forbids configs that include claim; change it to 'has(self.claim)' so the field is required (i.e., replace '!has(self.claim)' with 'has(self.claim)' for the claim/username validation entry in the CRD manifest).config/v1/zz_generated.swagger_doc_generated.go (1)
550-552:⚠️ Potential issue | 🟡 MinorUsername claim mapping docs still miss enforced constraints (and contain a typo).
claimstill says “a optional”,expressiondoes not document its length bounds, and docs still don’t state thatclaimis required whenprefixPolicyis"Prefix".Because this is generated output, please update the source comments and regenerate (
hack/update-swagger-docs.sh).📝 Suggested wording update
- "claim": "claim is a optional field ... Precisely one of claim or expression must be set if the ExternalOIDCWithUpstreamParity feature gate is enabled.\n\nclaim must not be an empty string (\"\") and must not exceed 256 characters.", - "expression": "expression is an optional CEL expression ...\n\nPrecisely one of claim or expression must be set if the ExternalOIDCWithUpstreamParity feature gate is enabled.", + "claim": "claim is an optional field ... Precisely one of claim or expression must be set if the ExternalOIDCWithUpstreamParity feature gate is enabled. claim must be set when prefixPolicy is 'Prefix'.\n\nclaim must not be an empty string (\"\") and must not exceed 256 characters.", + "expression": "expression is an optional CEL expression ...\n\nPrecisely one of claim or expression must be set if the ExternalOIDCWithUpstreamParity feature gate is enabled. expression must be at least 1 character and must not exceed 1024 characters.",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/zz_generated.swagger_doc_generated.go` around lines 550 - 552, Fix the source comments that generate the swagger docs for the fields claim, expression, and prefixPolicy: correct the typo in the claim doc ("a optional" -> "an optional"), add the missing length bounds for expression (match claim's "must not be an empty string and must not exceed 256 characters"), and explicitly document that claim is required when prefixPolicy is set to "Prefix" (and note that the prefix field must be set in that case). Update the comments for the prefixPolicy/prefix fields to clearly state the dependency (prefix required when prefixPolicy == "Prefix") and then regenerate the swagger docs using hack/update-swagger-docs.sh.config/v1/types_authentication.go (2)
623-624:⚠️ Potential issue | 🟠 MajorMalformed kubebuilder markers:
:=instead of=— these constraints are silently ignored.
+kubebuilder:validation:MinLength:=1and+kubebuilder:validation:MaxLength:=256use the wrong separator; controller-gen requires=, not:=. As-is, neither constraint is emitted in the generated CRD, soUsernameClaimMapping.Claimhas no length bounds in the schema.🐛 Proposed fix
- // +kubebuilder:validation:MinLength:=1 - // +kubebuilder:validation:MaxLength:=256 + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=256🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/types_authentication.go` around lines 623 - 624, The kubebuilder validation markers for UsernameClaimMapping.Claim are malformed using ":=" instead of "=" so controller-gen ignores the MinLength/MaxLength constraints; update the struct tags/comments where UsernameClaimMapping.Claim is defined to use "+kubebuilder:validation:MinLength=1" and "+kubebuilder:validation:MaxLength=256" (replace both ":=" with "=") so the generated CRD includes the length bounds.
353-355:⚠️ Potential issue | 🔴 Critical
!has(self.claim)is logically inverted — these rules forbidclaiminstead of requiring it.In Kubernetes CEL, a rule evaluates to
truewhen the object is valid.!has(self.claim)istruewhen claim is absent, so it accepts configs without a claim and rejects configs that do provide one.For the three non-parity feature gates (
"",ExternalOIDC,ExternalOIDCWithUIDAndExtraClaimMappings),claimis supposed to remain required. The corrected rule forTokenClaimMapping(which permits""as a legacy-compatible value) should use size-based checking, mirroring line 356:🐛 Proposed fix
-// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="!has(self.claim)",message="claim is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="!has(self.claim)",message="claim is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="!has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="size(self.?claim.orValue(\"\")) > 0",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="size(self.?claim.orValue(\"\")) > 0",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="size(self.?claim.orValue(\"\")) > 0",message="claim is required"This is the root cause of the same inversion in the generated Default CRD (lines 204–206 and 311–312).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/types_authentication.go` around lines 353 - 355, The CEL validation for TokenClaimMapping is inverted: change the three annotations that currently use '!has(self.claim)' for the feature gates "" (empty), ExternalOIDC, and ExternalOIDCWithUIDAndExtraClaimMappings so they require a non-empty claim instead of forbidding it; replace the '!has(self.claim)' checks with a size-based check (e.g. size(self.claim) > 0) to mirror the existing check used on the adjacent rule (line with size(self.claim) > 0) so TokenClaimMapping properly enforces a required, non-empty claim across those feature gates.payload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yaml (1)
311-312:⚠️ Potential issue | 🔴 CriticalSame inverted
!has(self.claim)rule onusername— always fails when claim is set.
UsernameClaimMapping.Claimis nowjson:"claim,omitempty"sohas(self.claim)correctly returnsfalsewhen omitted. But!has(self.claim)still means: "valid only when claim is absent" — any user who provides a claim value will fail validation under the Default feature-set.🐛 Proposed fix (CRD YAML)
x-kubernetes-validations: - - message: claim is required - rule: '!has(self.claim)' + - message: claim is required + rule: 'has(self.claim)'🐛 Proposed fix (Go source — UsernameClaimMapping, lines 610–612)
-// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="!has(self.claim)",message="claim is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="!has(self.claim)",message="claim is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="!has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="has(self.claim)",message="claim is required" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="has(self.claim)",message="claim is required"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yaml` around lines 311 - 312, The validation rule for the claim field is inverted: change the JSONSchema/CRD rule that currently uses '!has(self.claim)' to require the field with 'has(self.claim)' so the validator accepts objects that include a claim; update the corresponding UsernameClaimMapping validation in the Go source (the UsernameClaimMapping.Claim handling/validation logic) to use a positive presence check (has(self.claim)) instead of a negated one so provided claims do not incorrectly fail validation.payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml (1)
266-267:⚠️ Potential issue | 🟡 MinorGrammatical error: "a optional" → "an optional".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml` around lines 266 - 267, Fix the grammatical error in the CRD description by replacing "a optional" with "an optional" in the sentence that reads "claim is a optional field that configures the JWT token claim..." inside the CRD YAML (look for the description line in 0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml mentioning "claim is a optional field"). Ensure the updated sentence reads "claim is an optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping."payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml (1)
266-267:⚠️ Potential issue | 🟡 MinorSame grammatical error as in DevPreviewNoUpgrade: "a optional" → "an optional".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml` around lines 266 - 267, Fix the grammatical error in the CustomNoUpgrade CRD description: change the phrase "claim is a optional field that configures..." to "claim is an optional field that configures..." in payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml (and apply the same correction to the duplicated text in DevPreviewNoUpgrade) so the documentation reads correctly.
🧹 Nitpick comments (4)
config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml (2)
487-502: Inconsistent error message for username vs groups mutual exclusivity.The username error message (Line 502) says
"claim or expression must be specified"while the groups error message (Line 553) says"exactly one of claim or expression must be specified". Both rules enforce the same one-of semantics. The username message is ambiguous—it reads as "at least one" rather than "exactly one," which is misleading when the failure reason is that both are set.Consider aligning both to
"exactly one of claim or expression must be specified"(or similar) for clarity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml` around lines 487 - 502, The expected error for the username mapping is inconsistent and misleading: update the test case where claimMappings.username is set with both claim and expression so its expectedError matches the groups case; change the string from "claim or expression must be specified" to "exactly one of claim or expression must be specified" (or the canonical project wording) for the username validation in ExternalOIDCWithUpstreamParity.yaml to align with the groups mutual-exclusivity rule.
458-553: Missing negative tests for "neither claim nor expression" on username and groups.The new tests cover "expression only" (valid) and "both claim + expression" (invalid), but do not cover the case where neither claim nor expression is provided. The one-of validation rule in the CRD should reject that case too. Adding those tests would improve confidence in the validation rules.
Example test cases
- name: Cannot omit both claim and expression for username mapping initial: | apiVersion: config.openshift.io/v1 kind: Authentication spec: type: OIDC oidcProviders: - name: myoidc issuer: issuerURL: https://meh.tld audiences: ['openshift-aud'] claimMappings: username: {} expectedError: "claim or expression must be specified" - name: Cannot omit both claim and expression for groups mapping initial: | apiVersion: config.openshift.io/v1 kind: Authentication spec: type: OIDC oidcProviders: - name: myoidc issuer: issuerURL: https://meh.tld audiences: ['openshift-aud'] claimMappings: username: claim: "preferred_username" groups: {} expectedError: "exactly one of claim or expression must be specified"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml` around lines 458 - 553, Add two negative test cases to the existing OIDC claimMappings tests: one named "Cannot omit both claim and expression for username mapping" that sets claimMappings.username: {} and expects error "claim or expression must be specified", and one named "Cannot omit both claim and expression for groups mapping" that sets claimMappings.groups: {} (with username present) and expects error "exactly one of claim or expression must be specified"; place them alongside the other tests so they validate the one-of rule for claimMappings.username and claimMappings.groups.payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml (2)
190-215: Groupsclaimfield lacksminLengthconstraint, unlike username'sclaim.The
groups.claimfield (Line 189-194) hasmaxLength: 256but nominLength, whileusername.claim(Line 264-274) hasminLength: 1. The validation rule on Line 215 compensates by checkingsize(self.?claim.orValue("")) > 0, so an empty-string claim is effectively treated as absent, which is functionally correct. However, addingminLength: 1togroups.claimwould be more consistent and would reject empty strings at the schema level rather than relying solely on the CEL rule.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml` around lines 190 - 215, Add a minLength: 1 constraint to the groups.claim schema entry so it mirrors username.claim and prevents empty-string values at the schema level; update the groups.claim block (the object field named "groups" -> "claim") to include minLength: 1 while leaving the existing maxLength: 256 and the CEL x-kubernetes-validations rule intact.
332-334: Validation rule and message are correct, but the message wording is ambiguous.The rule
has(self.claim) ? !has(self.expression) : has(self.expression)correctly enforces exactly-one-of semantics. However, the message"claim or expression must be specified"reads as "at least one," which doesn't cover the failure case when both are set. The groups validation (Line 214) uses the clearer"exactly one of claim or expression must be specified". Consider aligning for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml` around lines 332 - 334, The x-kubernetes-validations entry using the rule `has(self.claim) ? !has(self.expression) : has(self.expression)` enforces exactly-one-of semantics but the message `"claim or expression must be specified"` is ambiguous; update the validation message to the clearer `"exactly one of claim or expression must be specified"` so it matches the groups validation wording and clearly covers both the neither-set and both-set failure cases (refer to the same x-kubernetes-validations block and the `claim`/`expression` fields).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yaml`:
- Around line 204-206: The CEL validation rules for required fields are
inverted: replace '!has(self.claim)' with 'has(self.claim)' and likewise change
the username rule to 'has(self.username)' in the CRD x-kubernetes-validations;
also update the Go source markers in config/v1/types_authentication.go for the
TokenClaimMapping.Claim and the corresponding username field to match (flip the
validation marker to require presence) and add `omitempty` to the JSON tags for
Claim and Username so absent fields are not always serialized (prevent has()
from always returning true).
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml`:
- Around line 257-260: Update the CRD description for the claim field to fix the
grammar: change the phrase "a optional field" to "an optional field" in the
description that mentions the claim and ExternalOIDCWithUpstreamParity feature
gate; look for the 'claim' field description text that reads "claim is a
optional field..." and edit that string accordingly (also check the equivalent
TechPreview CRD for the same typo and apply the same fix to its 'claim'
description).
- Around line 204-206: The validation rule for the claim field is inverted:
x-kubernetes-validations currently uses '!has(self.claim)' which rejects objects
that include claim while the message says "claim is required"; update the rule
to 'has(self.claim)' for the claim mapping entries in TokenClaimMapping and
UsernameClaimMapping (the CRD validation blocks that reference the claim field)
so the validator accepts objects that include claim and rejects those that omit
it, mirroring the Go types (config/v1/types_authentication.go) implementation.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`:
- Around line 264-287: Update the grammar in the 'claim' field description:
change "claim is a optional field" to "claim is an optional field" within the
description block for the claim property (the YAML block under the claim key);
ensure the change only alters that wording and preserves surrounding sentences
and indentation so the schema and constraints (maxLength/minLength/type) remain
unchanged.
---
Duplicate comments:
In `@config/v1/types_authentication.go`:
- Around line 623-624: The kubebuilder validation markers for
UsernameClaimMapping.Claim are malformed using ":=" instead of "=" so
controller-gen ignores the MinLength/MaxLength constraints; update the struct
tags/comments where UsernameClaimMapping.Claim is defined to use
"+kubebuilder:validation:MinLength=1" and
"+kubebuilder:validation:MaxLength=256" (replace both ":=" with "=") so the
generated CRD includes the length bounds.
- Around line 353-355: The CEL validation for TokenClaimMapping is inverted:
change the three annotations that currently use '!has(self.claim)' for the
feature gates "" (empty), ExternalOIDC, and
ExternalOIDCWithUIDAndExtraClaimMappings so they require a non-empty claim
instead of forbidding it; replace the '!has(self.claim)' checks with a
size-based check (e.g. size(self.claim) > 0) to mirror the existing check used
on the adjacent rule (line with size(self.claim) > 0) so TokenClaimMapping
properly enforces a required, non-empty claim across those feature gates.
In `@config/v1/zz_generated.swagger_doc_generated.go`:
- Around line 550-552: Fix the source comments that generate the swagger docs
for the fields claim, expression, and prefixPolicy: correct the typo in the
claim doc ("a optional" -> "an optional"), add the missing length bounds for
expression (match claim's "must not be an empty string and must not exceed 256
characters"), and explicitly document that claim is required when prefixPolicy
is set to "Prefix" (and note that the prefix field must be set in that case).
Update the comments for the prefixPolicy/prefix fields to clearly state the
dependency (prefix required when prefixPolicy == "Prefix") and then regenerate
the swagger docs using hack/update-swagger-docs.sh.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml`:
- Around line 266-267: Fix the grammatical error in the CustomNoUpgrade CRD
description: change the phrase "claim is a optional field that configures..." to
"claim is an optional field that configures..." in
payload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml
(and apply the same correction to the duplicated text in DevPreviewNoUpgrade) so
the documentation reads correctly.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yaml`:
- Around line 311-312: The validation rule for the claim field is inverted:
change the JSONSchema/CRD rule that currently uses '!has(self.claim)' to require
the field with 'has(self.claim)' so the validator accepts objects that include a
claim; update the corresponding UsernameClaimMapping validation in the Go source
(the UsernameClaimMapping.Claim handling/validation logic) to use a positive
presence check (has(self.claim)) instead of a negated one so provided claims do
not incorrectly fail validation.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml`:
- Around line 266-267: Fix the grammatical error in the CRD description by
replacing "a optional" with "an optional" in the sentence that reads "claim is a
optional field that configures the JWT token claim..." inside the CRD YAML (look
for the description line in
0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml
mentioning "claim is a optional field"). Ensure the updated sentence reads
"claim is an optional field that configures the JWT token claim whose value is
assigned to the cluster identity field associated with this mapping."
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml`:
- Around line 311-312: The validation rule for the username/claim field is
inverted — the rule currently uses '!has(self.claim)' which forbids configs that
include claim; change it to 'has(self.claim)' so the field is required (i.e.,
replace '!has(self.claim)' with 'has(self.claim)' for the claim/username
validation entry in the CRD manifest).
---
Nitpick comments:
In
`@config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yaml`:
- Around line 487-502: The expected error for the username mapping is
inconsistent and misleading: update the test case where claimMappings.username
is set with both claim and expression so its expectedError matches the groups
case; change the string from "claim or expression must be specified" to "exactly
one of claim or expression must be specified" (or the canonical project wording)
for the username validation in ExternalOIDCWithUpstreamParity.yaml to align with
the groups mutual-exclusivity rule.
- Around line 458-553: Add two negative test cases to the existing OIDC
claimMappings tests: one named "Cannot omit both claim and expression for
username mapping" that sets claimMappings.username: {} and expects error "claim
or expression must be specified", and one named "Cannot omit both claim and
expression for groups mapping" that sets claimMappings.groups: {} (with username
present) and expects error "exactly one of claim or expression must be
specified"; place them alongside the other tests so they validate the one-of
rule for claimMappings.username and claimMappings.groups.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`:
- Around line 190-215: Add a minLength: 1 constraint to the groups.claim schema
entry so it mirrors username.claim and prevents empty-string values at the
schema level; update the groups.claim block (the object field named "groups" ->
"claim") to include minLength: 1 while leaving the existing maxLength: 256 and
the CEL x-kubernetes-validations rule intact.
- Around line 332-334: The x-kubernetes-validations entry using the rule
`has(self.claim) ? !has(self.expression) : has(self.expression)` enforces
exactly-one-of semantics but the message `"claim or expression must be
specified"` is ambiguous; update the validation message to the clearer `"exactly
one of claim or expression must be specified"` so it matches the groups
validation wording and clearly covers both the neither-set and both-set failure
cases (refer to the same x-kubernetes-validations block and the
`claim`/`expression` fields).
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (9)
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yamlis excluded by!**/zz_generated.crd-manifests/*config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDC.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**config/v1/zz_generated.featuregated-crd-manifests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yamlis excluded by!**/zz_generated.featuregated-crd-manifests/**openapi/generated_openapi/zz_generated.openapi.gois excluded by!openapi/**
📒 Files selected for processing (8)
config/v1/tests/authentications.config.openshift.io/ExternalOIDCWithUpstreamParity.yamlconfig/v1/types_authentication.goconfig/v1/zz_generated.swagger_doc_generated.gopayload-manifests/crds/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yamlpayload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
| x-kubernetes-validations: | ||
| - message: claim is required | ||
| rule: '!has(self.claim)' |
There was a problem hiding this comment.
!has(self.claim) is an inverted validation rule — this rejects every valid config.
In Kubernetes CEL validation, the rule must evaluate to true for the object to be valid. The rule !has(self.claim) evaluates to true only when claim is absent, so it accepts configs without a claim and rejects configs that supply one — the exact opposite of "claim is required".
Compounding this: TokenClaimMapping.Claim has no omitempty JSON tag, so Go clients always serialize claim: "" even when not explicitly set. Since CEL's has() tests field presence (not non-emptiness), has(self.claim) is always true, making !has(self.claim) always false → validation will always fail when groups is supplied under the Default feature-set.
The same inversion is present at Line 311 for the username object.
The fix needs to apply in both the CRD manifests and in the source markers in config/v1/types_authentication.go (lines 353–355, 610–612):
🐛 Proposed fix (CRD YAML)
type: object
- x-kubernetes-validations:
- - message: claim is required
- rule: '!has(self.claim)'
+ x-kubernetes-validations:
+ - message: claim is required
+ rule: 'size(self.?claim.orValue("")) > 0'🐛 Proposed fix (Go source — TokenClaimMapping, lines 353–355)
-// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="!has(self.claim)",message="claim is required"
-// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="!has(self.claim)",message="claim is required"
-// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="!has(self.claim)",message="claim is required"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="size(self.?claim.orValue(\"\")) > 0",message="claim is required"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="size(self.?claim.orValue(\"\")) > 0",message="claim is required"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUIDAndExtraClaimMappings,rule="size(self.?claim.orValue(\"\")) > 0",message="claim is required"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-Default.crd.yaml`
around lines 204 - 206, The CEL validation rules for required fields are
inverted: replace '!has(self.claim)' with 'has(self.claim)' and likewise change
the username rule to 'has(self.username)' in the CRD x-kubernetes-validations;
also update the Go source markers in config/v1/types_authentication.go for the
TokenClaimMapping.Claim and the corresponding username field to match (flip the
validation marker to require presence) and add `omitempty` to the JSON tags for
Claim and Username so absent fields are not always serialized (prevent has()
from always returning true).
| x-kubernetes-validations: | ||
| - message: claim is required | ||
| rule: '!has(self.claim)' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, examine the specific lines in the OKD CRD file
echo "=== Examining lines 204-206 in OKD CRD file ==="
sed -n '200,210p' payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml
echo ""
echo "=== Examining lines 311-312 in OKD CRD file ==="
sed -n '308,315p' payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml
echo ""
echo "=== Searching for '!has(self.claim)' pattern in all CRD files ==="
rg -n -B2 -A1 '!has\(self\.claim\)' --glob '*.yaml' payload-manifests/crds/
echo ""
echo "=== Searching for 'claim is required' in all CRD files to see all occurrences ==="
rg -n -B1 -A1 'claim is required' --glob '*.yaml' payload-manifests/crds/
echo ""
echo "=== Looking for Go source files with validation rules ==="
fd -e go . | head -20Repository: openshift/api
Length of output: 6108
🏁 Script executed:
#!/bin/bash
echo "=== Searching for Go files in pkg/config/v1 related to authentication/OIDC ==="
fd -e go config | grep -E '(config|auth|oidc)' | grep -v vendor | head -20
echo ""
echo "=== Search for OIDC-related Go type definitions ==="
rg -n 'type.*OIDC' --glob '*.go' | grep -v vendor | head -20
echo ""
echo "=== Search for the exact validation message in Go source ==="
rg -n 'claim is required' --glob '*.go' | grep -v vendor
echo ""
echo "=== List Go files in pkg/config/v1 ==="
find pkg -name '*.go' -type f 2>/dev/null | head -30Repository: openshift/api
Length of output: 2125
🏁 Script executed:
#!/bin/bash
echo "=== Context around lines 353-355 in types_authentication.go ==="
sed -n '340,365p' config/v1/types_authentication.go
echo ""
echo "=== Context around lines 610-612 in types_authentication.go ==="
sed -n '595,620p' config/v1/types_authentication.go
echo ""
echo "=== Check if there are any comments or documentation about what claim should be ==="
sed -n '330,400p' config/v1/types_authentication.go | head -50Repository: openshift/api
Length of output: 6205
🏁 Script executed:
#!/bin/bash
echo "=== Verify which struct TokenClaimMapping is used in ==="
rg -n 'TokenClaimMapping' config/v1/types_authentication.go | grep -v '//'
echo ""
echo "=== Verify which struct UsernameClaimMapping is used in ==="
rg -n 'UsernameClaimMapping' config/v1/types_authentication.go | grep -v '//'Repository: openshift/api
Length of output: 440
Critical: Inverted validation rule — !has(self.claim) rejects objects that have claim set.
The rule !has(self.claim) passes when claim is absent and fails when claim is present, which is the opposite of the message "claim is required". This will reject every valid groups and username configuration that specifies a claim and accept every configuration that omits it.
The same bug exists at:
- Line 206 (groups claim mapping in TokenClaimMapping)
- Line 312 (username claim mapping in UsernameClaimMapping)
Both occur in OKD and Default CRD variants. The correct rule should be has(self.claim) without negation, as correctly implemented for the ExternalOIDCWithUpstreamParity feature gate in the Go source (config/v1/types_authentication.go lines 356 and 613).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml`
around lines 204 - 206, The validation rule for the claim field is inverted:
x-kubernetes-validations currently uses '!has(self.claim)' which rejects objects
that include claim while the message says "claim is required"; update the rule
to 'has(self.claim)' for the claim mapping entries in TokenClaimMapping and
UsernameClaimMapping (the CRD validation blocks that reference the claim field)
so the validator accepts objects that include claim and rejects those that omit
it, mirroring the Go types (config/v1/types_authentication.go) implementation.
| claim is a optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | ||
|
|
||
| Precisely one of claim or expression must be set if the | ||
| ExternalOIDCWithUpstreamParity feature gate is enabled. |
There was a problem hiding this comment.
Minor grammar: "a optional" → "an optional".
Same typo as in the TechPreview CRD.
- claim is a optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping.
+ claim is an optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| claim is a optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | |
| Precisely one of claim or expression must be set if the | |
| ExternalOIDCWithUpstreamParity feature gate is enabled. | |
| claim is an optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | |
| Precisely one of claim or expression must be set if the | |
| ExternalOIDCWithUpstreamParity feature gate is enabled. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-OKD.crd.yaml`
around lines 257 - 260, Update the CRD description for the claim field to fix
the grammar: change the phrase "a optional field" to "an optional field" in the
description that mentions the claim and ExternalOIDCWithUpstreamParity feature
gate; look for the 'claim' field description text that reads "claim is a
optional field..." and edit that string accordingly (also check the equivalent
TechPreview CRD for the same typo and apply the same fix to its 'claim'
description).
| claim: | ||
| description: |- | ||
| claim is a required field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | ||
| claim is a optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | ||
|
|
||
| Precisely one of claim or expression must be set if the | ||
| ExternalOIDCWithUpstreamParity feature gate is enabled. | ||
|
|
||
| claim must not be an empty string ("") and must not exceed 256 characters. | ||
| maxLength: 256 | ||
| minLength: 1 | ||
| type: string | ||
| expression: | ||
| description: |- | ||
| expression is an optional CEL expression used to derive | ||
| the username from JWT claims. | ||
|
|
||
| CEL expressions have access to the token claims | ||
| through a CEL variable, 'claims'. | ||
|
|
||
| Precisely one of claim or expression must be set if the | ||
| ExternalOIDCWithUpstreamParity feature gate is enabled. | ||
| maxLength: 1024 | ||
| minLength: 1 | ||
| type: string |
There was a problem hiding this comment.
Minor grammar: "a optional" → "an optional".
Line 266: claim is a optional field should be claim is an optional field.
- claim is a optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping.
+ claim is an optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| claim: | |
| description: |- | |
| claim is a required field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | |
| claim is a optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | |
| Precisely one of claim or expression must be set if the | |
| ExternalOIDCWithUpstreamParity feature gate is enabled. | |
| claim must not be an empty string ("") and must not exceed 256 characters. | |
| maxLength: 256 | |
| minLength: 1 | |
| type: string | |
| expression: | |
| description: |- | |
| expression is an optional CEL expression used to derive | |
| the username from JWT claims. | |
| CEL expressions have access to the token claims | |
| through a CEL variable, 'claims'. | |
| Precisely one of claim or expression must be set if the | |
| ExternalOIDCWithUpstreamParity feature gate is enabled. | |
| maxLength: 1024 | |
| minLength: 1 | |
| type: string | |
| claim: | |
| description: |- | |
| claim is an optional field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. | |
| Precisely one of claim or expression must be set if the | |
| ExternalOIDCWithUpstreamParity feature gate is enabled. | |
| claim must not be an empty string ("") and must not exceed 256 characters. | |
| maxLength: 256 | |
| minLength: 1 | |
| type: string | |
| expression: | |
| description: |- | |
| expression is an optional CEL expression used to derive | |
| the username from JWT claims. | |
| CEL expressions have access to the token claims | |
| through a CEL variable, 'claims'. | |
| Precisely one of claim or expression must be set if the | |
| ExternalOIDCWithUpstreamParity feature gate is enabled. | |
| maxLength: 1024 | |
| minLength: 1 | |
| type: string |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml`
around lines 264 - 287, Update the grammar in the 'claim' field description:
change "claim is a optional field" to "claim is an optional field" within the
description block for the claim property (the YAML block under the claim key);
ensure the change only alters that wording and preserves surrounding sentences
and indentation so the schema and constraints (maxLength/minLength/type) remain
unchanged.
|
@ShazaAldawamneh: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
UsernameClaimMapping.Claimto be optional whenExternalOIDCWithUpstreamParityis enabled.claimwhenPrefixPolicyis 'Prefix'.Expressionfield to be fully gated behindExternalOIDCWithUpstreamParity.claimin tests.