Skip to content

Commit 0703805

Browse files
authored
Merge pull request #24349 from liggitt/tokenreview
Clarify tokenreview API
2 parents 11ee97d + 5ff7c64 commit 0703805

File tree

1 file changed

+124
-27
lines changed

1 file changed

+124
-27
lines changed

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

Lines changed: 124 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ Webhook authentication is a hook for verifying bearer tokens.
414414

415415
* `--authentication-token-webhook-config-file` a configuration file describing how to access the remote webhook service.
416416
* `--authentication-token-webhook-cache-ttl` how long to cache authentication decisions. Defaults to two minutes.
417+
* `--authentication-token-webhook-version` determines whether to use `authentication.k8s.io/v1beta1` or `authentication.k8s.io/v1`
418+
`TokenReview` objects to send/receive information from the webhook. Defaults to `v1beta1`.
417419

418420
The configuration file uses the [kubeconfig](/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
419421
file format. Within the file, `clusters` refers to the remote service and
@@ -447,72 +449,167 @@ contexts:
447449
name: webhook
448450
```
449451

450-
When a client attempts to authenticate with the API server using a bearer token
451-
as discussed [above](#putting-a-bearer-token-in-a-request),
452-
the authentication webhook POSTs a JSON-serialized `authentication.k8s.io/v1beta1` `TokenReview` object containing the token
453-
to the remote service. Kubernetes will not challenge a request that lacks such a header.
452+
When a client attempts to authenticate with the API server using a bearer token as discussed [above](#putting-a-bearer-token-in-a-request),
453+
the authentication webhook POSTs a JSON-serialized `TokenReview` object containing the token to the remote service.
454454

455-
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/)
456-
as other Kubernetes API objects. Implementers should be aware of looser
457-
compatibility promises for beta objects and check the "apiVersion" field of the
458-
request to ensure correct deserialization. Additionally, the API server must
459-
enable the `authentication.k8s.io/v1beta1` API extensions group (`--runtime-config=authentication.k8s.io/v1beta1=true`).
455+
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/) as other Kubernetes API objects.
456+
Implementers should check the `apiVersion` field of the request to ensure correct deserialization,
457+
and **must** respond with a `TokenReview` object of the same version as the request.
460458

461-
The POST body will be of the following format:
459+
{{< tabs name="TokenReview_request" >}}
460+
{{% tab name="authentication.k8s.io/v1" %}}
461+
{{< note >}}
462+
The Kubernetes API server defaults to sending `authentication.k8s.io/v1beta1` token reviews for backwards compatibility.
463+
To opt into receiving `authentication.k8s.io/v1` token reviews, the API server must be started with `--authentication-token-webhook-version=v1`.
464+
{{< /note >}}
462465

463-
```json
466+
```yaml
467+
{
468+
"apiVersion": "authentication.k8s.io/v1",
469+
"kind": "TokenReview",
470+
"spec": {
471+
# Opaque bearer token sent to the API server
472+
"token": "014fbff9a07c...",
473+
474+
# Optional list of the audience identifiers for the server the token was presented to.
475+
# Audience-aware token authenticators (for example, OIDC token authenticators)
476+
# should verify the token was intended for at least one of the audiences in this list,
477+
# and return the intersection of this list and the valid audiences for the token in the response status.
478+
# This ensures the token is valid to authenticate to the server it was presented to.
479+
# If no audiences are provided, the token should be validated to authenticate to the Kubernetes API server.
480+
"audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"]
481+
}
482+
}
483+
```
484+
{{% /tab %}}
485+
{{% tab name="authentication.k8s.io/v1beta1" %}}
486+
```yaml
464487
{
465488
"apiVersion": "authentication.k8s.io/v1beta1",
466489
"kind": "TokenReview",
467490
"spec": {
468-
"token": "(BEARERTOKEN)"
491+
# Opaque bearer token sent to the API server
492+
"token": "014fbff9a07c...",
493+
494+
# Optional list of the audience identifiers for the server the token was presented to.
495+
# Audience-aware token authenticators (for example, OIDC token authenticators)
496+
# should verify the token was intended for at least one of the audiences in this list,
497+
# and return the intersection of this list and the valid audiences for the token in the response status.
498+
# This ensures the token is valid to authenticate to the server it was presented to.
499+
# If no audiences are provided, the token should be validated to authenticate to the Kubernetes API server.
500+
"audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"]
469501
}
470502
}
471503
```
504+
{{% /tab %}}
505+
{{< /tabs >}}
472506

473-
The remote service is expected to fill the `status` field of
474-
the request to indicate the success of the login. The response body's `spec`
475-
field is ignored and may be omitted. A successful validation of the bearer
476-
token would return:
507+
The remote service is expected to fill the `status` field of the request to indicate the success of the login.
508+
The response body's `spec` field is ignored and may be omitted.
509+
The remote service must return a response using the same `TokenReview` API version that it received.
510+
A successful validation of the bearer token would return:
477511

478-
```json
512+
{{< tabs name="TokenReview_response_success" >}}
513+
{{% tab name="authentication.k8s.io/v1" %}}
514+
```yaml
515+
{
516+
"apiVersion": "authentication.k8s.io/v1",
517+
"kind": "TokenReview",
518+
"status": {
519+
"authenticated": true,
520+
"user": {
521+
# Required
522+
"username": "[email protected]",
523+
# Optional
524+
"uid": "42",
525+
# Optional group memberships
526+
"groups": ["developers", "qa"],
527+
# Optional additional information provided by the authenticator.
528+
# This should not contain confidential data, as it can be recorded in logs
529+
# or API objects, and is made available to admission webhooks.
530+
"extra": {
531+
"extrafield1": [
532+
"extravalue1",
533+
"extravalue2"
534+
]
535+
}
536+
},
537+
# Optional list audience-aware token authenticators can return,
538+
# containing the audiences from the `spec.audiences` list for which the provided token was valid.
539+
# If this is omitted, the token is considered to be valid to authenticate to the Kubernetes API server.
540+
"audiences": ["https://myserver.example.com"]
541+
}
542+
}
543+
```
544+
{{% /tab %}}
545+
{{% tab name="authentication.k8s.io/v1beta1" %}}
546+
```yaml
479547
{
480548
"apiVersion": "authentication.k8s.io/v1beta1",
481549
"kind": "TokenReview",
482550
"status": {
483551
"authenticated": true,
484552
"user": {
553+
# Required
485554
"username": "[email protected]",
555+
# Optional
486556
"uid": "42",
487-
"groups": [
488-
"developers",
489-
"qa"
490-
],
557+
# Optional group memberships
558+
"groups": ["developers", "qa"],
559+
# Optional additional information provided by the authenticator.
560+
# This should not contain confidential data, as it can be recorded in logs
561+
# or API objects, and is made available to admission webhooks.
491562
"extra": {
492563
"extrafield1": [
493564
"extravalue1",
494565
"extravalue2"
495566
]
496567
}
497-
}
568+
},
569+
# Optional list audience-aware token authenticators can return,
570+
# containing the audiences from the `spec.audiences` list for which the provided token was valid.
571+
# If this is omitted, the token is considered to be valid to authenticate to the Kubernetes API server.
572+
"audiences": ["https://myserver.example.com"]
498573
}
499574
}
500575
```
576+
{{% /tab %}}
577+
{{< /tabs >}}
501578

502579
An unsuccessful request would return:
503580

504-
```json
581+
{{< tabs name="TokenReview_response_error" >}}
582+
{{% tab name="authentication.k8s.io/v1" %}}
583+
```yaml
584+
{
585+
"apiVersion": "authentication.k8s.io/v1",
586+
"kind": "TokenReview",
587+
"status": {
588+
"authenticated": false,
589+
# Optionally include details about why authentication failed.
590+
# If no error is provided, the API will return a generic Unauthorized message.
591+
# The error field is ignored when authenticated=true.
592+
"error": "Credentials are expired"
593+
}
594+
}
595+
```
596+
{{% /tab %}}
597+
{{% tab name="authentication.k8s.io/v1beta1" %}}
598+
```yaml
505599
{
506600
"apiVersion": "authentication.k8s.io/v1beta1",
507601
"kind": "TokenReview",
508602
"status": {
509-
"authenticated": false
603+
"authenticated": false,
604+
# Optionally include details about why authentication failed.
605+
# If no error is provided, the API will return a generic Unauthorized message.
606+
# The error field is ignored when authenticated=true.
607+
"error": "Credentials are expired"
510608
}
511609
}
512610
```
513-
514-
HTTP status codes can be used to supply additional error context.
515-
611+
{{% /tab %}}
612+
{{< /tabs >}}
516613

517614
### Authenticating Proxy
518615

0 commit comments

Comments
 (0)