Skip to content

Commit 864ac8b

Browse files
authored
Merge pull request #45108 from aramase/aramase/d/kep_3331_beta_docs
Add docs for Structured Authn beta
2 parents 5f50b28 + b35e434 commit 864ac8b

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

content/en/docs/reference/access-authn-authz/authentication.md

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -329,19 +329,42 @@ To enable the plugin, configure the following flags on the API server:
329329
| `--oidc-ca-file` | The path to the certificate for the CA that signed your identity provider's web certificate. Defaults to the host's root CAs. | `/etc/kubernetes/ssl/kc-ca.pem` | No |
330330
| `--oidc-signing-algs` | The signing algorithms accepted. Default is "RS256". | `RS512` | No |
331331

332-
##### Using Authentication Configuration
332+
##### Authentication configuration from a file {#using-authentication-configuration}
333333

334-
{{< feature-state for_k8s_version="v1.29" state="alpha" >}}
334+
{{< feature-state feature_gate_name="StructuredAuthenticationConfiguration" >}}
335335

336336
JWT Authenticator is an authenticator to authenticate Kubernetes users using JWT compliant tokens. The authenticator will attempt to
337337
parse a raw ID token, verify it's been signed by the configured issuer. The public key to verify the signature is discovered from the issuer's public endpoint using OIDC discovery.
338338

339-
The API server can be configured to use a JWT authenticator via the `--authentication-config` flag. This flag takes a path to a file containing the `AuthenticationConfiguration`. An example configuration is provided below.
340-
To use this config, the `StructuredAuthenticationConfiguration` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
341-
has to be enabled.
339+
The minimum valid JWT payload must contain the following claims:
340+
```yaml
341+
{
342+
"iss": "https://example.com", // must match the issuer.url
343+
"aud": ["my-app"], // at least one of the entries in issuer.audiences must match the "aud" claim in presented JWTs.
344+
"exp": 1234567890, // token expiration as Unix time (the number of seconds elapsed since January 1, 1970 UTC)
345+
"<username-claim>": "user" // this is the username claim configured in the claimMappings.username.claim or claimMappings.username.expression
346+
}
347+
```
348+
349+
The configuration file approach allows you to configure multiple JWT authenticators, each with a unique `issuer.url` and `issuer.discoveryURL`. The configuration file even allows you to specify [CEL](/docs/reference/using-api/cel/)
350+
expressions to map claims to user attributes, and to validate claims and user information. The API server also automatically reloads the authenticators when the configuration file is modified. You can use
351+
`apiserver_authentication_config_controller_automatic_reload_last_timestamp_seconds` metric to monitor the last time the configuration was reloaded by the API server.
352+
353+
You must specify the path to the authentication configuration using the `--authentication-config` flag on the API server. If you want to use command line flags instead of the configuration file, those will continue to work as-is.
354+
To access the new capabilities like configuring multiple authenticators, setting multiple audiences for an issuer, switch to using the configuration file.
355+
356+
For Kubernetes v{{< skew currentVersion >}}, the structured authentication configuration file format
357+
is beta-level, and the mechanism for using that configuration is also beta. Provided you didn't specifically
358+
disable the `StructuredAuthenticationConfiguration`
359+
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) for your cluster,
360+
you can turn on structured authentication by specifying the `--authentication-config` command line
361+
argument to the kube-apiserver. An example of the structured authentication configuration file is shown below.
342362

343363
{{< note >}}
344-
When the feature is enabled, setting both `--authentication-config` and any of the `--oidc-*` flags will result in an error. If you want to use the feature, you have to remove the `--oidc-*` flags and use the configuration file instead.
364+
If you specify `--authentication-config` along with any of the `--oidc-*` command line arguments, this is
365+
a misconfiguration. In this situation, the API server reports an errors and then immediately exits.
366+
If you want to switch to using structured authentication configuration, you have to remove the `--oidc-*`
367+
command line arguments, and use the configuration file instead.
345368
{{< /note >}}
346369

347370
```yaml
@@ -350,14 +373,33 @@ When the feature is enabled, setting both `--authentication-config` and any of t
350373
# CAUTION: this is an example configuration.
351374
# Do not use this for your own cluster!
352375
#
353-
apiVersion: apiserver.config.k8s.io/v1alpha1
376+
apiVersion: apiserver.config.k8s.io/v1beta1
354377
kind: AuthenticationConfiguration
355378
# list of authenticators to authenticate Kubernetes users using JWT compliant tokens.
379+
# the maximum number of allowed authenticators is 64.
356380
jwt:
357381
- issuer:
382+
# url must be unique across all authenticators.
383+
# url must not conflict with issuer configured in --service-account-issuer.
358384
url: https://example.com # Same as --oidc-issuer-url.
385+
# discoveryURL, if specified, overrides the URL used to fetch discovery
386+
# information instead of using "{url}/.well-known/openid-configuration".
387+
# The exact value specified is used, so "/.well-known/openid-configuration"
388+
# must be included in discoveryURL if needed.
389+
#
390+
# The "issuer" field in the fetched discovery information must match the "issuer.url" field
391+
# in the AuthenticationConfiguration and will be used to validate the "iss" claim in the presented JWT.
392+
# This is for scenarios where the well-known and jwks endpoints are hosted at a different
393+
# location than the issuer (such as locally in the cluster).
394+
# discoveryURL must be different from url if specified and must be unique across all authenticators.
395+
discoveryURL: https://discovery.example.com/.well-known/openid-configuration
396+
# audiences is the set of acceptable audiences the JWT must be issued to.
397+
# At least one of the entries must match the "aud" claim in presented JWTs.
359398
audiences:
360399
- my-app # Same as --oidc-client-id.
400+
- my-other-app
401+
# this is required to be set to "MatchAny" when multiple audiences are specified.
402+
audienceMatchPolicy: MatchAny
361403
# rules applied to validate token claims to authenticate users.
362404
claimValidationRules:
363405
# Same as --oidc-required-claim key=value.
@@ -383,6 +425,13 @@ jwt:
383425
prefix: ""
384426
# Mutually exclusive with username.claim and username.prefix.
385427
# expression is a CEL expression that evaluates to a string.
428+
#
429+
# 1. If username.expression uses 'claims.email', then 'claims.email_verified' must be used in
430+
# username.expression or extra[*].valueExpression or claimValidationRules[*].expression.
431+
# An example claim validation rule expression that matches the validation automatically
432+
# applied when username.claim is set to 'email' is 'claims.?email_verified.orValue(true)'.
433+
# 2. If the username asserted based on username.expression is the empty string, the authentication
434+
# request will fail.
386435
expression: 'claims.username + ":external-user"'
387436
# groups represents an option for the groups attribute.
388437
groups:
@@ -442,7 +491,7 @@ jwt:
442491
{{< tabs name="example_configuration" >}}
443492
{{% tab name="Valid token" %}}
444493
```yaml
445-
apiVersion: apiserver.config.k8s.io/v1alpha1
494+
apiVersion: apiserver.config.k8s.io/v1beta1
446495
kind: AuthenticationConfiguration
447496
jwt:
448497
- issuer:
@@ -502,7 +551,7 @@ jwt:
502551
{{% /tab %}}
503552
{{% tab name="Fails claim validation" %}}
504553
```yaml
505-
apiVersion: apiserver.config.k8s.io/v1alpha1
554+
apiVersion: apiserver.config.k8s.io/v1beta1
506555
kind: AuthenticationConfiguration
507556
jwt:
508557
- issuer:
@@ -550,7 +599,7 @@ jwt:
550599
{{% /tab %}}
551600
{{% tab name="Fails user validation" %}}
552601
```yaml
553-
apiVersion: apiserver.config.k8s.io/v1alpha1
602+
apiVersion: apiserver.config.k8s.io/v1beta1
554603
kind: AuthenticationConfiguration
555604
jwt:
556605
- issuer:
@@ -614,12 +663,10 @@ jwt:
614663
{{% /tab %}}
615664
{{< /tabs >}}
616665

617-
Importantly, the API server is not an OAuth2 client, rather it can only be
618-
configured to trust a single issuer. This allows the use of public providers,
619-
such as Google, without trusting credentials issued to third parties. Admins who
620-
wish to utilize multiple OAuth clients should explore providers which support the
621-
`azp` (authorized party) claim, a mechanism for allowing one client to issue
622-
tokens on behalf of another.
666+
###### Limitations
667+
668+
1. Distributed claims do not work via [CEL](/docs/reference/using-api/cel/) expressions.
669+
1. Egress selector configuration is not supported for calls to `issuer.url` and `issuer.discoveryURL`.
623670

624671
Kubernetes does not provide an OpenID Connect Identity Provider.
625672
You can use an existing public OpenID Connect Identity Provider (such as Google, or
@@ -631,9 +678,15 @@ Tremolo Security's [OpenUnison](https://openunison.github.io/).
631678

632679
For an identity provider to work with Kubernetes it must:
633680

634-
1. Support [OpenID connect discovery](https://openid.net/specs/openid-connect-discovery-1_0.html); not all do.
635-
1. Run in TLS with non-obsolete ciphers
636-
1. Have a CA signed certificate (even if the CA is not a commercial CA or is self signed)
681+
1. Support [OpenID connect discovery](https://openid.net/specs/openid-connect-discovery-1_0.html)
682+
683+
The public key to verify the signature is discovered from the issuer's public endpoint using OIDC discovery.
684+
If you're using the authentication configuration file, the identity provider doesn't need to publicly expose the discovery endpoint.
685+
You can host the discovery endpoint at a different location than the issuer (such as locally in the cluster) and specify the
686+
`issuer.discoveryURL` in the configuration file.
687+
688+
2. Run in TLS with non-obsolete ciphers
689+
3. Have a CA signed certificate (even if the CA is not a commercial CA or is self signed)
637690

638691
A note about requirement #3 above, requiring a CA signed certificate. If you deploy your own
639692
identity provider (as opposed to one of the cloud providers like Google or Microsoft) you MUST

content/en/docs/reference/command-line-tools-reference/feature-gates/structured-authentication-configuration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ stages:
99
- stage: alpha
1010
defaultValue: false
1111
fromVersion: "1.29"
12+
toVersion: "1.29"
13+
- stage: beta
14+
defaultValue: true
15+
fromVersion: "1.30"
1216
---
1317
Enable [structured authentication configuration](/docs/reference/access-authn-authz/authentication/#configuring-the-api-server)
1418
for the API server.

0 commit comments

Comments
 (0)