Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ require (
github.com/google/go-cmp v0.7.0
github.com/onsi/ginkgo/v2 v2.21.0
github.com/openshift-eng/openshift-tests-extension v0.0.0-20251205182537-ff5553e56f33
github.com/openshift/api v0.0.0-20260126183958-606bd613f9f7
github.com/openshift/api v0.0.0-20260212193555-c06ab675261f
github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee
github.com/openshift/client-go v0.0.0-20260108185524-48f4ccfc4e13
github.com/openshift/library-go v0.0.0-20260210145149-d0e860e8d752
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5
github.com/openshift/multi-operator-manager v0.0.0-20241205181422-20aa3906b99d
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/openshift-eng/openshift-tests-extension v0.0.0-20251205182537-ff5553e56f33 h1:LJf6kWZQ36iako7WXRzdEa5XKrnyrAX8GBhlAcKRaZQ=
github.com/openshift-eng/openshift-tests-extension v0.0.0-20251205182537-ff5553e56f33/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M=
github.com/openshift/api v0.0.0-20260126183958-606bd613f9f7 h1:96rhgJpWlWzKEslMd6aYFMixV9vQVY32M71JcO4Gzn0=
github.com/openshift/api v0.0.0-20260126183958-606bd613f9f7/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY=
github.com/openshift/api v0.0.0-20260212193555-c06ab675261f h1:l1IgsK48Ym/nED30yfaCTF4MtswO1eOoyfXgh2rEmdw=
github.com/openshift/api v0.0.0-20260212193555-c06ab675261f/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY=
github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee h1:+Sp5GGnjHDhT/a/nQ1xdp43UscBMr7G5wxsYotyhzJ4=
github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee/go.mod h1:8jcm8UPtg2mCAsxfqKil1xrmRMI3a+XU2TZ9fF8A7TE=
github.com/openshift/client-go v0.0.0-20260108185524-48f4ccfc4e13 h1:6rd4zSo2UaWQcAPZfHK9yzKVqH0BnMv1hqMzqXZyTds=
github.com/openshift/client-go v0.0.0-20260108185524-48f4ccfc4e13/go.mod h1:YvOmPmV7wcJxpfhTDuFqqs2Xpb3M3ovsM6Qs/i2ptq4=
github.com/openshift/library-go v0.0.0-20260210145149-d0e860e8d752 h1:KQj7j9VpMzv+gYerCgA9CbPehwGO3ARUg+B2Pt1YcWs=
github.com/openshift/library-go v0.0.0-20260210145149-d0e860e8d752/go.mod h1:DCRz1EgdayEmr9b6KXKDL+DWBN0rGHu/VYADeHzPoOk=
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5 h1:9Pe6iVOMjt9CdA/vaKBNUSoEIjIe1po5Ha3ABRYXLJI=
github.com/openshift/library-go v0.0.0-20260213153706-03f1709971c5/go.mod h1:K3FoNLgNBFYbFuG+Kr8usAnQxj1w84XogyUp2M8rK8k=
github.com/openshift/multi-operator-manager v0.0.0-20241205181422-20aa3906b99d h1:Rzx23P63JFNNz5D23ubhC0FCN5rK8CeJhKcq5QKcdyU=
github.com/openshift/multi-operator-manager v0.0.0-20241205181422-20aa3906b99d/go.mod h1:iVi9Bopa5cLhjG5ie9DoZVVqkH8BGb1FQVTtecOLn4I=
github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ=
Expand Down
62 changes: 59 additions & 3 deletions pkg/controllers/externaloidc/externaloidc_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,22 @@ func generateJWTForProvider(provider configv1.OIDCProvider, configMapLister core
return apiserverv1beta1.JWTAuthenticator{}, fmt.Errorf("generating claimMappings for provider %q: %v", provider.Name, err)
}

claimValidationRules, err := generateClaimValidationRules(provider.ClaimValidationRules...)
claimValidationRules, err := generateClaimValidationRules(featureGates, provider.ClaimValidationRules...)
if err != nil {
return apiserverv1beta1.JWTAuthenticator{}, fmt.Errorf("generating claimValidationRules for provider %q: %v", provider.Name, err)
}

var userValidationRules []apiserverv1beta1.UserValidationRule
if featureGates.Enabled(features.FeatureGateExternalOIDCWithUpstreamParity) {
userValidationRules, err = generateUserValidationRules(featureGates, provider.UserValidationRules)
if err != nil {
return apiserverv1beta1.JWTAuthenticator{}, fmt.Errorf("generating userValidationRules for provider %q: %v", provider.Name, err)
}
}
out.Issuer = issuer
out.ClaimMappings = claimMappings
out.ClaimValidationRules = claimValidationRules
out.UserValidationRules = userValidationRules

return out, nil
}
Expand All @@ -215,7 +223,9 @@ func generateIssuer(issuer configv1.TokenIssuer, configMapLister corev1listers.C
for _, audience := range issuer.Audiences {
out.Audiences = append(out.Audiences, string(audience))
}

if len(issuer.DiscoveryURL) > 0 {
out.DiscoveryURL = &issuer.DiscoveryURL
}
if len(issuer.CertificateAuthority.Name) > 0 {
ca, err := getCertificateAuthorityFromConfigMap(issuer.CertificateAuthority.Name, configMapLister)
if err != nil {
Expand Down Expand Up @@ -394,7 +404,7 @@ func generateExtraMapping(extraMapping configv1.ExtraMapping) (apiserverv1beta1.
return out, nil
}

func generateClaimValidationRules(claimValidationRules ...configv1.TokenClaimValidationRule) ([]apiserverv1beta1.ClaimValidationRule, error) {
func generateClaimValidationRules(featureGates featuregates.FeatureGate, claimValidationRules ...configv1.TokenClaimValidationRule) ([]apiserverv1beta1.ClaimValidationRule, error) {
out := []apiserverv1beta1.ClaimValidationRule{}
errs := []error{}
for _, claimValidationRule := range claimValidationRules {
Expand Down Expand Up @@ -428,13 +438,59 @@ func generateClaimValidationRule(claimValidationRule configv1.TokenClaimValidati

out.Claim = claimValidationRule.RequiredClaim.Claim
out.RequiredValue = claimValidationRule.RequiredClaim.RequiredValue
case configv1.TokenValidationRuleTypeCEL:
if len(claimValidationRule.CEL.Expression) == 0 {
return apiserverv1beta1.ClaimValidationRule{}, fmt.Errorf("claimValidationRule.type is %s and expression is not set", configv1.TokenValidationRuleTypeCEL)
}

// validate CEL expression
if err := validateCELExpression(&authenticationcel.ClaimMappingExpression{
Expression: claimValidationRule.CEL.Expression,
}); err != nil {
return apiserverv1beta1.ClaimValidationRule{}, fmt.Errorf("invalid CEL expression: %v", err)
}

out.Expression = claimValidationRule.CEL.Expression
out.Message = claimValidationRule.CEL.Message

default:
return apiserverv1beta1.ClaimValidationRule{}, fmt.Errorf("unknown claimValidationRule type %q", claimValidationRule.Type)
}

return out, nil
}

func generateUserValidationRule(rule configv1.TokenUserValidationRule, featureGates featuregates.FeatureGate) (apiserverv1beta1.UserValidationRule, error) {
if len(rule.Expression) == 0 {
return apiserverv1beta1.UserValidationRule{}, fmt.Errorf("userValidationRule expression must be non-empty")
}

return apiserverv1beta1.UserValidationRule{
Expression: rule.Expression,
Message: rule.Message,
}, nil
}

func generateUserValidationRules(featureGates featuregates.FeatureGate, rules []configv1.TokenUserValidationRule) ([]apiserverv1beta1.UserValidationRule, error) {
out := []apiserverv1beta1.UserValidationRule{}
errs := []error{}

for _, r := range rules {
uvr, err := generateUserValidationRule(r, featureGates)
if err != nil {
errs = append(errs, fmt.Errorf("generating userValidationRule: %v", err))
continue
}
out = append(out, uvr)
}

if len(errs) > 0 {
return nil, errors.Join(errs...)
}

return out, nil
}

// getExpectedApplyConfig serializes the input authConfig into JSON and creates an apply configuration
// for a configmap with the serialized authConfig in the right key.
func getExpectedApplyConfig(authConfig apiserverv1beta1.AuthenticationConfiguration) (*corev1ac.ConfigMapApplyConfiguration, error) {
Expand Down
Loading