From 83696fd023204ddc6d05503b07825fd8c7d3dd5d Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Fri, 18 Jul 2025 12:22:06 -0700 Subject: [PATCH] improve errors and docs for JWTAuthenticator features, with int tests --- .../v1alpha1/types_jwtauthenticator.go.tmpl | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.26/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.27/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.28/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.29/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.30/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.31/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.32/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/1.33/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- ...cierge.pinniped.dev_jwtauthenticators.yaml | 61 ++- generated/latest/README.adoc | 61 ++- .../v1alpha1/types_jwtauthenticator.go | 62 ++- .../jwtcachefiller/jwtcachefiller.go | 38 +- .../jwtcachefiller/jwtcachefiller_test.go | 63 ++- .../concierge_jwtauthenticator_status_test.go | 378 ++++++++++++++++-- 31 files changed, 1787 insertions(+), 410 deletions(-) diff --git a/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go.tmpl b/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go.tmpl index 8d416bcbf..6c782b5ce 100644 --- a/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go.tmpl +++ b/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go.tmpl @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/deploy/concierge/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/deploy/concierge/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/deploy/concierge/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/deploy/concierge/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.26/README.adoc b/generated/1.26/README.adoc index 0983f1dc9..b80bc78a9 100644 --- a/generated/1.26/README.adoc +++ b/generated/1.26/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.26/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.26/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.26/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.26/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.26/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.26/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.26/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.26/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.27/README.adoc b/generated/1.27/README.adoc index ba630e361..c485b28f2 100644 --- a/generated/1.27/README.adoc +++ b/generated/1.27/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.27/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.27/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.27/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.27/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.27/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.27/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.27/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.27/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.28/README.adoc b/generated/1.28/README.adoc index 42d652eeb..92e119a98 100644 --- a/generated/1.28/README.adoc +++ b/generated/1.28/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.28/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.28/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.28/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.28/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.28/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.28/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.28/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.28/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.29/README.adoc b/generated/1.29/README.adoc index 2b5102cf5..ddb30051b 100644 --- a/generated/1.29/README.adoc +++ b/generated/1.29/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.29/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.29/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.29/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.29/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.29/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.29/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.29/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.29/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.30/README.adoc b/generated/1.30/README.adoc index 3c64b7b2d..171e02987 100644 --- a/generated/1.30/README.adoc +++ b/generated/1.30/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.30/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.30/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.30/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.30/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.30/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.30/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.30/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.30/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.31/README.adoc b/generated/1.31/README.adoc index d05ca7c5d..09eda657f 100644 --- a/generated/1.31/README.adoc +++ b/generated/1.31/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.31/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.31/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.31/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.31/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.31/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.31/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.31/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.31/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.32/README.adoc b/generated/1.32/README.adoc index ab808e660..d545aeb41 100644 --- a/generated/1.32/README.adoc +++ b/generated/1.32/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-32-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-32-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.32/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.32/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.32/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.32/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.32/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.32/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.32/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.32/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/1.33/README.adoc b/generated/1.33/README.adoc index 5796e1366..f8805ee9c 100644 --- a/generated/1.33/README.adoc +++ b/generated/1.33/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-33-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-33-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/1.33/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/1.33/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/1.33/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/1.33/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/generated/1.33/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/generated/1.33/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml index 057c8d7b8..4fa9acc3e 100644 --- a/generated/1.33/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ b/generated/1.33/crds/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -78,7 +78,6 @@ spec: claim: description: |- claim is the name of a required claim. - Same as --oidc-required-claim flag. Only string claim keys are supported. Mutually exclusive with expression and message. type: string @@ -106,7 +105,6 @@ spec: requiredValue: description: |- requiredValue is the value of a required claim. - Same as --oidc-required-claim flag. Only string claim values are supported. If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. Mutually exclusive with expression and message. @@ -120,18 +118,44 @@ spec: properties: extra: description: |- - extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - the Kubernetes API server does not have any mechanism for transmitting auth extras via client - certificates. When configured, these extras will appear in client certificates issued by the - Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - extras. This is probably only useful if you are using a custom authenticating proxy in front - of your Kubernetes API server which can translate these OUs into auth extras, as described by + extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + However, note that the Pinniped Concierge issues client certificates to users for the purpose + of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + auth extras via client certificates. When configured, these extras will appear in client + certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + Kubernetes will ignore these extras. This is probably only useful if you are using a custom + authenticating proxy in front of your Kubernetes API server which can translate these OUs into + auth extras, as described by https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. This is an advanced configuration option. During an end-user login flow, each of these CEL expressions must evaluate to either a string or an array of strings, or else the user's login will fail. + + These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + expression must produce a string or string array value. + If the value is empty, the extra mapping will not be present. + + Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + hard-coded extra key/value + - key: "acme.io/foo" + valueExpression: "'bar'" + This will result in an extra attribute - acme.io/foo: ["bar"] + + hard-coded key, value copying claim value + - key: "acme.io/foo" + valueExpression: "claims.some_claim" + This will result in an extra attribute - acme.io/foo: [value of some_claim] + + hard-coded key, value derived from claim value + - key: "acme.io/admin" + valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + This will result in: + - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added items: description: ExtraMapping provides the configuration for a single extra mapping. @@ -144,6 +168,7 @@ spec: be valid HTTP Path characters as defined by RFC 3986. key must be lowercase. Required to be unique. + Additionally, the key must not contain an equals sign ("="). type: string valueExpression: description: |- @@ -176,9 +201,14 @@ spec: groupsExpression: description: |- groupsExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's group memberships. + groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to one of the expected types without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + The expression must produce a string or string array value. "", [], and null values are treated as the group mapping not being present. @@ -204,9 +234,14 @@ spec: usernameExpression: description: |- usernameExpression represents an expression which will be evaluated by CEL. - The expression's result will become the user's username. + usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to the expected type without errors, or else the user's login will fail. + Additionally, mistakes in this configuration can cause the users to have unintended usernames. + The expression must produce a non-empty string value. If the expression uses 'claims.email', then 'claims.email_verified' must be used in the expression or extra[*].valueExpression or claimValidationRules[*].expression. diff --git a/generated/latest/README.adoc b/generated/latest/README.adoc index 5796e1366..f8805ee9c 100644 --- a/generated/latest/README.adoc +++ b/generated/latest/README.adoc @@ -74,11 +74,9 @@ ClaimValidationRule provides the configuration for a single claim validation rul |=== | Field | Description | *`claim`* __string__ | claim is the name of a required claim. + -Same as --oidc-required-claim flag. + Only string claim keys are supported. + Mutually exclusive with expression and message. + | *`requiredValue`* __string__ | requiredValue is the value of a required claim. + -Same as --oidc-required-claim flag. + Only string claim values are supported. + If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. + Mutually exclusive with expression and message. + @@ -119,6 +117,7 @@ subdomain as defined by RFC 1123. All characters trailing the first "/" must + be valid HTTP Path characters as defined by RFC 3986. + key must be lowercase. + Required to be unique. + +Additionally, the key must not contain an equals sign ("="). + | *`valueExpression`* __string__ | valueExpression is a CEL expression to extract extra attribute value. + valueExpression must produce a string or string array value. + "", [], and null values are treated as the extra mapping not being present. + @@ -244,9 +243,14 @@ unless usernameExpression is specified. + Mutually exclusive with usernameExpression. Use either username or usernameExpression to + determine the user's username from the JWT token. + | *`usernameExpression`* __string__ | usernameExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's username. + +usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to the expected type without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended usernames. + + The expression must produce a non-empty string value. + If the expression uses 'claims.email', then 'claims.email_verified' must be used in + the expression or extra[*].valueExpression or claimValidationRules[*].expression. + @@ -271,9 +275,14 @@ unless groupsExpression is specified. + Mutually exclusive with groupsExpression. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + | *`groupsExpression`* __string__ | groupsExpression represents an expression which will be evaluated by CEL. + - The expression's result will become the user's group memberships. + +groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + +This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + +must evaluate to one of the expected types without errors, or else the user's login will fail. + +Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + + The expression must produce a string or string array value. + "", [], and null values are treated as the group mapping not being present. + @@ -286,18 +295,44 @@ Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + Mutually exclusive with groups. Use either groups or groupsExpression to + determine the user's group membership from the JWT token. + -| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-33-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in + -https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the + -Pinniped Concierge issues client certificates to users for the purpose of authenticating, and + -the Kubernetes API server does not have any mechanism for transmitting auth extras via client + -certificates. When configured, these extras will appear in client certificates issued by the + -Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this + -client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these + -extras. This is probably only useful if you are using a custom authenticating proxy in front + -of your Kubernetes API server which can translate these OUs into auth extras, as described by + +| *`extra`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-33-apis-concierge-authentication-v1alpha1-extramapping[$$ExtraMapping$$] array__ | extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + +as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + + +However, note that the Pinniped Concierge issues client certificates to users for the purpose + +of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + +auth extras via client certificates. When configured, these extras will appear in client + +certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + +Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + +Kubernetes will ignore these extras. This is probably only useful if you are using a custom + +authenticating proxy in front of your Kubernetes API server which can translate these OUs into + +auth extras, as described by + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. + This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + must evaluate to either a string or an array of strings, or else the user's login will fail. + + +These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + + +expression must produce a string or string array value. + +If the value is empty, the extra mapping will not be present. + + +Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + + +hard-coded extra key/value + +- key: "acme.io/foo" + +valueExpression: "'bar'" + +This will result in an extra attribute - acme.io/foo: ["bar"] + + +hard-coded key, value copying claim value + +- key: "acme.io/foo" + +valueExpression: "claims.some_claim" + +This will result in an extra attribute - acme.io/foo: [value of some_claim] + + +hard-coded key, value derived from claim value + +- key: "acme.io/admin" + +valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + +This will result in: + +- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + +- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + |=== diff --git a/generated/latest/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go b/generated/latest/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go index 8d416bcbf..6c782b5ce 100644 --- a/generated/latest/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go +++ b/generated/latest/apis/concierge/authentication/v1alpha1/types_jwtauthenticator.go @@ -77,14 +77,12 @@ type JWTAuthenticatorSpec struct { // ClaimValidationRule provides the configuration for a single claim validation rule. type ClaimValidationRule struct { // claim is the name of a required claim. - // Same as --oidc-required-claim flag. // Only string claim keys are supported. // Mutually exclusive with expression and message. // +optional Claim string `json:"claim,omitempty"` // requiredValue is the value of a required claim. - // Same as --oidc-required-claim flag. // Only string claim values are supported. // If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string. // Mutually exclusive with expression and message. @@ -147,9 +145,14 @@ type JWTTokenClaims struct { Username string `json:"username"` // usernameExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's username. // + // usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to the expected type without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended usernames. + // // The expression must produce a non-empty string value. // If the expression uses 'claims.email', then 'claims.email_verified' must be used in // the expression or extra[*].valueExpression or claimValidationRules[*].expression. @@ -180,9 +183,14 @@ type JWTTokenClaims struct { Groups string `json:"groups"` // groupsExpression represents an expression which will be evaluated by CEL. - // // The expression's result will become the user's group memberships. // + // groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions + // must evaluate to one of the expected types without errors, or else the user's login will fail. + // Additionally, mistakes in this configuration can cause the users to have unintended group memberships. + // // The expression must produce a string or string array value. // "", [], and null values are treated as the group mapping not being present. // @@ -198,18 +206,45 @@ type JWTTokenClaims struct { // +optional GroupsExpression string `json:"groupsExpression,omitempty"` - // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration as documented in - // https://kubernetes.io/docs/reference/access-authn-authz/authentication. However, note that the - // Pinniped Concierge issues client certificates to users for the purpose of authenticating, and - // the Kubernetes API server does not have any mechanism for transmitting auth extras via client - // certificates. When configured, these extras will appear in client certificates issued by the - // Pinniped Supervisor in the x509 Subject field as Organizational Units (OU). However, when this - // client certificate is presented to Kubernetes for authentication, Kubernetes will ignore these - // extras. This is probably only useful if you are using a custom authenticating proxy in front - // of your Kubernetes API server which can translate these OUs into auth extras, as described by + // extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration + // as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication. + // + // However, note that the Pinniped Concierge issues client certificates to users for the purpose + // of authenticating, and the Kubernetes API server does not have any mechanism for transmitting + // auth extras via client certificates. When configured, these extras will appear in client + // certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational + // Units (OU). However, when this client certificate is presented to Kubernetes for authentication, + // Kubernetes will ignore these extras. This is probably only useful if you are using a custom + // authenticating proxy in front of your Kubernetes API server which can translate these OUs into + // auth extras, as described by // https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy. // This is an advanced configuration option. During an end-user login flow, each of these CEL expressions // must evaluate to either a string or an array of strings, or else the user's login will fail. + // + // These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("="). + // + // expression must produce a string or string array value. + // If the value is empty, the extra mapping will not be present. + // + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // hard-coded extra key/value + // - key: "acme.io/foo" + // valueExpression: "'bar'" + // This will result in an extra attribute - acme.io/foo: ["bar"] + // + // hard-coded key, value copying claim value + // - key: "acme.io/foo" + // valueExpression: "claims.some_claim" + // This will result in an extra attribute - acme.io/foo: [value of some_claim] + // + // hard-coded key, value derived from claim value + // - key: "acme.io/admin" + // valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""' + // This will result in: + // - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"] + // - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added + // // +optional Extra []ExtraMapping `json:"extra,omitempty"` } @@ -222,6 +257,7 @@ type ExtraMapping struct { // be valid HTTP Path characters as defined by RFC 3986. // key must be lowercase. // Required to be unique. + // Additionally, the key must not contain an equals sign ("="). // +required Key string `json:"key"` diff --git a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go index 1469b69e6..c99a62a0c 100644 --- a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go +++ b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go @@ -680,13 +680,18 @@ func (c *jwtCacheFillerController) newCachedJWTAuthenticator( for i, mapping := range spec.Claims.Extra { if strings.Contains(mapping.Key, "=") { // Use the same field path that ValidateAuthenticationConfiguration() would build, for consistency. - fieldPath := field.NewPath("jwt").Index(0).Child("claimMappings").Child("extra").Index(i) - errList = append(errList, field.Invalid(fieldPath, "", "Pinniped does not allow extra key names to contain equals sign")) + fieldPath := field.NewPath("jwt").Index(0). + Child("claimMappings"). + Child("extra").Index(i). + Child("key") + errList = append(errList, field.Invalid(fieldPath, mapping.Key, + "Pinniped does not allow extra key names to contain equals sign", + )) } } if errList != nil { - rewriteJWTAuthenticatorErrorPrefixes(errList) + rewriteJWTAuthenticatorErrors(errList) errText := "could not initialize jwt authenticator" err := errList.ToAggregate() @@ -740,18 +745,35 @@ func (c *jwtCacheFillerController) newCachedJWTAuthenticator( }, conditions, nil } -// We don't have any control over the error prefixes created by ValidateAuthenticationConfiguration(), but we +// We don't have any control over the error strings created by ValidateAuthenticationConfiguration(), but we // can rewrite them to make them more consistent with our JWTAuthenticator CRD field names where they don't agree. -func rewriteJWTAuthenticatorErrorPrefixes(errList field.ErrorList) { +func rewriteJWTAuthenticatorErrors(errList field.ErrorList) { // ValidateAuthenticationConfiguration() will prefix all our errors with "jwt[0]." because we always pass it // exactly one jwtAuthenticator to validate. undesirablePrefix := fmt.Sprintf("%s.", field.NewPath("jwt").Index(0).String()) + // Replace these to make the spec names consistent with how they are named in the JWTAuthenticator CRD. + replacements := []struct { + str string + repl string + }{ + // replace these more specific strings first + {str: "claimMappings.username.expression", repl: "claims.usernameExpression"}, + {str: "claimMappings.groups.expression", repl: "claims.groupsExpression"}, + + // then replace these less specific strings (substrings of the strings above) if they still exist + {str: "claimMappings.username", repl: "claims.username"}, + {str: "claimMappings.groups", repl: "claims.groups"}, + + // and also replace this one + {str: "claimMappings.extra", repl: "claims.extra"}, + } + for _, err := range errList { err.Field = strings.TrimPrefix(err.Field, undesirablePrefix) - if strings.HasPrefix(err.Field, "claimMappings.") { - // Pinniped's CRD calls this field "claims". Otherwise, our field names are the same. - err.Field = strings.Replace(err.Field, "claimMappings.", "claims.", 1) + for _, spec := range replacements { + err.Field = strings.ReplaceAll(err.Field, spec.str, spec.repl) + err.Detail = strings.ReplaceAll(err.Detail, spec.str, spec.repl) } } } diff --git a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go index 4ea127c3d..877acfe65 100644 --- a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go +++ b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go @@ -440,12 +440,24 @@ func TestController(t *testing.T) { GroupsExpression: `["group1"]`, }, } + invalidClaimsUsernameExpressUsesClaimsDotEmailWrongJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: goodIssuer, + Audience: goodAudience, + TLS: goodOIDCIssuerServerTLSSpec, + Claims: authenticationv1alpha1.JWTTokenClaims{ + UsernameExpression: "claims.email", + }, + } invalidClaimsExtraContainsEqualSignJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{ Issuer: goodIssuer, Audience: goodAudience, TLS: goodOIDCIssuerServerTLSSpec, Claims: authenticationv1alpha1.JWTTokenClaims{ Extra: []authenticationv1alpha1.ExtraMapping{ + { + Key: "example.com/legal-key", + ValueExpression: `"extra-value"`, + }, { Key: "example.com/key=contains-equals-sign", // this should cause a validation error in our own code ValueExpression: `"extra-value"`, @@ -2755,6 +2767,55 @@ func TestController(t *testing.T) { } }, }, + { + name: "newCachedJWTAuthenticator: validateAuthenticationConfiguration: when usernameExpression uses claims.email without using claims.email_verified elsewhere: loop will fail sync, will write failed and unknown status conditions, but will not enqueue a resync due to user config error", + jwtAuthenticators: []runtime.Object{ + &authenticationv1alpha1.JWTAuthenticator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-name", + }, + Spec: *invalidClaimsUsernameExpressUsesClaimsDotEmailWrongJWTAuthenticatorSpec, + }, + }, + wantLogLines: []string{ + fmt.Sprintf(`{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","logger":"jwtcachefiller-controller","caller":"jwtcachefiller/jwtcachefiller.go:$jwtcachefiller.(*jwtCacheFillerController).syncIndividualJWTAuthenticator","message":"invalid jwt authenticator","jwtAuthenticator":"test-name","issuer":"%s","removedFromCache":false}`, invalidClaimsUsernameExpressUsesClaimsDotEmailWrongJWTAuthenticatorSpec.Issuer), + fmt.Sprintf(`{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","logger":"jwtcachefiller-controller","caller":"jwtcachefiller/jwtcachefiller.go:$jwtcachefiller.(*jwtCacheFillerController).updateStatus","message":"jwtauthenticator status successfully updated","jwtAuthenticator":"test-name","issuer":"%s","phase":"Error"}`, invalidClaimsUsernameExpressUsesClaimsDotEmailWrongJWTAuthenticatorSpec.Issuer), + }, + wantActions: func() []coretesting.Action { + updateStatusAction := coretesting.NewUpdateAction(jwtAuthenticatorsGVR, "", &authenticationv1alpha1.JWTAuthenticator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-name", + }, + Spec: *invalidClaimsUsernameExpressUsesClaimsDotEmailWrongJWTAuthenticatorSpec, + Status: authenticationv1alpha1.JWTAuthenticatorStatus{ + Conditions: conditionstestutil.Replace( + allHappyConditionsSuccess(goodIssuer, frozenMetav1Now, 0), + []metav1.Condition{ + sadReadyCondition(frozenMetav1Now, 0), + happyIssuerURLValid(frozenMetav1Now, 0), + happyDiscoveryURLValid(frozenMetav1Now, 0), + sadAuthenticatorValid( + `could not initialize jwt authenticator: claims.usernameExpression: Invalid value: "claims.email": `+ + `claims.email_verified must be used in claims.usernameExpression or claims.extra[*].valueExpression or `+ + `claimValidationRules[*].expression when claims.email is used in claims.usernameExpression`, + frozenMetav1Now, + 0, + ), + happyJWKSURLValid(frozenMetav1Now, 0), + happyJWKSFetch(frozenMetav1Now, 0), + }, + ), + Phase: "Error", + }, + }) + updateStatusAction.Subresource = "status" + return []coretesting.Action{ + coretesting.NewListAction(jwtAuthenticatorsGVR, jwtAUthenticatorGVK, "", metav1.ListOptions{}), + coretesting.NewWatchAction(jwtAuthenticatorsGVR, "", metav1.ListOptions{Watch: true}), + updateStatusAction, + } + }, + }, { name: "newCachedJWTAuthenticator: when any claims.extra[].key contains an equals sign: loop will fail sync, will write failed and unknown status conditions, but will not enqueue a resync due to user config error", jwtAuthenticators: []runtime.Object{ @@ -2783,7 +2844,7 @@ func TestController(t *testing.T) { happyIssuerURLValid(frozenMetav1Now, 0), happyDiscoveryURLValid(frozenMetav1Now, 0), sadAuthenticatorValid( - `could not initialize jwt authenticator: claims.extra[0]: Invalid value: "": Pinniped does not allow extra key names to contain equals sign`, + `could not initialize jwt authenticator: claims.extra[1].key: Invalid value: "example.com/key=contains-equals-sign": Pinniped does not allow extra key names to contain equals sign`, frozenMetav1Now, 0, ), diff --git a/test/integration/concierge_jwtauthenticator_status_test.go b/test/integration/concierge_jwtauthenticator_status_test.go index 2a34d5816..9049f48e0 100644 --- a/test/integration/concierge_jwtauthenticator_status_test.go +++ b/test/integration/concierge_jwtauthenticator_status_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 the Pinniped contributors. All Rights Reserved. +// Copyright 2024-2025 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration @@ -322,6 +322,308 @@ func TestConciergeJWTAuthenticatorStatus_Parallel(t *testing.T) { }, ), }, + { + name: "claims cannot use both username and usernameExpression", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + Claims: authenticationv1alpha1.JWTTokenClaims{ + Username: "foo", + UsernameExpression: "bar", + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: `could not initialize jwt authenticator: claims.username: Invalid value: "": claim and expression can't both be set`, + }, + }, + ), + }, + { + name: "claims cannot use both groups and groupsExpression", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + Claims: authenticationv1alpha1.JWTTokenClaims{ + Groups: "foo", + GroupsExpression: "bar", + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: `could not initialize jwt authenticator: claims.groups: Invalid value: "": claim and expression can't both be set`, + }, + }, + ), + }, + { + name: "username claim expression cannot use clams.email unless it also uses claims.email_verified elsewhere", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + Claims: authenticationv1alpha1.JWTTokenClaims{ + UsernameExpression: "claims.email", + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: `could not initialize jwt authenticator: claims.usernameExpression: Invalid value: "claims.email": ` + + `claims.email_verified must be used in claims.usernameExpression or claims.extra[*].valueExpression or ` + + `claimValidationRules[*].expression when claims.email is used in claims.usernameExpression`, + }, + }, + ), + }, + { + name: "username claim expression cannot use invalid CEL expression", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + Claims: authenticationv1alpha1.JWTTokenClaims{ + UsernameExpression: "this is not a valid CEL expression", + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: "could not initialize jwt authenticator: claims.usernameExpression: Invalid value: " + + "\"this is not a valid CEL expression\": compilation failed: ERROR: :1:6: Syntax error: mismatched input 'is' expecting \n" + + " | this is not a valid CEL expression\n" + + " | .....^", + }, + }, + ), + }, + { + name: "groups claim expression cannot use invalid CEL expression", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + Claims: authenticationv1alpha1.JWTTokenClaims{ + GroupsExpression: "this is not a valid CEL expression", + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: "could not initialize jwt authenticator: claims.groupsExpression: Invalid value: " + + "\"this is not a valid CEL expression\": compilation failed: ERROR: :1:6: Syntax error: mismatched input 'is' expecting \n" + + " | this is not a valid CEL expression\n" + + " | .....^", + }, + }, + ), + }, + { + name: "extra keys cannot have equal sign and must be domain-prefixed path", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + Claims: authenticationv1alpha1.JWTTokenClaims{ + Extra: []authenticationv1alpha1.ExtraMapping{ + { + Key: "a=b", + ValueExpression: `"value"`, + }, + }, + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: `could not initialize jwt authenticator: [` + + `claims.extra[0].key: Invalid value: "a=b": must be a domain-prefixed path (such as "acme.io/foo"), ` + + `claims.extra[0].key: Invalid value: "a=b": Pinniped does not allow extra key names to contain equals sign]`, + }, + }, + ), + }, + { + name: "claimValidationRules claim and requiredValue are mutually exclusive with expression and message", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + ClaimValidationRules: []authenticationv1alpha1.ClaimValidationRule{ + { + Claim: "foo", + RequiredValue: "bar", + Expression: "baz", + Message: "bat", + }, + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: `could not initialize jwt authenticator: claimValidationRules[0]: Invalid value: "foo": claim and expression can't both be set`, + }, + }, + ), + }, + { + name: "claimValidationRules cannot use invalid CEL expressions", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + ClaimValidationRules: []authenticationv1alpha1.ClaimValidationRule{ + { + Expression: "this is not a valid CEL expression", + }, + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: "could not initialize jwt authenticator: claimValidationRules[0].expression: Invalid value: " + + "\"this is not a valid CEL expression\": compilation failed: ERROR: :1:6: Syntax error: mismatched input 'is' expecting \n" + + " | this is not a valid CEL expression\n" + + " | .....^", + }, + }, + ), + }, + { + name: "userValidationRules must use valid CEL expressions", + spec: authenticationv1alpha1.JWTAuthenticatorSpec{ + Issuer: env.SupervisorUpstreamOIDC.Issuer, + Audience: "some-fake-audience", + TLS: &authenticationv1alpha1.TLSSpec{ + CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)), + }, + UserValidationRules: []authenticationv1alpha1.UserValidationRule{ + { + Expression: "this is not a valid CEL expression", + }, + }, + }, + wantPhase: authenticationv1alpha1.JWTAuthenticatorPhaseError, + wantConditions: replaceSomeConditions(t, + allSuccessfulJWTAuthenticatorConditions(len(env.SupervisorUpstreamOIDC.CABundle) != 0), + []metav1.Condition{ + { + Type: "Ready", + Status: "False", + Reason: "NotReady", + Message: "the JWTAuthenticator is not ready: see other conditions for details", + }, { + Type: "AuthenticatorValid", + Status: "False", + Reason: "InvalidAuthenticator", + Message: "could not initialize jwt authenticator: userValidationRules[0].expression: Invalid value: " + + "\"this is not a valid CEL expression\": compilation failed: ERROR: :1:6: Syntax error: mismatched input 'is' expecting \n" + + " | this is not a valid CEL expression\n" + + " | .....^", + }, + }, + ), + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -479,40 +781,42 @@ func allSuccessfulJWTAuthenticatorConditions(caBundleExists bool) []metav1.Condi if caBundleExists { tlsConfigValidMsg = "spec.tls is valid: using configured CA bundle" } - return []metav1.Condition{{ - Type: "AuthenticatorValid", - Status: "True", - Reason: "Success", - Message: "authenticator initialized", - }, { - Type: "DiscoveryURLValid", - Status: "True", - Reason: "Success", - Message: "discovery performed successfully", - }, { - Type: "IssuerURLValid", - Status: "True", - Reason: "Success", - Message: "issuer is a valid URL", - }, { - Type: "JWKSFetchValid", - Status: "True", - Reason: "Success", - Message: "successfully fetched jwks", - }, { - Type: "JWKSURLValid", - Status: "True", - Reason: "Success", - Message: "jwks_uri is a valid URL", - }, { - Type: "Ready", - Status: "True", - Reason: "Success", - Message: "the JWTAuthenticator is ready", - }, { - Type: "TLSConfigurationValid", - Status: "True", - Reason: "Success", - Message: tlsConfigValidMsg, - }} + return []metav1.Condition{ + { + Type: "AuthenticatorValid", + Status: "True", + Reason: "Success", + Message: "authenticator initialized", + }, { + Type: "DiscoveryURLValid", + Status: "True", + Reason: "Success", + Message: "discovery performed successfully", + }, { + Type: "IssuerURLValid", + Status: "True", + Reason: "Success", + Message: "issuer is a valid URL", + }, { + Type: "JWKSFetchValid", + Status: "True", + Reason: "Success", + Message: "successfully fetched jwks", + }, { + Type: "JWKSURLValid", + Status: "True", + Reason: "Success", + Message: "jwks_uri is a valid URL", + }, { + Type: "Ready", + Status: "True", + Reason: "Success", + Message: "the JWTAuthenticator is ready", + }, { + Type: "TLSConfigurationValid", + Status: "True", + Reason: "Success", + Message: tlsConfigValidMsg, + }, + } }