Use Hashicorp Vault to generate tokens for the Kubernetes Dashboard
Deploying the Kubernetes Dashboard is quite easy. There's a Helm chart with good documentation. It gets harder when you want to limit the access to this dashboard. This post provides a way to setup readonly
access to the dashboard.
Prerequisites
- Kubernetes cluster
- Vault setup
Different ways of authentication
The Kubernetes Dashboard application supports many authentication methods. The most common used ones are:
- Basic Auth
- Kubeconfig file
- Bearer Token
The Basic Auth
method is disabled by default. The reason is that Kubernetes API server needs to be configured with authorization mode ABAC and --basic-auth-file
flag provided.
The Kubeconfig file
method is provided for convenience. You can see it as an authentication method for a Dashboard PoC.
The Bearer Token
method is the one we will use in this guide.
Let's deploy the dashboard
I've chosen to deploy the Dashboard via Helm. How Helm works, is out of scope for this blog post, but there's extensive documentation to be found on the internet. As said in the beginning, we're going to setup readonly
access, so let's provide a necessary configuration value to the Helm chart:
rbac:
clusterReadOnlyRole: true
This instructs Helm to create a readonly ClusterRole
. This ClusterRole
allows the ServiceAccount
via a ClusterRoleBinding
to read all Kubernetes objects, like pods, services, ...
When Helm is ready provisioning the dashboard, you should be greeted with the following screen:

You could now test the functionality of the dashboard by logging in with your kubeconfig
file.
Prepare the Vault secrets engine
The Kubernetes secretes engine requires a ServiceAccount
on the Kubernetes cluster, with enough permissions to create ServiceAccount tokens. The ServiceAccount can be created in any namespace, as it will have a ClusterRole
attached to it, which is not a namespaced object.
Let's start with the creation of a namespace for the ServiceAccount:
apiVersion: v1
kind: Namespace
metadata:
name: vault
Then we create the ServiceAccount in the new namespace:
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault
namespace: vault
Next, we need a ClusterRole
that allows to create ServiceAccount tokens:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: create-service-account-tokens
rules:
- apiGroups: [""]
resources: ["serviceaccounts/token"]
verbs: ["create"]
To be able to attach this ClusterRole to a ServiceAccount, we need a ClusterRoleBinding
:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: create-service-account-tokens-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: create-service-account-tokens
subjects:
- kind: ServiceAccount
name: vault
namespace: vault
We can now apply all these manifests to the cluster with kubectl apply
.
Now that the vault
ServiceAccount is provisioned, we need to create a token for it, so the Kubernetes secrets engine can use this ServiceAccount:
kubectl create token vault --namespace vault --duration=31536000s
The duration equals 1 year, as we don't want to reconfigure the secrets engine all the time.
With all the preparations done at the Kubernetes side, we can setup the secret engine for real in Vault. The first step is to enable the secrets engine itself.
vault secrets enable kubernetes
Next, we need to configure this secrets engine. We need to point it to the Kubernetes API, provide the certificate to authenticate to the API and give it a service_account_jwt
attached to the vault
ServiceAccount we created earlier.
vault write kubernetes/config kubernetes_host=https://<ADDRESS>:<PORT> kubernetes_ca_cert="@ca.crt" service_account_jwt=<TOKEN>
The final step it to create a Vault role that can generate ServiceAccount tokens for the readonly
ServiceAccount that the Helm chart created.
vault write kubernetes/roles/dashboard allowed_kubernetes_namespaces=<KUBERNETES_DASHBOARD_NAMESPACE> service_account_name=<SERVICE_ACCOUNT_NAME>
Create a token
Finally, we can create a token to use to login to the dashboard:
vault write -field=service_account_token kubernetes/creds/dashboard kubernetes_namespace=<KUBERNETES_DASHBOARD_NAMESPACE>
The authorization of who can use the kubernetes/creds/dashboard
endpoint is configured by Vault policies, but thats out of scope for this guide. A successful request returns a token that you can use on the dashboard login page.