Kubernetes v1.18 [stable]
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, 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 Bootstrapping system.
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.
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.
The Bootstrap Token authenticator can be enabled using the following flag on the API server:
--enable-bootstrap-token-auth
When enabled, bootstrapping tokens can be used as bearer token credentials to authenticate requests against the API server.
Authorization: Bearer 07401b.f395accd246ae52d
Tokens authenticate as the username system:bootstrap:<token id>
and are members of the group system:bootstrappers
. Additional groups may be specified in the token's Secret.
Expired tokens can be deleted automatically by enabling the tokencleaner
controller on the controller manager.
--controllers=*,tokencleaner
Each valid token is backed by a secret in the kube-system
namespace. You can find the full design doc here.
Here is what the secret looks like.
apiVersion: v1
kind: Secret
metadata:
# Name MUST be of form "bootstrap-token-<token id>"
name: bootstrap-token-07401b
namespace: kube-system
# Type MUST be 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
# Human readable description. Optional.
description: "The default bootstrap token generated by 'kubeadm init'."
# Token ID and secret. Required.
token-id: 07401b
token-secret: f395accd246ae52d
# Expiration. Optional.
expiration: 2017-03-10T03:22:11Z
# Allowed usages.
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
# Extra groups to authenticate the token as. Must start with "system:bootstrappers:"
auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
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
namespace.
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 as a bearer token.usage-bootstrap-signing
indicates that the token may be used to sign the cluster-info
ConfigMap as described below.The expiration
field controls the expiry of the token. Expired tokens are rejected when used for authentication and ignored during ConfigMap signing. The expiry value is encoded as an absolute UTC time using RFC3339. Enable the tokencleaner
controller to automatically delete expired tokens.
You can use the kubeadm
tool to manage tokens on a running cluster. See the kubeadm token docs for details.
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 server. The signed ConfigMap can be authenticated by the shared token.
Enable ConfigMap signing by enabling the bootstrapsigner
controller on the Controller Manager.
--controllers=*,bootstrapsigner
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:
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 only 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 is used.
Consult the kubeadm implementation details section for more information.
© 2022 The Kubernetes Authors
Documentation Distributed under CC BY 4.0.
https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/