BlogSecrets

Vault Kubernetes auth: secrets without static tokens

Let pods authenticate to Vault with their service account token and get short-lived secrets — no bootstrap secret to leak.

Jun 9, 2026·12 min readAdvanced

The bootstrap problem with secrets managers is circular: your pod needs a credential to fetch its credentials. Vault's Kubernetes auth method breaks the loop — the pod presents the service account token it already has, Vault verifies it with the cluster's TokenReview API, and returns a short-lived Vault token scoped by policy.

The trust chain
1
Pod
has projected SA token
2
Vault
TokenReview -> API server
3
Role
SA maps to policy
4
Secret
short-lived, leased

Enable the auth method

bash
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"

Bind a service account to a policy

bash
vault write auth/kubernetes/role/payments \
bound_service_account_names=payments \
bound_service_account_namespaces=shop \
policies=payments-read \
ttl=20m
Scope the binding tightly
bound_service_account_namespaces is the security boundary. A wildcard here means any pod in any namespace with that SA name can assume the role.

Consume it from a pod

The Vault Agent Injector turns a few annotations into a sidecar that logs in and writes the secret to a shared in-memory volume — your app just reads a file.

deploy.yaml
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "payments"
vault.hashicorp.com/agent-inject-secret-db: "database/creds/payments"
bash — inside the podlive
cat /vault/secrets/db
username: v-kubernetes-payments-x9f2
password: A1a-3f7c9d2e...
a fresh DB user, leased for 20m, revoked when the lease ends
Go deeper in a courseVault from dev to productionAuth methods, dynamic secrets, PKI and rotation, hands-on.View course

Related posts