
Intro
This is part three of our Vault for Dummies series. After Part 2 where we set up Vault with Transit Auto-unseal, it’s time to tackle Kubernetes authentication, from outside the cluster.
In this post, we’ll walk through setting up Kubernetes auth with an external Vault, so your K8s workloads can securely authenticate and pull secrets without hardcoded tokens. We’ll walk through using the TokenReview API, handling service account tokens in modern K8s (1.24+), and securely wiring Vault to your cluster for workload identity.
☝️First Rule: One Auth Method Per Cluster
Each K8s cluster should have its own dedicated Vault auth method. This makes access scoping and policy management way easier in the long term.
☸️How Does Vault Authenticate Kubernetes Clients?
Vault leverages Kubernetes’ TokenReview API to validate the identity of workloads. This requires:
- A JWT token from a K8s Service Account (SA)
- A CA certificate to validate the K8s API
- And depending on where Vault is running (in K8s or external)— potentially a token_reviewer_jwt
Vault Inside VS Outside Kubernetes
Feature | Vault Inside Kubernetes | Vault Outside Kubernetes |
---|---|---|
API Discovery | Auto-discovers Kubernetes API | Must manually set kubernetes_host |
CA Certificate | Auto-detected | Must manually provide kubernetes_ca_cert |
Service Account Token | Auto-mounted | Must manually retrieve token_reviewer_jwt |
A. Vault Runs Inside Kubernetes
This is the easy path. Vault can simply grab the necessary data from its own pod’s mounted Service Account:
- It auto-discovers the API address and CA cert from
/var/run/secrets/kubernetes.io/serviceaccount/
- No need to manually provide
kubernetes_ca_cert
ortoken_reviewer_jwt
B. Vault Runs Outside Kubernetes
Things get manual in this case, but manageable. Vault has no direct access to Kubernetes’ internal Service Account system, so you need to explicitly provide following information
Field | Description |
---|---|
kubernetes_host | Your cluster’s API server endpoint |
kubernetes_ca_cert | CA certificate used to verify the API server’s TLS cert |
token_reviewer_jwt | Long-lived JWT from a Service Account that can call the TokenReview API |
🤔But wait ! why do we need this token_reviewer_jwt
anyway?
🔍 Why a token_reviewer_jwt
?
When a K8s workload tries to authenticate to Vault using its own SA token, Vault has to validate it.
It does this by asking the cluster:
That’s a TokenReview request — and Vault needs permission to do that. The token_reviewer_jwt
gives Vault this ability. It’s tied to a Service Account that has the system:auth-delegator
role. Without it, Vault cannot validate k8s workloads.
I. Getting Started with External Vault k8s auth
If you’re on Kubernetes 1.24 or later, note this: SA tokens are no longer auto-created. You have to create them yourself.
You must manually create a Secret of type kubernetes.io/service-account-token
manually. Here’s how.
1️⃣Create a dedicated Service Account
kubectl create sa vault-auth
2️⃣ Bind it to a reviewer role
kubectl create clusterrolebinding vault-auth-binding \
--clusterrole=system:auth-delegator \
--serviceaccount=default:vault-auth
3️⃣ Manually create a token Secret
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: vault-auth-token
namespace: default
annotations:
kubernetes.io/service-account.name: "vault-auth"
type: kubernetes.io/service-account-token
EOF
4️⃣ Extract the JWT token
TOKEN=$(kubectl get secret vault-auth-token -o jsonpath='{.data.token}' | base64 --decode)
$TOKEN
now, contains the ServiceAccount JWT Token, which you can use to configure Vault.
5️⃣ Get the Kubernetes CA cert
kubectl get secret vault-auth-token -o jsonpath='{.data.ca\.crt}' | base64 --decode > ca.crt
6️⃣ Get your cluster API address
export KUBERNETES_API_ADDR=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
7️⃣ Configure Vault’s Kubernetes auth method
Now, configure Vault using the manually created service account token:
#1. Enable K8s auth method
$ vault auth enable -path=auth-k8s kubernetes
#2. Configure Vault's Kubernetes auth method
vault write auth/auth-k8s/config \
kubernetes_host="$KUBERNETES_API_ADDR" \
kubernetes_ca_cert=@ca.crt \
token_reviewer_jwt="$TOKEN"
II. K8s Auth Alternatives for external vaults
💡Use Client JWT for TokenReview
You can also configure Vault to reuse the client’s own JWT to call the TokenReview API
- Allows all K8s SAs access to TokenReview operation in each login attempt to Vault
- skipping the dedicated reviewer token
token_reviewer_jwt = ""
disable_local_ca_jwt = true
system:auth-delegator
role. Use with caution.
kubectl create clusterrolebinding vault-client-tokenreviews \
--clusterrole=system:auth-delegator \
--group=system:serviceaccounts
🔁 OIDC Option: Use Kubernetes as an OIDC Provider
With K8s configured as an OIDC issuer, you can authenticate to Vault using OIDC and JWTs directly (no TokenReview).
- Tokens are short-lived
- No need for a reviewer JWT
- Just ensure Vault trusts the OIDC discovery endpoint and public keys
Conclusion🚀
That wraps up our Vault for Dummies series🎇! Whether you’re experimenting locally, prepping for the Vault Associate exam, or deploying a real-world setup, you’ve now covered the essentials. From Raft storage to Transit unseal and Kubernetes auth. Thanks for tagging along, and feel free to reach out if you’re putting this into practice!
✅ TL;DR Summary
- Vault outside Kubernetes needs manual setup.
- You must create a token reviewer JWT, extract the CA cert, and pass them to Vault.
- Kubernetes 1.24+ disables auto-creation of SA tokens — you must manually generate Secrets.
- Optional: skip the reviewer token by reusing the client’s JWT with proper RBAC.
- Long-term: consider using OIDC for cleaner, scalable auth.
🙋🏻♀️If you like this content please subscribe to our blog newsletter ❤️.