diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
index de0dd293a85..d883307d841 100644
--- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
+++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
@@ -446,6 +446,434 @@ spec:
? has(self.requiredClaim) : !has(self.requiredClaim)'
type: array
x-kubernetes-list-type: atomic
+ externalClaimsSources:
+ description: |-
+ externalClaimsSources is an optional field that can be used to configure
+ sources, external to the token provided in a request, in which claims
+ should be fetched from and made available to the claim mapping process
+ that is used to build the identity of a token holder.
+
+ For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint.
+
+ When not specified, only claims present in the token itself will be available
+ in the claim mapping process.
+
+ When specified, at least one external claim source must be specified and no more than 5
+ sources may be specified.
+ All external claim sources must have unique claim mappings.
+ When an external source responds and resolves additional claims successfully, they will
+ be made available as claims during the claim mapping process.
+ Externally sourced claims with the same name as a claim existing within the token will
+ overwrite the claim data from the token with the externally sourced information.
+ If an external source does not respond, responds with an error, or the additional
+ claim data cannot be resolved from the response successfully it will not be
+ included in the claim data passed to the claim mapping process.
+ items:
+ description: ExternalClaimsSource provides the configuration
+ for a single external claim source.
+ properties:
+ authentication:
+ description: |-
+ authentication is an optional field that configures how the apiserver authenticates with an external claims source.
+ When not specified, anonymous authentication is used which means no 'Authorization' header
+ is sent in the HTTP request to fetch the external claims.
+ properties:
+ clientCredential:
+ description: |-
+ clientCredential configures the client credentials
+ and token endpoint to use to get an access token.
+ clientCredential is required when type is 'ClientCredential', and forbidden otherwise.
+ properties:
+ clientID:
+ description: |-
+ clientID is a required client identifier to use during the OAuth2 client credentials flow.
+ clientID must be at least 1 character in length, must not exceed 256 characters in length,
+ and must only contain printable ASCII characters.
+ maxLength: 256
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: clientID must only contain printable
+ ASCII characters
+ rule: self.matches('^[[:print:]]+$')
+ clientSecret:
+ description: |-
+ clientSecret is a required reference to a Secret in the openshift-config namespace to be used
+ as the client secret during the OAuth2 client credentials flow.
+
+ The key 'client-secret' is used to locate the client secret data in the Secret.
+ properties:
+ name:
+ description: |-
+ name is the required name of the Secret that exists in the openshift-config namespace.
+
+ It must be at least 1 character in length, must not exceed 253 characters in length,
+ must start and end with a lowercase alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or '.'.
+ maxLength: 253
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must start and end with a
+ lowercase alphanumeric character, and
+ must only contain lowercase alphanumeric
+ characters, '-' or '.'
+ rule: '!format.dns1123Subdomain().validate(self).hasValue()'
+ required:
+ - name
+ type: object
+ scopes:
+ description: |-
+ scopes is an optional list of OAuth2 scopes to request when obtaining
+ an access token.
+
+ If not specified, the token endpoint's default scopes
+ will be used.
+
+ When specified, there must be at least 1 entry and must not exceed 16 entries.
+ Each entry must be at least 1 character in length and must not exceed 256 characters in length.
+ Each entry must only contain printable ASCII characters, excluding spaces, double quotes and backslashes.
+ Entries must be unique.
+ items:
+ description: |-
+ OAuth2Scope is a string alias that represents an OAuth2 Scope as defined by https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.4
+ Must be at least 1 character in length, must not exceed 256 characters in length and must only contain printable ASCII characters, excluding spaces, double quotes and backslashes.
+ maxLength: 256
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: scopes must only contain printable
+ ASCII characters excluding spaces, double
+ quotes and backslashes
+ rule: self.matches('^[!#-[\\]-~]+$')
+ maxItems: 16
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: set
+ tls:
+ description: |-
+ tls is an optional field that allows configuring the TLS
+ settings used to interact with the identity provider
+ as an OAuth2 client.
+
+ When omitted, system default TLS settings will be used
+ for the OAuth2 client.
+ properties:
+ certificateAuthority:
+ description: |-
+ certificateAuthority is a required reference to a ConfigMap in the openshift-config
+ namespace that contains the CA certificate to use to validate TLS connections with the external claims source.
+ The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+ properties:
+ name:
+ description: |-
+ name is the required name of the ConfigMap that exists in the openshift-config namespace.
+ The key "ca-bundle.crt" must be present and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+
+ It must be at least 1 character in length, must not exceed 253 characters in length,
+ must start and end with a lowercase alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or '.'.
+ maxLength: 253
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must start and end with
+ a lowercase alphanumeric character,
+ and must only contain lowercase alphanumeric
+ characters, '-' or '.'
+ rule: '!format.dns1123Subdomain().validate(self).hasValue()'
+ required:
+ - name
+ type: object
+ required:
+ - certificateAuthority
+ type: object
+ tokenEndpoint:
+ description: |-
+ tokenEndpoint is a required URL to query for an access token using
+ the client credential OAuth2 flow.
+ tokenEndpoint must be at least 1 character in length and must not exceed 2048 characters in length.
+ tokenEndpoint must be a valid HTTPS URL.
+ tokenEndpoint must have a host and a path.
+ tokenEndpoint must not contain query parameters, fragments,
+ or user information (e.g., "user:password@host").
+ maxLength: 2048
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: tokenEndpoint must be a valid HTTPS
+ url
+ rule: isURL(self)
+ - message: tokenEndpoint must be a valid HTTPS
+ url
+ rule: isURL(self) && url(self).getScheme() ==
+ 'https'
+ - message: tokenEndpoint must have a hostname
+ rule: isURL(self) && url(self).getHost() !=
+ ''
+ - message: tokenEndpoint must have a path
+ rule: isURL(self) && url(self).getEscapedPath()
+ != ''
+ - message: tokenEndpoint must not have query parameters
+ rule: isURL(self) && url(self).getQuery() ==
+ {}
+ - message: tokenEndpoint must not have a fragment
+ rule: isURL(self) && self.find('#(.+)$') ==
+ ''
+ - message: tokenEndpoint must not have user info
+ rule: isURL(self) && !self.matches('^https://[^/]+@.+$')
+ required:
+ - clientID
+ - clientSecret
+ - tokenEndpoint
+ type: object
+ type:
+ description: |-
+ type is a required field that sets the type of
+ authentication method used by the authenticator
+ when fetching external claims.
+
+ Allowed values are 'RequestProvidedToken' and 'ClientCredential'.
+
+ When set to 'RequestProvidedToken', the authenticator will
+ use the token provided to the kube-apiserver as part of the
+ request to authenticate with the external claims source.
+
+ When set to 'ClientCredential', the authenticator will
+ use the configured client-id, client-secret, and token endpoint
+ to fetch an access token using the OAuth2 client credentials grant
+ flow. The fetched access token will then be used to authenticate
+ with the external claims source.
+ enum:
+ - RequestProvidedToken
+ - ClientCredential
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: clientCredential is required when type is ClientCredential,
+ and forbidden otherwise
+ rule: 'self.type == ''ClientCredential'' ? has(self.clientCredential)
+ : !has(self.clientCredential)'
+ mappings:
+ description: |-
+ mappings is a required list of the claim
+ and response handling expression pairs
+ that produces the claims from the external source.
+ mappings must have at least 1 entry and must not exceed 16 entries.
+ Entries must have a unique name across all external claim sources.
+ items:
+ description: |-
+ SourcedClaimMapping configures the mapping behavior for a single external claim
+ from the response the apiserver received from the external claim source.
+ properties:
+ expression:
+ description: |-
+ expression is a required CEL expression that
+ will produce a value to be assigned to the claim.
+ The full response body from the request to the
+ external claim source is provided via the
+ `response.body` variable.
+
+ The contents of the `response.body` variable varies based on the response received
+ from the external source. It is the responsibility of those configuring
+ this expression to understand what is returned from the external source.
+
+ expression must be at least 1 character and must not exceed 1024 characters in length.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ name:
+ description: |-
+ name is a required name of the claim that
+ will be produced and made available during
+ the claim-to-identity mapping process.
+ name must consist of only lowercase alpha characters and underscores ('_').
+ name must be at least 1 character and must not exceed 256 characters in length.
+ maxLength: 256
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must consist of only lowercase alpha
+ characters and underscores
+ rule: self.matches('^[a-z_]+$')
+ required:
+ - expression
+ - name
+ type: object
+ maxItems: 16
+ minItems: 1
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ predicates:
+ description: |-
+ predicates is an optional list of constraints in
+ which claims should attempt to be fetched from this
+ external source.
+
+ When omitted, claims are always fetched
+ from this external source.
+
+ When specified, all predicates must evaluate to 'true'
+ before claims are attempted to be fetched from this external source.
+ predicates must have at least 1 entry and must not exceed 16 entries.
+ Entries must have unique expressions.
+ items:
+ description: |-
+ ExternalSourcePredicate configures a singular condition
+ that must return true before the external source is queried
+ to retrieve external claims.
+ properties:
+ expression:
+ description: |-
+ expression is a required CEL expression that
+ is used to determine whether or not an external
+ source should be used to fetch external claims.
+
+ The expression must return a boolean value,
+ where true means that the source should be consulted
+ and false means that it should not.
+
+ Claims from the token used for the request to the kube-apiserver
+ are made available via the `claims` variable.
+
+ The contents of the `claims` variable varies based on the claims that are
+ present in the token being validated. It is the responsibility of those configuring this
+ field to understand what claims the identity provider includes when issuing tokens.
+
+ expression must be at least 1 character and must not exceed 1024 characters in length.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - expression
+ type: object
+ maxItems: 16
+ minItems: 1
+ type: array
+ x-kubernetes-list-map-keys:
+ - expression
+ x-kubernetes-list-type: map
+ tls:
+ description: |-
+ tls is an optional field that configures the http client TLS
+ settings when fetching external claims from this source.
+
+ When omitted, system default TLS settings will be used
+ for fetching claims from the external source.
+ properties:
+ certificateAuthority:
+ description: |-
+ certificateAuthority is a required reference to a ConfigMap in the openshift-config
+ namespace that contains the CA certificate to use to validate TLS connections with the external claims source.
+ The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+ properties:
+ name:
+ description: |-
+ name is the required name of the ConfigMap that exists in the openshift-config namespace.
+ The key "ca-bundle.crt" must be present and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+
+ It must be at least 1 character in length, must not exceed 253 characters in length,
+ must start and end with a lowercase alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or '.'.
+ maxLength: 253
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must start and end with a lowercase
+ alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or
+ '.'
+ rule: '!format.dns1123Subdomain().validate(self).hasValue()'
+ required:
+ - name
+ type: object
+ required:
+ - certificateAuthority
+ type: object
+ url:
+ description: |-
+ url is a required configuration of the URL
+ for which the external claims are located.
+ properties:
+ hostname:
+ description: |-
+ hostname is a required hostname for which the external claims are located.
+
+ It must be a valid DNS subdomain name as per RFC1123.
+
+ This means that it must start and end with a lowercase alphanumeric character,
+ must only consist of lowercase alphanumeric characters, '-', and '.'.
+ hostname may optionally specify a port in the format ':{port}'.
+ If a port is specified it must not exceed 65535.
+
+ hostname must be at least 1 character in length.
+ When specifying a port, hostname must not exceed 259 characters in length.
+ When not specifying a port, hostname must not exceed 253 characters in length.
+ maxLength: 259
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: hostname must be a valid hostname
+ rule: isURL('https://'+self)
+ - message: hostname before port must start and end
+ with a lowercase alphanumeric character, and must
+ only contain lowercase alphanumeric characters,
+ '-' or '.'
+ rule: '!format.dns1123Subdomain().validate(self.split('':'')[0]).hasValue()'
+ - message: port must not exceed 65535
+ rule: 'self.split('':'').size() > 1 ? int(self.split('':'')[1])
+ <= 65535 : true'
+ pathExpression:
+ description: |-
+ pathExpression is a required CEL expression that returns a list
+ of string values used to construct the URL path.
+ Claims from the token used for the request to the kube-apiserver
+ are made available via the `claims` variable.
+ expression must be at least 1 character in length and must not exceed 1024 characters in length.
+
+ Values in the returned list will be joined with the hostname using a forward slash
+ (`/`) as a separator. Values in the returned list do not need to include the forward slash.
+ If a forward slash is included in a returned value, it will be encoded as `%2F`.
+
+ Example of a static path configuration:
+
+ pathExpression: ['realms', 'k8s', 'protocol', 'openid-connect', 'userinfo']
+
+ The above example would resolve to the path: '/realms/k8s/protocol/openid-connect/userinfo'
+
+ Example of a dynamic path configuration:
+
+ pathExpression: "['admin', 'realms', 'k8s', 'users'] + [claims.sub] + ['groups']"
+
+ Assuming 'claims.sub' is set to '12345', the above example would resolve to the path: '/admin/realms/k8s/users/12345/groups'
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - hostname
+ - pathExpression
+ type: object
+ required:
+ - mappings
+ - url
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ x-kubernetes-validations:
+ - message: mapping names must be unique across all external
+ claim sources.
+ rule: self.all(s, s.mappings.all(m, self.filter(s2, s2.mappings.exists(m2,
+ m2.name == m.name)).size() == 1))
issuer:
description: issuer is a required field that configures how
the platform interacts with the identity provider and how
diff --git a/features.md b/features.md
index b7ee33cfcec..ca895415a0a 100644
--- a/features.md
+++ b/features.md
@@ -16,7 +16,6 @@
| ClusterUpdatePreflight| | | Enabled | Enabled | | | | |
| ConfidentialCluster| | | Enabled | Enabled | | | | |
| Example2| | | Enabled | Enabled | | | | |
-| ExternalOIDCExternalClaimsSourcing| | | Enabled | Enabled | | | | |
| ExternalSnapshotMetadata| | | Enabled | Enabled | | | | |
| MachineAPIMigrationVSphere| | | Enabled | Enabled | | | | |
| NetworkConnect| | | Enabled | Enabled | | | | |
@@ -61,6 +60,7 @@
| DyanmicServiceEndpointIBMCloud| | | Enabled | Enabled | | | Enabled | Enabled |
| EtcdBackendQuota| | | Enabled | Enabled | | | Enabled | Enabled |
| Example| | | Enabled | Enabled | | | Enabled | Enabled |
+| ExternalOIDCExternalClaimsSourcing| | | Enabled | Enabled | | | Enabled | Enabled |
| ExternalOIDCWithUpstreamParity| | | Enabled | Enabled | | | Enabled | Enabled |
| GCPCustomAPIEndpoints| | | Enabled | Enabled | | | Enabled | Enabled |
| GCPCustomAPIEndpointsInstall| | | Enabled | Enabled | | | Enabled | Enabled |
diff --git a/features/features.go b/features/features.go
index de530fa66b0..217e4e30d2a 100644
--- a/features/features.go
+++ b/features/features.go
@@ -389,7 +389,7 @@ var (
contactPerson("bpalmer").
productScope(ocpSpecific).
enhancementPR("https://github.com/openshift/enhancements/pull/1907").
- enable(inDevPreviewNoUpgrade()).
+ enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()).
mustRegister()
FeatureGateExample = newFeatureGate("Example").
diff --git a/payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
index de0dd293a85..d883307d841 100644
--- a/payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
+++ b/payload-manifests/crds/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml
@@ -446,6 +446,434 @@ spec:
? has(self.requiredClaim) : !has(self.requiredClaim)'
type: array
x-kubernetes-list-type: atomic
+ externalClaimsSources:
+ description: |-
+ externalClaimsSources is an optional field that can be used to configure
+ sources, external to the token provided in a request, in which claims
+ should be fetched from and made available to the claim mapping process
+ that is used to build the identity of a token holder.
+
+ For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint.
+
+ When not specified, only claims present in the token itself will be available
+ in the claim mapping process.
+
+ When specified, at least one external claim source must be specified and no more than 5
+ sources may be specified.
+ All external claim sources must have unique claim mappings.
+ When an external source responds and resolves additional claims successfully, they will
+ be made available as claims during the claim mapping process.
+ Externally sourced claims with the same name as a claim existing within the token will
+ overwrite the claim data from the token with the externally sourced information.
+ If an external source does not respond, responds with an error, or the additional
+ claim data cannot be resolved from the response successfully it will not be
+ included in the claim data passed to the claim mapping process.
+ items:
+ description: ExternalClaimsSource provides the configuration
+ for a single external claim source.
+ properties:
+ authentication:
+ description: |-
+ authentication is an optional field that configures how the apiserver authenticates with an external claims source.
+ When not specified, anonymous authentication is used which means no 'Authorization' header
+ is sent in the HTTP request to fetch the external claims.
+ properties:
+ clientCredential:
+ description: |-
+ clientCredential configures the client credentials
+ and token endpoint to use to get an access token.
+ clientCredential is required when type is 'ClientCredential', and forbidden otherwise.
+ properties:
+ clientID:
+ description: |-
+ clientID is a required client identifier to use during the OAuth2 client credentials flow.
+ clientID must be at least 1 character in length, must not exceed 256 characters in length,
+ and must only contain printable ASCII characters.
+ maxLength: 256
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: clientID must only contain printable
+ ASCII characters
+ rule: self.matches('^[[:print:]]+$')
+ clientSecret:
+ description: |-
+ clientSecret is a required reference to a Secret in the openshift-config namespace to be used
+ as the client secret during the OAuth2 client credentials flow.
+
+ The key 'client-secret' is used to locate the client secret data in the Secret.
+ properties:
+ name:
+ description: |-
+ name is the required name of the Secret that exists in the openshift-config namespace.
+
+ It must be at least 1 character in length, must not exceed 253 characters in length,
+ must start and end with a lowercase alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or '.'.
+ maxLength: 253
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must start and end with a
+ lowercase alphanumeric character, and
+ must only contain lowercase alphanumeric
+ characters, '-' or '.'
+ rule: '!format.dns1123Subdomain().validate(self).hasValue()'
+ required:
+ - name
+ type: object
+ scopes:
+ description: |-
+ scopes is an optional list of OAuth2 scopes to request when obtaining
+ an access token.
+
+ If not specified, the token endpoint's default scopes
+ will be used.
+
+ When specified, there must be at least 1 entry and must not exceed 16 entries.
+ Each entry must be at least 1 character in length and must not exceed 256 characters in length.
+ Each entry must only contain printable ASCII characters, excluding spaces, double quotes and backslashes.
+ Entries must be unique.
+ items:
+ description: |-
+ OAuth2Scope is a string alias that represents an OAuth2 Scope as defined by https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.4
+ Must be at least 1 character in length, must not exceed 256 characters in length and must only contain printable ASCII characters, excluding spaces, double quotes and backslashes.
+ maxLength: 256
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: scopes must only contain printable
+ ASCII characters excluding spaces, double
+ quotes and backslashes
+ rule: self.matches('^[!#-[\\]-~]+$')
+ maxItems: 16
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: set
+ tls:
+ description: |-
+ tls is an optional field that allows configuring the TLS
+ settings used to interact with the identity provider
+ as an OAuth2 client.
+
+ When omitted, system default TLS settings will be used
+ for the OAuth2 client.
+ properties:
+ certificateAuthority:
+ description: |-
+ certificateAuthority is a required reference to a ConfigMap in the openshift-config
+ namespace that contains the CA certificate to use to validate TLS connections with the external claims source.
+ The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+ properties:
+ name:
+ description: |-
+ name is the required name of the ConfigMap that exists in the openshift-config namespace.
+ The key "ca-bundle.crt" must be present and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+
+ It must be at least 1 character in length, must not exceed 253 characters in length,
+ must start and end with a lowercase alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or '.'.
+ maxLength: 253
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must start and end with
+ a lowercase alphanumeric character,
+ and must only contain lowercase alphanumeric
+ characters, '-' or '.'
+ rule: '!format.dns1123Subdomain().validate(self).hasValue()'
+ required:
+ - name
+ type: object
+ required:
+ - certificateAuthority
+ type: object
+ tokenEndpoint:
+ description: |-
+ tokenEndpoint is a required URL to query for an access token using
+ the client credential OAuth2 flow.
+ tokenEndpoint must be at least 1 character in length and must not exceed 2048 characters in length.
+ tokenEndpoint must be a valid HTTPS URL.
+ tokenEndpoint must have a host and a path.
+ tokenEndpoint must not contain query parameters, fragments,
+ or user information (e.g., "user:password@host").
+ maxLength: 2048
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: tokenEndpoint must be a valid HTTPS
+ url
+ rule: isURL(self)
+ - message: tokenEndpoint must be a valid HTTPS
+ url
+ rule: isURL(self) && url(self).getScheme() ==
+ 'https'
+ - message: tokenEndpoint must have a hostname
+ rule: isURL(self) && url(self).getHost() !=
+ ''
+ - message: tokenEndpoint must have a path
+ rule: isURL(self) && url(self).getEscapedPath()
+ != ''
+ - message: tokenEndpoint must not have query parameters
+ rule: isURL(self) && url(self).getQuery() ==
+ {}
+ - message: tokenEndpoint must not have a fragment
+ rule: isURL(self) && self.find('#(.+)$') ==
+ ''
+ - message: tokenEndpoint must not have user info
+ rule: isURL(self) && !self.matches('^https://[^/]+@.+$')
+ required:
+ - clientID
+ - clientSecret
+ - tokenEndpoint
+ type: object
+ type:
+ description: |-
+ type is a required field that sets the type of
+ authentication method used by the authenticator
+ when fetching external claims.
+
+ Allowed values are 'RequestProvidedToken' and 'ClientCredential'.
+
+ When set to 'RequestProvidedToken', the authenticator will
+ use the token provided to the kube-apiserver as part of the
+ request to authenticate with the external claims source.
+
+ When set to 'ClientCredential', the authenticator will
+ use the configured client-id, client-secret, and token endpoint
+ to fetch an access token using the OAuth2 client credentials grant
+ flow. The fetched access token will then be used to authenticate
+ with the external claims source.
+ enum:
+ - RequestProvidedToken
+ - ClientCredential
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: clientCredential is required when type is ClientCredential,
+ and forbidden otherwise
+ rule: 'self.type == ''ClientCredential'' ? has(self.clientCredential)
+ : !has(self.clientCredential)'
+ mappings:
+ description: |-
+ mappings is a required list of the claim
+ and response handling expression pairs
+ that produces the claims from the external source.
+ mappings must have at least 1 entry and must not exceed 16 entries.
+ Entries must have a unique name across all external claim sources.
+ items:
+ description: |-
+ SourcedClaimMapping configures the mapping behavior for a single external claim
+ from the response the apiserver received from the external claim source.
+ properties:
+ expression:
+ description: |-
+ expression is a required CEL expression that
+ will produce a value to be assigned to the claim.
+ The full response body from the request to the
+ external claim source is provided via the
+ `response.body` variable.
+
+ The contents of the `response.body` variable varies based on the response received
+ from the external source. It is the responsibility of those configuring
+ this expression to understand what is returned from the external source.
+
+ expression must be at least 1 character and must not exceed 1024 characters in length.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ name:
+ description: |-
+ name is a required name of the claim that
+ will be produced and made available during
+ the claim-to-identity mapping process.
+ name must consist of only lowercase alpha characters and underscores ('_').
+ name must be at least 1 character and must not exceed 256 characters in length.
+ maxLength: 256
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must consist of only lowercase alpha
+ characters and underscores
+ rule: self.matches('^[a-z_]+$')
+ required:
+ - expression
+ - name
+ type: object
+ maxItems: 16
+ minItems: 1
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ predicates:
+ description: |-
+ predicates is an optional list of constraints in
+ which claims should attempt to be fetched from this
+ external source.
+
+ When omitted, claims are always fetched
+ from this external source.
+
+ When specified, all predicates must evaluate to 'true'
+ before claims are attempted to be fetched from this external source.
+ predicates must have at least 1 entry and must not exceed 16 entries.
+ Entries must have unique expressions.
+ items:
+ description: |-
+ ExternalSourcePredicate configures a singular condition
+ that must return true before the external source is queried
+ to retrieve external claims.
+ properties:
+ expression:
+ description: |-
+ expression is a required CEL expression that
+ is used to determine whether or not an external
+ source should be used to fetch external claims.
+
+ The expression must return a boolean value,
+ where true means that the source should be consulted
+ and false means that it should not.
+
+ Claims from the token used for the request to the kube-apiserver
+ are made available via the `claims` variable.
+
+ The contents of the `claims` variable varies based on the claims that are
+ present in the token being validated. It is the responsibility of those configuring this
+ field to understand what claims the identity provider includes when issuing tokens.
+
+ expression must be at least 1 character and must not exceed 1024 characters in length.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - expression
+ type: object
+ maxItems: 16
+ minItems: 1
+ type: array
+ x-kubernetes-list-map-keys:
+ - expression
+ x-kubernetes-list-type: map
+ tls:
+ description: |-
+ tls is an optional field that configures the http client TLS
+ settings when fetching external claims from this source.
+
+ When omitted, system default TLS settings will be used
+ for fetching claims from the external source.
+ properties:
+ certificateAuthority:
+ description: |-
+ certificateAuthority is a required reference to a ConfigMap in the openshift-config
+ namespace that contains the CA certificate to use to validate TLS connections with the external claims source.
+ The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+ properties:
+ name:
+ description: |-
+ name is the required name of the ConfigMap that exists in the openshift-config namespace.
+ The key "ca-bundle.crt" must be present and must contain the CA certificate to be used
+ to verify the external source's TLS certificate.
+
+ It must be at least 1 character in length, must not exceed 253 characters in length,
+ must start and end with a lowercase alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or '.'.
+ maxLength: 253
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: name must start and end with a lowercase
+ alphanumeric character, and must only contain
+ lowercase alphanumeric characters, '-' or
+ '.'
+ rule: '!format.dns1123Subdomain().validate(self).hasValue()'
+ required:
+ - name
+ type: object
+ required:
+ - certificateAuthority
+ type: object
+ url:
+ description: |-
+ url is a required configuration of the URL
+ for which the external claims are located.
+ properties:
+ hostname:
+ description: |-
+ hostname is a required hostname for which the external claims are located.
+
+ It must be a valid DNS subdomain name as per RFC1123.
+
+ This means that it must start and end with a lowercase alphanumeric character,
+ must only consist of lowercase alphanumeric characters, '-', and '.'.
+ hostname may optionally specify a port in the format ':{port}'.
+ If a port is specified it must not exceed 65535.
+
+ hostname must be at least 1 character in length.
+ When specifying a port, hostname must not exceed 259 characters in length.
+ When not specifying a port, hostname must not exceed 253 characters in length.
+ maxLength: 259
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: hostname must be a valid hostname
+ rule: isURL('https://'+self)
+ - message: hostname before port must start and end
+ with a lowercase alphanumeric character, and must
+ only contain lowercase alphanumeric characters,
+ '-' or '.'
+ rule: '!format.dns1123Subdomain().validate(self.split('':'')[0]).hasValue()'
+ - message: port must not exceed 65535
+ rule: 'self.split('':'').size() > 1 ? int(self.split('':'')[1])
+ <= 65535 : true'
+ pathExpression:
+ description: |-
+ pathExpression is a required CEL expression that returns a list
+ of string values used to construct the URL path.
+ Claims from the token used for the request to the kube-apiserver
+ are made available via the `claims` variable.
+ expression must be at least 1 character in length and must not exceed 1024 characters in length.
+
+ Values in the returned list will be joined with the hostname using a forward slash
+ (`/`) as a separator. Values in the returned list do not need to include the forward slash.
+ If a forward slash is included in a returned value, it will be encoded as `%2F`.
+
+ Example of a static path configuration:
+
+ pathExpression: ['realms', 'k8s', 'protocol', 'openid-connect', 'userinfo']
+
+ The above example would resolve to the path: '/realms/k8s/protocol/openid-connect/userinfo'
+
+ Example of a dynamic path configuration:
+
+ pathExpression: "['admin', 'realms', 'k8s', 'users'] + [claims.sub] + ['groups']"
+
+ Assuming 'claims.sub' is set to '12345', the above example would resolve to the path: '/admin/realms/k8s/users/12345/groups'
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - hostname
+ - pathExpression
+ type: object
+ required:
+ - mappings
+ - url
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ x-kubernetes-validations:
+ - message: mapping names must be unique across all external
+ claim sources.
+ rule: self.all(s, s.mappings.all(m, self.filter(s2, s2.mappings.exists(m2,
+ m2.name == m.name)).size() == 1))
issuer:
description: issuer is a required field that configures how
the platform interacts with the identity provider and how
diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
index c527e026146..6dc62a87042 100644
--- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
+++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
@@ -40,9 +40,6 @@
{
"name": "Example2"
},
- {
- "name": "ExternalOIDCExternalClaimsSourcing"
- },
{
"name": "ExternalSnapshotMetadata"
},
@@ -234,6 +231,9 @@
{
"name": "ExternalOIDC"
},
+ {
+ "name": "ExternalOIDCExternalClaimsSourcing"
+ },
{
"name": "ExternalOIDCWithUIDAndExtraClaimMappings"
},
diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
index 233599c2005..f250defab58 100644
--- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
+++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
@@ -40,9 +40,6 @@
{
"name": "Example2"
},
- {
- "name": "ExternalOIDCExternalClaimsSourcing"
- },
{
"name": "ExternalSnapshotMetadata"
},
@@ -210,6 +207,9 @@
{
"name": "ExternalOIDC"
},
+ {
+ "name": "ExternalOIDCExternalClaimsSourcing"
+ },
{
"name": "ExternalOIDCWithUIDAndExtraClaimMappings"
},