Vault

Vault Kubernetes Secrets Engine: Dynamic Service Account Token Issuance

2026-04-19
NicheeLab Editorial Team

You want to keep Kubernetes cluster permissions minimal while still distributing short-lived credentials to automation infrastructure and workloads. Vault's Kubernetes secrets engine answers this need by calling Kubernetes's TokenRequest API to dynamically issue Service Account tokens.

Based on the stable behavior documented in the official guides, this article walks through the setup steps, RBAC design, operational patterns, and the differences exams love to ask about (specifically vs. the Kubernetes auth method).

Fundamentals and Flow: Short-Lived Tokens via TokenRequest

Vault's Kubernetes secrets engine calls the Kubernetes API's TokenRequest subresource against an existing Service Account (SA), obtains a JWT with a short expiration, and returns it to the client. Vault controls the Kubernetes connection info needed for this issuance, and uses roles to define which SAs and namespaces it is allowed to issue tokens for.

This approach uses standard SA tokens signed and verified by Kubernetes, so it offers high compatibility and fits operations that rely on natural TTL expiration (early forced revocation is generally not possible; the model assumes short lifetimes and frequent reissue).

  • Benefits: short-lived tokens reduce leak risk and make distribution easy to automate
  • Caveat: TTL may be truncated by Kubernetes's TokenRequest upper limit or other cluster settings
  • Prerequisite: Vault needs RBAC permission to call TokenRequest against the Kubernetes API

End-to-end picture of dynamic issuance

ClientApp/CIVaultSE role / issue tokenKubernetes APIServiceAccounts(1) issue request(2) TokenRequesttarget SA/Namespace/TTL/Audience(3) short-lived JWTLease tracked on the Vault side(4) use token (short-lived)Issuance flow: Client → Vault → Kubernetes

Minimal example for obtaining a token from Vault (conceptual)

## A conceptual example (paths and field names differ between versions. Check the docs)
# Issue an SA token via the role named my-role
vault read kubernetes/issue/my-role \
  service_account_name=my-app \
  namespace=apps \
  ttl=15m \
  audiences=https://kubernetes.default.svc

# Example output (abridged)
# token          : eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# expiration     : 2026-04-19T12:34:56Z
# namespace      : apps
# service_account: my-app

Required Permissions and Connection Setup: RBAC and Vault-side config

To let Vault execute TokenRequest, grant create permission on serviceaccounts/token on the Kubernetes side. Avoid overly broad permissions: the recommended pattern is to scope roles to a single namespace and a minimal set of Service Accounts.

On the Vault secrets engine side, configure the Kubernetes API server endpoint, the CA certificate, and a Service Account token (used by Vault to connect to Kubernetes) backed by the RBAC described above.

  • Default to Role/RoleBinding (per-namespace) for RBAC. Use ClusterRoleBinding only when unavoidable
  • Limit the create permission on TokenRequest to specific SAs or namespaces
  • Set the CA, API endpoint, and token in Vault's kubernetes/config

Example: RBAC and the Vault secrets-engine connection config

# Kubernetes side (least privilege: TokenRequest inside the apps namespace only)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vault-k8s-se
  namespace: vault
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: tokenrequest-minimal
  namespace: apps
rules:
- apiGroups: [""]
  resources: ["serviceaccounts/token"]
  verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: vault-k8s-se-binding
  namespace: apps
subjects:
- kind: ServiceAccount
  name: vault-k8s-se
  namespace: vault
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: tokenrequest-minimal

# Vault side (conceptual. Check the docs for the real field names)
# Enable the Kubernetes secrets engine
vault secrets enable kubernetes

# Configure the connection (assumes in-cluster)
vault write kubernetes/config \
  kubernetes_host="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}" \
  kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
  token=@/var/run/secrets/kubernetes.io/serviceaccount/token

Role Design and Issuance: Tuning Namespace, SA, Audience, and TTL

Define what can be issued using roles. A role constrains the allowed namespaces and Service Accounts, the allowed audiences, and the upper bound on TTL. This keeps separation of duties and least privilege intact on the Vault side.

To issue a token, perform a read (or write) operation specifying the role name. The returned token is a JWT signed and verified by Kubernetes, and its TTL may be shortened depending on cluster-side settings.

  • TTL may be shortened by Kubernetes's TokenRequest cap (cluster-dependent)
  • Scope each role tightly by namespace and SA, and split horizontally into separate roles
  • A Vault lease is created at issuance time, but the Kubernetes token itself generally cannot be revoked early

Conceptual commands for creating a role and issuing a token

# Create the role (conceptual. Check the docs for your Vault version's parameter names)
vault write kubernetes/roles/ci-deployer \
  allowed_namespaces=apps,staging \
  allowed_service_accounts=deployer \
  allowed_audiences=https://kubernetes.default.svc \
  ttl=15m \
  max_ttl=1h

# Issue (for an SA/namespace combination the role permits)
vault read kubernetes/issue/ci-deployer \
  service_account_name=deployer \
  namespace=apps \
  audiences=https://kubernetes.default.svc \
  ttl=10m

# Returned (abridged): token, expiration, namespace, service_account

Operational Patterns: Integrating with Vault Agent and CI/CD

For distributing tokens to workloads, a practical approach is to use Vault Agent (as a sidecar) to periodically reissue and write the token to a file that the process reads. For CI/CD, fetch once at the start of the job and size the TTL so it covers only the job's duration.

For observability, the bare minimum is monitoring lease expiration, exposing issuance-failure metrics, and collecting audit logs. Even when early revocation is not required, periodically verify that short TTLs and automated reissue actually work.

  • Workloads: use a Vault Agent sidecar for automated reissue and rotation
  • CI/CD: size the TTL to match job duration (idempotent retries and clear failure handling)
  • Auditing: enable Vault's audit device alongside the Kubernetes API server audit log

Example: template output via Vault Agent (sidecar)

# Agent configuration (conceptual): fetch from kubernetes/issue/ci-deployer and write to a file
exit_after_auth = false
pid_file = "/tmp/vault-agent.pid"

auth {
  method = "approle"  # authenticate the agent with AppRole, for example
  mount_path = "auth/approle"
  config = {
    role_id_file_path   = "/vault/secrets/role_id"
    secret_id_file_path = "/vault/secrets/secret_id"
  }
}

template {
  destination = "/work/token"
  contents    = <<EOF
{{ with secret "kubernetes/issue/ci-deployer" (printf "service_account_name=%s namespace=%s ttl=%s" "deployer" "apps" "10m") }}{{ .Data.token }}{{ end }}
EOF
}

# The workload reads /work/token, and the agent replaces it before it expires

Exam Focus: Auth Method vs. Secrets Engine, and Understanding TTL/Leases

Vault's Kubernetes auth method is the mechanism for Pods to log in to Vault. The Kubernetes secrets engine described here is the mechanism for Vault to issue Kubernetes credentials (SA tokens). Mixing up the direction of these two is a classic design mistake.

Also, tokens issued via Kubernetes's TokenRequest expire naturally with time. Revoking a Vault lease only affects Vault's internal bookkeeping; you generally cannot force a previously issued token to be invalid on the Kubernetes side. Short TTLs and automated rotation are therefore the assumed operating model.

  • Kubernetes auth method: Pod-to-Vault authentication
  • Kubernetes secrets engine: Vault-to-Kubernetes token issuance
  • Early revocation: assumed impossible. Short TTLs and frequent reissue are the solution
FeatureIntended use caseDirection of authenticationMain benefit
Kubernetes auth methodPods log in to Vault to access secrets stored inside VaultKubernetes → VaultFine-grained access control by Pod identity
Kubernetes secrets engine (this article)Dynamically obtain Kubernetes SA tokens (for CI/CD and automation)Vault → KubernetesShort-lived tokens with standard TokenRequest compatibility
Static Service Account tokenLong-lived, fixed credentials; manual distributionSA → client (direct)Simple, with few dependencies

Minimal exam-ready policy (allow read on the Vault issuance role)

# Vault policy (example): allow issuing for one role only
auth "*" {
  # Authentication is configured separately
}

path "kubernetes/issue/ci-deployer" {
  capabilities = ["read"]
}

# In practice, split this per target role with least privilege

Troubleshooting and Auditing: Common Pitfalls and What to Check

Missing RBAC for TokenRequest is by far the most common issue. Verify that create on serviceaccounts/token is granted on the target namespace/SA, and that resourceNames are not constraining things too tightly. If the TTL is shorter than expected, suspect the cluster-side upper limit.

For auditing, enable Vault's audit device so you can trace who issued tokens with which role and when. Being able to correlate this with Kubernetes API audit logs makes it even more useful.

  • 403 Forbidden: Role/RoleBinding in the wrong namespace, or a resourceNames mismatch
  • TTL truncation: hitting the cluster's TokenRequest cap. Raising Vault-side TTL cannot exceed it
  • Audience mismatch: align with the target service's verifying audience (e.g. https://kubernetes.default.svc)

Practical commands for auditing and verification

# Check the lease (Vault side)
vault list sys/leases/lookup/kubernetes

# Recent issue requests (grep the Vault audit log)
# Assumes the file audit device writes to /var/log/vault_audit.log
grep 'kubernetes/issue/ci-deployer' /var/log/vault_audit.log | tail -n 20

# Test the Kubernetes-side permissions (a permission review)
kubectl auth can-i create serviceaccounts/token --as=system:serviceaccount:vault:vault-k8s-se -n apps

Check Your Understanding

Ops

Question 1

Which statement about dynamically issuing Service Account tokens with Vault's Kubernetes secrets engine is correct?

  1. Tokens issued via Kubernetes TokenRequest are short-lived and generally cannot be revoked early, so short TTLs and automated reissue are the assumed model
  2. The Kubernetes secrets engine is the same as Vault's Kubernetes auth method, used by Pods to log in to Vault
  3. TokenRequest can be executed regardless of Kubernetes RBAC, so Vault needs no special permissions
  4. Operations are simpler than with static Service Account tokens, but the TTL setting cannot be controlled on the Kubernetes side

Correct answer: A

The secrets engine uses TokenRequest to issue short-lived SA tokens. Issued tokens generally cannot be revoked early, so short TTLs and automated rotation are the assumed design. The Kubernetes auth method serves a different purpose (Pod-to-Vault login). Executing TokenRequest requires create permission on serviceaccounts/token, and TTLs can be shortened by Kubernetes-side caps.

Frequently Asked Questions

How can I revoke a token early?

SA tokens issued by TokenRequest are designed to expire naturally with time, and there is generally no way to revoke them early. Use a short TTL, re-issue frequently, and keep role/permission scopes tight. If something goes wrong, contain the blast radius by reducing the Service Account's permissions or deleting it.

I set a long TTL, but the expiration is still short. Why?

The Kubernetes cluster caps token lifetime via the TokenRequest upper limit (the maximum allowed expirationSeconds). Increasing ttl/max_ttl on the Vault side will not exceed that cap. Either revisit the cluster configuration, or adjust your job duration to fit the cluster's limit.

Can the Kubernetes auth method and secrets engine be used together?

Yes. The two are typically combined: workloads log in to Vault via the Kubernetes auth method, while other workloads or CI/CD pipelines obtain short-lived Kubernetes credentials via the Kubernetes secrets engine. Separate the roles and permissions, and use policies to prevent the two from interfering with each other.

Check what you learned with practice questions

Practice with certification-focused question sets

Try free questions
Author

NicheeLab Editorial Team

NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.


Related articles
Vault

Vault Core Concepts: Sealed/Unsealed, Auth, Secrets (2026)

Vault fundamentals — sealed/unsealed state, auth methods, se...

Vault

Vault Operations Professional (VOP-003): Complete Guide (2026)

Pass the Vault Operations Professional exam — enterprise pat...

Vault

Vault Path-Based Routing: API URL Structure (2026)

How Vault's path-based routing works — mount points, sub-pat...

Vault

Vault Tokens: Auth Token Mechanics (2026)

Token fundamentals — service vs. batch tokens, accessor, ren...

Vault

Vault Token Types: Service, Batch, Periodic (2026)

Service vs. batch tokens compared — performance, ACL behavio...

Browse all Vault articles (101)
© 2026 NicheeLab All rights reserved.