2017-03-10 03:13:12 +00:00
|
|
|
---
|
2017-08-03 23:22:52 +00:00
|
|
|
approvers:
|
2017-03-10 03:13:12 +00:00
|
|
|
- jbeda
|
|
|
|
title: Authenticating with Bootstrap Tokens
|
|
|
|
---
|
|
|
|
|
|
|
|
* TOC
|
|
|
|
{:toc}
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
|
|
|
Bootstrap tokens are a simple bearer token that is meant to be used when
|
|
|
|
creating new clusters or joining new nodes to an existing cluster. It was built
|
|
|
|
to support [`kubeadm`](/docs/admin/kubeadm/), but can be used in other contexts
|
|
|
|
for users that wish to start clusters without `kubeadm`. It is also built to
|
|
|
|
work, via RBAC policy, with the [Kubelet TLS
|
2017-03-29 12:16:50 +00:00
|
|
|
Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) system.
|
2017-03-10 03:13:12 +00:00
|
|
|
|
|
|
|
Bootstrap Tokens are defined with a specific type
|
|
|
|
(`bootstrap.kubernetes.io/token`) of secrets that lives in the `kube-system`
|
|
|
|
namespace. These Secrets are then read by the Bootstrap Authenticator in the
|
|
|
|
API Server. Expired tokens are removed with the TokenCleaner controller in the
|
|
|
|
Controller Manager. The tokens are also used to create a signature for a
|
|
|
|
specific ConfigMap used in a "discovery" process through a BootstrapSigner
|
|
|
|
controller.
|
|
|
|
|
|
|
|
Currently, Bootstrap Tokens are **alpha** but there are no large breaking
|
|
|
|
changes expected.
|
|
|
|
|
|
|
|
## Token Format
|
|
|
|
|
|
|
|
Bootstrap Tokens take the form of `abcdef.0123456789abcdef`. More formally,
|
|
|
|
they must match the regular expression `[a-z0-9]{6}\.[a-z0-9]{16}`.
|
|
|
|
|
|
|
|
The first part of the token is the "Token ID" and is considered public
|
|
|
|
information. It is used when referring to a token without leaking the secret
|
|
|
|
part used for authentication. The second part is the "Token Secret" and should
|
|
|
|
only be shared with trusted parties.
|
|
|
|
|
|
|
|
## Enabling Bootstrap Tokens
|
|
|
|
|
|
|
|
All features for Bootstrap Tokens are disabled by default in Kubernetes v1.6.
|
|
|
|
|
|
|
|
You can enable the Bootstrap Token authenticator with the
|
|
|
|
`--experimental-bootstrap-token-auth` flag on the API server. You can enable
|
2017-08-07 14:11:49 +00:00
|
|
|
the Bootstrap controllers by specifying them with the `--controllers` flag on the
|
2017-03-10 03:13:12 +00:00
|
|
|
controller manager with something like
|
|
|
|
`--controllers=*,tokencleaner,bootstrapsigner`. This is done automatically when
|
|
|
|
using `kubeadm`.
|
|
|
|
|
|
|
|
Tokens are used in an HTTPS call as follows:
|
|
|
|
|
|
|
|
```http
|
|
|
|
Authorization: Bearer 07401b.f395accd246ae52d
|
|
|
|
```
|
|
|
|
|
|
|
|
## Bootstrap Token Secret Format
|
|
|
|
|
|
|
|
Each valid token is backed by a secret in the `kube-system` namespace. You can
|
|
|
|
find the full design doc
|
2017-09-21 13:20:58 +00:00
|
|
|
[here](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/cluster-lifecycle/bootstrap-discovery.md).
|
2017-03-10 03:13:12 +00:00
|
|
|
|
|
|
|
Here is what the secret looks like. Note that `base64(string)` indicates the
|
|
|
|
value should be base64 encoded. The undecoded version is provided here for
|
|
|
|
readability.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
apiVersion: v1
|
|
|
|
kind: Secret
|
|
|
|
metadata:
|
|
|
|
name: bootstrap-token-07401b
|
|
|
|
namespace: kube-system
|
|
|
|
type: bootstrap.kubernetes.io/token
|
|
|
|
data:
|
|
|
|
description: base64(The default bootstrap token generated by 'kubeadm init'.)
|
|
|
|
token-id: base64(07401b)
|
|
|
|
token-secret: base64(f395accd246ae52d)
|
|
|
|
expiration: base64(2017-03-10T03:22:11Z)
|
|
|
|
usage-bootstrap-authentication: base64(true)
|
|
|
|
usage-bootstrap-signing: base64(true)
|
|
|
|
```
|
|
|
|
|
|
|
|
The type of the secret must be `bootstrap.kubernetes.io/token` and the name must
|
|
|
|
be `bootstrap-token-<token id>`. It must also exist in the `kube-system`
|
2017-08-25 06:43:29 +00:00
|
|
|
namespace. `description` is a human readable description that should not be
|
2017-03-10 03:13:12 +00:00
|
|
|
used for machine readable information. The Token ID and Secret are included in
|
|
|
|
the data dictionary.
|
|
|
|
|
|
|
|
The `usage-bootstrap-*` members indicate what this secret is intended to be used
|
|
|
|
for. A value must be set to `true` to be enabled.
|
|
|
|
|
|
|
|
`usage-bootstrap-authentication` indicates that the token can be used to
|
|
|
|
authenticate to the API server. The authenticator authenticates as
|
|
|
|
`system:bootstrap:<Token ID>`. It is included in the `system:bootstrappers`
|
|
|
|
group. The naming and groups are intentionally limited to discourage users from
|
|
|
|
using these tokens past bootstrapping.
|
|
|
|
|
|
|
|
`usage-bootstrap-signing` indicates that the token should be used to sign the
|
|
|
|
`cluster-info` ConfigMap as described below.
|
|
|
|
|
|
|
|
The `expiration` data member lists a time after which the token is no longer
|
|
|
|
valid. This is encoded as an absolute UTC time using RFC3339. The TokenCleaner
|
|
|
|
controller will delete expired tokens.
|
|
|
|
|
|
|
|
## Token Management with `kubeadm`
|
|
|
|
|
|
|
|
You can use the `kubeadm` tool to manage tokens on a running cluster. It will
|
|
|
|
automatically grab the default admin credentials on a master from a `kubeadm`
|
|
|
|
created cluster (`/etc/kubernetes/admin.conf`). You can specify an alternate
|
|
|
|
kubeconfig file for credentials with the `--kubeconfig` to the following
|
|
|
|
commands.
|
|
|
|
|
|
|
|
* `kubeadm token list` Lists the tokens along with when they expire and what the
|
|
|
|
approved usages are.
|
|
|
|
* `kubeadm token create` Creates a new token.
|
|
|
|
* `--description` Set the description on the new token.
|
|
|
|
* `--ttl duration` Set expiration time of the token as a delta from "now".
|
|
|
|
Default is 0 for no expiration.
|
|
|
|
* `--usages` Set the ways that the token can be used. The default is
|
|
|
|
`signing,authentication`. These are the usages as described above.
|
|
|
|
* `kubeadm token delete <token id>|<token id>.<token secret>` Delete a token.
|
|
|
|
The token can either be identified with just an ID or with the entire token
|
|
|
|
value. Only the ID is used; the token is still deleted if the secret does not
|
|
|
|
match.
|
|
|
|
|
|
|
|
## ConfigMap Signing
|
|
|
|
|
|
|
|
In addition to authentication, the tokens can be used to sign a ConfigMap. This
|
|
|
|
is used early in a cluster bootstrap process before the client trusts the API
|
2017-08-06 14:06:52 +00:00
|
|
|
server. The signed ConfigMap can be authenticated by the shared token.
|
2017-03-10 03:13:12 +00:00
|
|
|
|
|
|
|
The ConfigMap that is signed is `cluster-info` in the `kube-public` namespace.
|
|
|
|
The typical flow is that a client reads this ConfigMap while unauthenticated and
|
|
|
|
ignoring TLS errors. It then validates the payload of the ConfigMap by looking
|
|
|
|
at a signature embedded in the ConfigMap.
|
|
|
|
|
|
|
|
The ConfigMap may look like this:
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
apiVersion: v1
|
|
|
|
kind: ConfigMap
|
|
|
|
metadata:
|
|
|
|
name: cluster-info
|
|
|
|
namespace: kube-public
|
|
|
|
data:
|
|
|
|
jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
|
|
|
|
kubeconfig: |
|
|
|
|
apiVersion: v1
|
|
|
|
clusters:
|
|
|
|
- cluster:
|
|
|
|
certificate-authority-data: <really long certificate data>
|
|
|
|
server: https://10.138.0.2:6443
|
|
|
|
name: ""
|
|
|
|
contexts: []
|
|
|
|
current-context: ""
|
|
|
|
kind: Config
|
|
|
|
preferences: {}
|
|
|
|
users: []
|
|
|
|
```
|
|
|
|
|
|
|
|
The `kubeconfig` member of the ConfigMap is a config file with just the cluster
|
|
|
|
information filled out. The key thing being communicated here is the
|
|
|
|
`certificate-authority-data`. This may be expanded in the future.
|
|
|
|
|
|
|
|
The signature is a JWS signature using the "detached" mode. To validate the
|
|
|
|
signature, the user should encode the `kubeconfig` payload according to JWS
|
|
|
|
rules (base64 encoded while discarding any trailing `=`). That encoded payload
|
|
|
|
is then used to form a whole JWS by inserting it between the 2 dots. You can
|
|
|
|
verify the JWS using the `HS256` scheme (HMAC-SHA256) with the full token (e.g.
|
|
|
|
`07401b.f395accd246ae52d`) as the shared secret. Users _must_ verify that HS256
|
2017-03-29 12:16:50 +00:00
|
|
|
is used.
|