From 5ff7c64134e56e7740a0ea9ded7bd95ab2a5c368 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Fri, 2 Oct 2020 12:05:05 -0400 Subject: [PATCH] Clarify tokenreview API --- .../access-authn-authz/authentication.md | 155 ++++++++++++++---- 1 file changed, 126 insertions(+), 29 deletions(-) diff --git a/content/en/docs/reference/access-authn-authz/authentication.md b/content/en/docs/reference/access-authn-authz/authentication.md index efdc9026aa..a97dca823f 100644 --- a/content/en/docs/reference/access-authn-authz/authentication.md +++ b/content/en/docs/reference/access-authn-authz/authentication.md @@ -414,6 +414,8 @@ Webhook authentication is a hook for verifying bearer tokens. * `--authentication-token-webhook-config-file` a configuration file describing how to access the remote webhook service. * `--authentication-token-webhook-cache-ttl` how long to cache authentication decisions. Defaults to two minutes. +* `--authentication-token-webhook-version` determines whether to use `authentication.k8s.io/v1beta1` or `authentication.k8s.io/v1` + `TokenReview` objects to send/receive information from the webhook. Defaults to `v1beta1`. The configuration file uses the [kubeconfig](/docs/concepts/configuration/organize-cluster-access-kubeconfig/) file format. Within the file, `clusters` refers to the remote service and @@ -447,72 +449,167 @@ contexts: name: webhook ``` -When a client attempts to authenticate with the API server using a bearer token -as discussed [above](#putting-a-bearer-token-in-a-request), -the authentication webhook POSTs a JSON-serialized `authentication.k8s.io/v1beta1` `TokenReview` object containing the token -to the remote service. Kubernetes will not challenge a request that lacks such a header. +When a client attempts to authenticate with the API server using a bearer token as discussed [above](#putting-a-bearer-token-in-a-request), +the authentication webhook POSTs a JSON-serialized `TokenReview` object containing the token to the remote service. -Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/) -as other Kubernetes API objects. Implementers should be aware of looser -compatibility promises for beta objects and check the "apiVersion" field of the -request to ensure correct deserialization. Additionally, the API server must -enable the `authentication.k8s.io/v1beta1` API extensions group (`--runtime-config=authentication.k8s.io/v1beta1=true`). +Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/) as other Kubernetes API objects. +Implementers should check the `apiVersion` field of the request to ensure correct deserialization, +and **must** respond with a `TokenReview` object of the same version as the request. -The POST body will be of the following format: +{{< tabs name="TokenReview_request" >}} +{{% tab name="authentication.k8s.io/v1" %}} +{{< note >}} +The Kubernetes API server defaults to sending `authentication.k8s.io/v1beta1` token reviews for backwards compatibility. +To opt into receiving `authentication.k8s.io/v1` token reviews, the API server must be started with `--authentication-token-webhook-version=v1`. +{{< /note >}} -```json +```yaml +{ + "apiVersion": "authentication.k8s.io/v1", + "kind": "TokenReview", + "spec": { + # Opaque bearer token sent to the API server + "token": "014fbff9a07c...", + + # Optional list of the audience identifiers for the server the token was presented to. + # Audience-aware token authenticators (for example, OIDC token authenticators) + # should verify the token was intended for at least one of the audiences in this list, + # and return the intersection of this list and the valid audiences for the token in the response status. + # This ensures the token is valid to authenticate to the server it was presented to. + # If no audiences are provided, the token should be validated to authenticate to the Kubernetes API server. + "audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"] + } +} +``` +{{% /tab %}} +{{% tab name="authentication.k8s.io/v1beta1" %}} +```yaml { "apiVersion": "authentication.k8s.io/v1beta1", "kind": "TokenReview", "spec": { - "token": "(BEARERTOKEN)" + # Opaque bearer token sent to the API server + "token": "014fbff9a07c...", + + # Optional list of the audience identifiers for the server the token was presented to. + # Audience-aware token authenticators (for example, OIDC token authenticators) + # should verify the token was intended for at least one of the audiences in this list, + # and return the intersection of this list and the valid audiences for the token in the response status. + # This ensures the token is valid to authenticate to the server it was presented to. + # If no audiences are provided, the token should be validated to authenticate to the Kubernetes API server. + "audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"] } } ``` +{{% /tab %}} +{{< /tabs >}} -The remote service is expected to fill the `status` field of -the request to indicate the success of the login. The response body's `spec` -field is ignored and may be omitted. A successful validation of the bearer -token would return: +The remote service is expected to fill the `status` field of the request to indicate the success of the login. +The response body's `spec` field is ignored and may be omitted. +The remote service must return a response using the same `TokenReview` API version that it received. +A successful validation of the bearer token would return: -```json +{{< tabs name="TokenReview_response_success" >}} +{{% tab name="authentication.k8s.io/v1" %}} +```yaml { - "apiVersion": "authentication.k8s.io/v1beta1", + "apiVersion": "authentication.k8s.io/v1", "kind": "TokenReview", "status": { "authenticated": true, "user": { + # Required "username": "janedoe@example.com", + # Optional "uid": "42", - "groups": [ - "developers", - "qa" - ], + # Optional group memberships + "groups": ["developers", "qa"], + # Optional additional information provided by the authenticator. + # This should not contain confidential data, as it can be recorded in logs + # or API objects, and is made available to admission webhooks. "extra": { "extrafield1": [ "extravalue1", "extravalue2" ] } - } + }, + # Optional list audience-aware token authenticators can return, + # containing the audiences from the `spec.audiences` list for which the provided token was valid. + # If this is omitted, the token is considered to be valid to authenticate to the Kubernetes API server. + "audiences": ["https://myserver.example.com"] } } ``` - -An unsuccessful request would return: - -```json +{{% /tab %}} +{{% tab name="authentication.k8s.io/v1beta1" %}} +```yaml { "apiVersion": "authentication.k8s.io/v1beta1", "kind": "TokenReview", "status": { - "authenticated": false + "authenticated": true, + "user": { + # Required + "username": "janedoe@example.com", + # Optional + "uid": "42", + # Optional group memberships + "groups": ["developers", "qa"], + # Optional additional information provided by the authenticator. + # This should not contain confidential data, as it can be recorded in logs + # or API objects, and is made available to admission webhooks. + "extra": { + "extrafield1": [ + "extravalue1", + "extravalue2" + ] + } + }, + # Optional list audience-aware token authenticators can return, + # containing the audiences from the `spec.audiences` list for which the provided token was valid. + # If this is omitted, the token is considered to be valid to authenticate to the Kubernetes API server. + "audiences": ["https://myserver.example.com"] } } ``` +{{% /tab %}} +{{< /tabs >}} -HTTP status codes can be used to supply additional error context. +An unsuccessful request would return: +{{< tabs name="TokenReview_response_error" >}} +{{% tab name="authentication.k8s.io/v1" %}} +```yaml +{ + "apiVersion": "authentication.k8s.io/v1", + "kind": "TokenReview", + "status": { + "authenticated": false, + # Optionally include details about why authentication failed. + # If no error is provided, the API will return a generic Unauthorized message. + # The error field is ignored when authenticated=true. + "error": "Credentials are expired" + } +} +``` +{{% /tab %}} +{{% tab name="authentication.k8s.io/v1beta1" %}} +```yaml +{ + "apiVersion": "authentication.k8s.io/v1beta1", + "kind": "TokenReview", + "status": { + "authenticated": false, + # Optionally include details about why authentication failed. + # If no error is provided, the API will return a generic Unauthorized message. + # The error field is ignored when authenticated=true. + "error": "Credentials are expired" + } +} +``` +{{% /tab %}} +{{< /tabs >}} ### Authenticating Proxy