---
approvers:
- 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
Bootstrapping](/docs/admin/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.

{% include feature-state-beta.md %}

## 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 Token Authentication

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.

```http
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
```

## Bootstrap Token Secret Format

Each valid token is backed by a secret in the `kube-system` namespace.  You can
find the full design doc
[here](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/cluster-lifecycle/bootstrap-discovery.md).

Here is what the secret looks like.

```yaml
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.

## Token Management with `kubeadm`

You can use the `kubeadm` tool to manage tokens on a running cluster. See the
[`kubeadm token` docs](/docs/admin/kubeadm/#manage-tokens) for details.

## 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
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:

```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
is used.

WARNING: Any party with a bootstrapping token can create a valid signature for that
token. When using ConfigMap signing it's discouraged to share the same token with
many clients, since a compromised client can potentially man-in-the middle another
client relying on the signature to bootstrap TLS trust.

Consult the [kubeadm security model](/docs/reference/generated/kubeadm/#security-model)
section for more information.
