|
| 1 | +--- |
| 2 | +layout: blog |
| 3 | +title: "Kubernetes 1.30: Structured Authentication Configuration Moves to Beta" |
| 4 | +date: 2024-04-29 |
| 5 | +slug: structured-authentication-moves-to-beta |
| 6 | +--- |
| 7 | + |
| 8 | +**Authors:** [Anish Ramasekar](https://github.com/aramase) (Microsoft) |
| 9 | + |
| 10 | +With Kubernetes 1.30, we (SIG Auth) are moving Structured Authentication Configuration to beta. |
| 11 | + |
| 12 | +## Motivation |
| 13 | +Kubernetes has had a long-standing need for a more flexible and extensible |
| 14 | +authentication system. The current system, while powerful, has some limitations |
| 15 | +that make it difficult to use in certain scenarios. For example, it is not |
| 16 | +possible to use multiple authenticators of the same type (e.g., multiple JWT |
| 17 | +authenticators) or to change the configuration without restarting the API server. The |
| 18 | +Structured Authentication Configuration feature is the first step towards |
| 19 | +addressing these limitations and providing a more flexible and extensible way |
| 20 | +to configure authentication in Kubernetes. |
| 21 | + |
| 22 | +## What is Structured Authentication Configuration? |
| 23 | + |
| 24 | +The Structured Authentication Configuration feature is a new way to configure |
| 25 | +authentication in Kubernetes. It currently only supports configuring JWT |
| 26 | +authenticators, which serve as the next iteration of the existing OIDC |
| 27 | +authenticator. JWT authenticator is an authenticator to |
| 28 | +authenticate Kubernetes users using JWT compliant tokens. The authenticator |
| 29 | +will attempt to parse a raw ID token, verify it's been signed by the configured |
| 30 | +issuer. |
| 31 | + |
| 32 | +The feature is designed to be more flexible and extensible than the existing |
| 33 | +flag-based approach for configuring the JWT authenticator. |
| 34 | + |
| 35 | +### Benefits of Structured Authentication Configuration |
| 36 | +The Structured Authentication Configuration feature brings several benefits to |
| 37 | +Kubernetes: |
| 38 | +1. **Multiple JWT authenticators**: You can configure multiple JWT authenticators |
| 39 | + simultaneously. This allows you to use multiple identity providers (e.g., |
| 40 | + Okta, Keycloak, GitLab) without needing to use an intermediary like Dex |
| 41 | + that handles multiplexing between multiple identity providers. |
| 42 | +2. **Dynamic configuration**: You can change the configuration without |
| 43 | + restarting the API server. This allows you to add, remove, or modify |
| 44 | + authenticators without disrupting the API server. |
| 45 | +3. **Any JWT-compliant token**: You can use any JWT-compliant token for |
| 46 | + authentication. This allows you to use tokens from any identity provider that |
| 47 | + supports JWT. The minimum valid JWT payload must contain the claims documented |
| 48 | + [here](https://github.com/kubernetes/kubernetes/blob/121607e80963370c1838f9f620c2b8552041abfc/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go#L152-L157). |
| 49 | +4. **CEL (Common Expression Language) support**: You can use [CEL](/docs/reference/using-api/cel/) |
| 50 | + to determine whether the token's claims match the user's attributes in Kubernetes (e.g., |
| 51 | + username, group). This allows you to use complex logic to determine whether a |
| 52 | + token is valid. |
| 53 | +5. **Multiple audiences**: You can configure multiple audiences for a single |
| 54 | + authenticator. This allows you to use the same authenticator for multiple |
| 55 | + audiences, such as using a different OAuth client for `kubectl` and dashboard. |
| 56 | +6. **Using Identity providers that don't support OpenID connect discovery**: You |
| 57 | + can use identity providers that don't support [OpenID Connect |
| 58 | + discovery](https://openid.net/specs/openid-connect-discovery-1_0.html). The only |
| 59 | + requirement is to host the discovery document at a different location than the |
| 60 | + issuer (such as locally in the cluster) and specify the `issuer.discoveryURL` in |
| 61 | + the configuration file. |
| 62 | + |
| 63 | +## How to use Structured Authentication Configuration |
| 64 | +To use the Structured Authentication Configuration feature, you must specify |
| 65 | +the path to the authentication configuration using the `--authentication-config` |
| 66 | +command line argument in the API server. The configuration file is a YAML file |
| 67 | +that specifies the authenticators and their configuration. Here is an example |
| 68 | +configuration file that configures two JWT authenticators: |
| 69 | + |
| 70 | +```yaml |
| 71 | +apiVersion: apiserver.config.k8s.io/v1beta1 |
| 72 | +kind: AuthenticationConfiguration |
| 73 | +jwt: |
| 74 | +- issuer: |
| 75 | + url: https://issuer1.example.com |
| 76 | + audiences: |
| 77 | + - audience1 |
| 78 | + - audience2 |
| 79 | + audienceMatchPolicy: MatchAny |
| 80 | + claimValidationRules: |
| 81 | + expression: 'claims.hd == "example.com"' |
| 82 | + message: "the hd claim must be example.com" |
| 83 | + claimMappings: |
| 84 | + username: |
| 85 | + expression: 'claims.username' |
| 86 | + groups: |
| 87 | + expression: 'claims.groups' |
| 88 | + uid: |
| 89 | + expression: 'claims.uid' |
| 90 | + extra: |
| 91 | + - key: 'example.com/tenant' |
| 92 | + expression: 'claims.tenant' |
| 93 | + userValidationRules: |
| 94 | + - expression: "!user.username.startsWith('system:')" |
| 95 | + message: "username cannot use reserved system: prefix" |
| 96 | +# second authenticator that exposes the discovery document at a different location |
| 97 | +# than the issuer |
| 98 | +- issuer: |
| 99 | + url: https://issuer2.example.com |
| 100 | + discoveryURL: https://discovery.example.com/.well-known/openid-configuration |
| 101 | + audiences: |
| 102 | + - audience3 |
| 103 | + - audience4 |
| 104 | + audienceMatchPolicy: MatchAny |
| 105 | + claimValidationRules: |
| 106 | + expression: 'claims.hd == "example.com"' |
| 107 | + message: "the hd claim must be example.com" |
| 108 | + claimMappings: |
| 109 | + username: |
| 110 | + expression: 'claims.username' |
| 111 | + groups: |
| 112 | + expression: 'claims.groups' |
| 113 | + uid: |
| 114 | + expression: 'claims.uid' |
| 115 | + extra: |
| 116 | + - key: 'example.com/tenant' |
| 117 | + expression: 'claims.tenant' |
| 118 | + userValidationRules: |
| 119 | + - expression: "!user.username.startsWith('system:')" |
| 120 | + message: "username cannot use reserved system: prefix" |
| 121 | +``` |
| 122 | +
|
| 123 | +## Migration from command line flags to configuration file |
| 124 | +The Structured Authentication Configuration feature is designed to be |
| 125 | +backwards-compatible with the existing flag-based approach for configuring the |
| 126 | +JWT authenticator. This means that you can continue to use the existing |
| 127 | +command-line flags to configure the JWT authenticator. However, we recommend |
| 128 | +migrating to the new configuration file-based approach, as it provides more |
| 129 | +flexibility and extensibility. |
| 130 | +
|
| 131 | +{{% alert title="Note" color="primary" %}} |
| 132 | +If you specify `--authentication-config` along with any of the `--oidc-*` command line arguments, this is |
| 133 | +a misconfiguration. In this situation, the API server reports an error and then immediately exits. |
| 134 | + |
| 135 | +If you want to switch to using structured authentication configuration, you have to remove the `--oidc-*` |
| 136 | +command line arguments, and use the configuration file instead. |
| 137 | +{{% /alert %}} |
| 138 | + |
| 139 | +Here is an example of how to migrate from the command-line flags to the |
| 140 | +configuration file: |
| 141 | + |
| 142 | +### Command-line flags |
| 143 | +```bash |
| 144 | +--oidc-issuer-url=https://issuer.example.com |
| 145 | +--oidc-client-id=example-client-id |
| 146 | +--oidc-username-claim=username |
| 147 | +--oidc-groups-claim=groups |
| 148 | +--oidc-username-prefix=oidc: |
| 149 | +--oidc-groups-prefix=oidc: |
| 150 | +--oidc-required-claim="hd=example.com" |
| 151 | +--oidc-required-claim="admin=true" |
| 152 | +--oidc-ca-file=/path/to/ca.pem |
| 153 | +``` |
| 154 | + |
| 155 | +> There is no equivalent in the configuration file for the `--oidc-signing-algs`. |
| 156 | +> The authenticator will support all asymmetric algorithms listed |
| 157 | +> [here](https://github.com/kubernetes/kubernetes/blob/b4935d910dcf256288694391ef675acfbdb8e7a3/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go#L222-L233). |
| 158 | + |
| 159 | +### Configuration file |
| 160 | +```yaml |
| 161 | +apiVersion: apiserver.config.k8s.io/v1beta1 |
| 162 | +kind: AuthenticationConfiguration |
| 163 | +jwt: |
| 164 | +- issuer: |
| 165 | + url: https://issuer.example.com |
| 166 | + audiences: |
| 167 | + - example-client-id |
| 168 | + certificateAuthority: <value is the content of file /path/to/ca.pem> |
| 169 | + claimMappings: |
| 170 | + username: |
| 171 | + claim: username |
| 172 | + prefix: "oidc:" |
| 173 | + groups: |
| 174 | + claim: groups |
| 175 | + prefix: "oidc:" |
| 176 | + claimValidationRules: |
| 177 | + - claim: hd |
| 178 | + requiredValue: "example.com" |
| 179 | + - claim: admin |
| 180 | + requiredValue: "true" |
| 181 | +``` |
| 182 | + |
| 183 | +## What's next? |
| 184 | +For Kubernetes v1.31, we expect the feature to stay in beta while we get more |
| 185 | +feedback. In the coming releases, we want to investigate: |
| 186 | +- Making distributed claims work via CEL expressions. |
| 187 | +- Egress selector configuration support for calls to `issuer.url` and |
| 188 | + `issuer.discoveryURL`. |
| 189 | + |
| 190 | +You can learn more about this feature on the [structured authentication |
| 191 | +configuration](/docs/reference/access-authn-authz/authentication/#using-authentication-configuration) |
| 192 | +Kubernetes doc website. You can also follow along on the |
| 193 | +[KEP-3331](https://kep.k8s.io/3331) to track progress across the coming |
| 194 | +Kubernetes releases. |
| 195 | + |
| 196 | +## Call to action |
| 197 | +In this post, we have covered the benefits the Structured Authentication |
| 198 | +Configuration feature brings in Kubernetes v1.30. To use this feature, you must specify the path to the |
| 199 | +authentication configuration using the `--authentication-config` command line |
| 200 | +argument. From Kubernetes v1.30, the feature is in beta and enabled by default. |
| 201 | +If you want to keep using command line flags instead of a configuration file, |
| 202 | +those will continue to work as-is. |
| 203 | + |
| 204 | +We would love to hear your feedback on this feature. Please reach out to us on the |
| 205 | +[#sig-auth-authenticators-dev](https://kubernetes.slack.com/archives/C04UMAUC4UA) |
| 206 | +channel on Kubernetes Slack. |
| 207 | + |
| 208 | +## How to get involved |
| 209 | +If you are interested in getting involved in the development of this feature, |
| 210 | +share feedback, or participate in any other ongoing SIG Auth projects, please |
| 211 | +reach out on the [#sig-auth](https://kubernetes.slack.com/archives/C0EN96KUY) |
| 212 | +channel on Kubernetes Slack. |
| 213 | + |
| 214 | +You are also welcome to join the bi-weekly [SIG Auth |
| 215 | +meetings](https://github.com/kubernetes/community/blob/master/sig-auth/README.md#meetings) |
| 216 | +held every-other Wednesday. |
0 commit comments