client exec auth: updates for 1.11 (#9154)

This commit is contained in:
Jordan Liggitt
2018-06-19 19:18:34 -04:00
committed by Misty Linville
parent cb820cebbd
commit fa7593380c
@@ -675,7 +675,7 @@ rules:
## client-go credential plugins ## client-go credential plugins
{{< feature-state for_k8s_version="v1.10" state="alpha" >}} {% assign for_k8s_version="v1.11" %}{% include feature-state-beta.md %}
`k8s.io/client-go` and tools using it such as `kubectl` and `kubelet` are able to execute an `k8s.io/client-go` and tools using it such as `kubectl` and `kubelet` are able to execute an
external command to receive user credentials. external command to receive user credentials.
@@ -686,8 +686,6 @@ protocol specific logic, then returns opaque credentials to use. Almost all cred
use cases require a server side component with support for the [webhook token authenticator](#webhook-token-authentication) use cases require a server side component with support for the [webhook token authenticator](#webhook-token-authentication)
to interpret the credential format produced by the client plugin. to interpret the credential format produced by the client plugin.
As of 1.10 only bearer tokens are supported. Support for client certs may be added in a future release.
### Example use case ### Example use case
In a hypothetical use case, an organization would run an external service that exchanges LDAP credentials In a hypothetical use case, an organization would run an external service that exchanges LDAP credentials
@@ -718,11 +716,13 @@ users:
# Command to execute. Required. # Command to execute. Required.
command: "example-client-go-exec-plugin" command: "example-client-go-exec-plugin"
# API version to use when encoding and decoding the ExecCredentials # API version to use when decoding the ExecCredentials resource. Required.
# resource. Required.
# #
# The API version returned by the plugin MUST match the version encoded. # The API version returned by the plugin MUST match the version listed here.
apiVersion: "client.authentication.k8s.io/v1alpha1" #
# To integrate with tools that support multiple versions (such as client.authentication.k8s.io/v1alpha1),
# set an environment variable or pass an argument to the tool that indicates which version the exec plugin expects.
apiVersion: "client.authentication.k8s.io/v1beta1"
# Environment variables to set when executing the plugin. Optional. # Environment variables to set when executing the plugin. Optional.
env: env:
@@ -756,64 +756,43 @@ the binary `/home/jane/bin/example-client-go-exec-plugin` is executed.
exec: exec:
# Path relative to the directory of the kubeconfig # Path relative to the directory of the kubeconfig
command: "./bin/example-client-go-exec-plugin" command: "./bin/example-client-go-exec-plugin"
apiVersion: "client.authentication.k8s.io/v1alpha1" apiVersion: "client.authentication.k8s.io/v1beta1"
``` ```
### Input and output formats ### Input and output formats
When executing the command, `k8s.io/client-go` sets the `KUBERNETES_EXEC_INFO` environment The executed command prints an `ExecCredential` object to `stdout`. `k8s.io/client-go`
variable to a JSON serialized [`ExecCredential`]( authenticates against the Kubernetes API using the returned credentials in the `status`.
https://github.com/kubernetes/client-go/blob/master/pkg/apis/clientauthentication/v1alpha1/types.go)
resource.
``` When run from an interactive session, `stdin` is exposed directly to the plugin. Plugins should use a
KUBERNETES_EXEC_INFO='{ [TTY check](https://godoc.org/golang.org/x/crypto/ssh/terminal#IsTerminal) to determine if it's
"apiVersion": "client.authentication.k8s.io/v1alpha1", appropriate to prompt a user interactively.
"kind": "ExecCredential",
"spec": {
"interactive": true
}
}'
```
When plugins are executed from an interactive session, `stdin` and `stderr` are directly To use bearer token credentials, the plugin returns a token in the status of the `ExecCredential`.
exposed to the plugin so the user can provide input for interactive logins.
When responding to a 401 HTTP status code, which indicates invalid credentials, this object
includes metadata about the response.
```json ```json
{ {
"apiVersion": "client.authentication.k8s.io/v1alpha1", "apiVersion": "client.authentication.k8s.io/v1beta1",
"kind": "ExecCredential", "kind": "ExecCredential",
"spec": { "status": {
"response": { "token": "my-bearer-token"
"code": 401,
"header": {
"WWW-Authenticate": [
"Bearer realm=ldap.example.com"
]
},
},
"interactive": true
} }
} }
``` ```
After the plugin outputs an `ExecCredential` structure to `stdout`, the `k8s.io/client-go` library Alternatively, a PEM-encoded client certificate and key can be returned to use TLS client auth.
looks for a bearer token or client TLS key and certificate (or all three) in the If the plugin returns a different certificate and key on a subsequent call, `k8s.io/client-go`
`status` field and uses it to authenticate against the Kubernetes API. The library can will close existing connections with the server to force a new TLS handshake.
use a bearer token on its own (`token`), a client TLS key and certificate
(`clientKeyData` and `clientCertificateData`; both must be present), or a combination If specified, `clientKeyData` and `clientCertificateData` must both must be present.
of both methods. `clientCertificateData` may contain additional intermediate
certificates to send to the server. `clientCertificateData` may contain additional intermediate certificates to send to the server.
```json ```json
{ {
"apiVersion": "client.authentication.k8s.io/v1alpha1", "apiVersion": "client.authentication.k8s.io/v1beta1",
"kind": "ExecCredential", "kind": "ExecCredential",
"status": { "status": {
"token": "my-bearer-token",
"clientCertificateData": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----", "clientCertificateData": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"clientKeyData": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----" "clientKeyData": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
} }
@@ -821,7 +800,7 @@ certificates to send to the server.
``` ```
Optionally, the response can include the expiry of the credential formatted as a Optionally, the response can include the expiry of the credential formatted as a
RFC3339 timestamp. Presence or absense of an expiry has the following impact: RFC3339 timestamp. Presence or absence of an expiry has the following impact:
- If an expiry is included, the bearer token and TLS credentials are cached until - If an expiry is included, the bearer token and TLS credentials are cached until
the expiry time is reached, or if the server responds with a 401 HTTP status code, the expiry time is reached, or if the server responds with a 401 HTTP status code,
@@ -829,15 +808,12 @@ RFC3339 timestamp. Presence or absense of an expiry has the following impact:
- If an expiry is omitted, the bearer token and TLS credentials are cached until - If an expiry is omitted, the bearer token and TLS credentials are cached until
the server responds with a 401 HTTP status code or until the process exits. the server responds with a 401 HTTP status code or until the process exits.
```json ```json
{ {
"apiVersion": "client.authentication.k8s.io/v1alpha1", "apiVersion": "client.authentication.k8s.io/v1beta1",
"kind": "ExecCredential", "kind": "ExecCredential",
"status": { "status": {
"token": "my-bearer-token", "token": "my-bearer-token",
"clientCertificateData": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"clientKeyData": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
"expirationTimestamp": "2018-03-05T17:30:20-08:00" "expirationTimestamp": "2018-03-05T17:30:20-08:00"
} }
} }