The standard way to securely authenticate Kubernetes Pods to Vault is the Kubernetes Auth Method backed by Service Account tokens. This article walks through RBAC and role design, plus the implementation details of secret distribution via the Vault Agent Injector sidecar, from both exam and operational perspectives.
On the Associate exam, expect questions on the components of auth/kubernetes, how Service Accounts map to Vault roles, Agent Injector annotations and behavior, and the concepts of token renewal and TTL. The configuration examples, comparison tables, and diagrams below should help cement the picture.
The Kubernetes Auth Method uses the Service Account (SA) JWT that is auto-mounted into a Pod. Vault validates it through the Kubernetes API and issues a Vault token in return. In the sidecar pattern, the Vault Agent handles auto-authentication, secret fetching, and template rendering inside the Pod, and the application reads secrets from files.
In practice, distributing secrets via files through a sidecar (or Init container) is usually easier to operate than having the application talk to Vault directly, and it makes rotation and reload control simpler. The diagram below shows the flow from authentication to secret injection.
| Pattern | Pros | Considerations |
|---|---|---|
| App logs in to Vault directly (SDK / HTTP) | Fewer dependencies; offers flexible control. | App must implement auth, renewal, and retries — and the implementation varies per language. |
| Sidecar (Vault Agent Injector) | Easy to onboard via Pod annotations; auto-auth, templating, and renewal are bundled together. | Extra container consumes resources; you need to understand the annotations and permission model. |
| Init container for one-shot injection | Completes at startup; the app only needs to read a file. | Weak at post-startup rotation; updates require a Pod restart. |
| CSI driver (Secrets Store CSI + Vault provider) | Accessed via a standard K8s volume; files can be projected without going through a K8s Secret. | Adds cluster-side operational overhead; you need to understand feature gaps and sync behavior. |
Typical Kubernetes Auth + sidecar flow
Minimal configuration in concept (excerpt)
# Pod内のService Accountトークンを使い、VaultのKubernetes Authでlogin。
# SidecarのVault Agentがテンプレートでシークレットをファイル出力し、
# アプリはread-onlyでマウントされたボリュームから読み取る。On the Vault server, enable the Kubernetes Auth Method, prepare a Service Account that can call TokenReview against the Kubernetes API, and register the required information into auth/kubernetes/config. This lets Vault validate Pod JWTs as legitimate Kubernetes-issued tokens.
Least-privilege RBAC is sufficient — grant only the permissions needed for TokenReview and validating Service Account tokens in the relevant namespaces.
| Parameter | Purpose | Configuration Tip |
|---|---|---|
| kubernetes_host | The Kubernetes API endpoint Vault will query | From inside the cluster, use something like https://$KUBERNETES_PORT_443_TCP_ADDR:443 |
| token_reviewer_jwt | JWT used to call TokenReview against the Kubernetes API | Use a dedicated Service Account's token; Projected Tokens are recommended. |
| kubernetes_ca_cert | The CA certificate for the API server | Mount the cluster CA from a ConfigMap and pass it in; the system trust store may also work (environment dependent). |
Relationship between the configuration components
Enabling Kubernetes Auth and configuring RBAC (example)
# 1) Vault側: Kubernetes Authを有効化
vault auth enable kubernetes
# 2) Reviewer用のService Account/RBAC(kube側)
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault-token-reviewer
namespace: vault
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:token-reviewer
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: vault-token-reviewer-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:token-reviewer
subjects:
- kind: ServiceAccount
name: vault-token-reviewer
namespace: vault
# 3) VaultにK8sクラスタ情報を登録
# 環境に合わせて$K8S_HOST, $REVIEWER_JWT, $CA_CERTを用意
vault write auth/kubernetes/config \
kubernetes_host="$K8S_HOST" \
token_reviewer_jwt="$REVIEWER_JWT" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crtA Vault Kubernetes role binds Vault policies to a specific Service Account name + namespace combination and issues a token to logins from authorized Pods. Use bound_service_account_names, bound_service_account_namespaces, and optionally bound_audiences to constrain the JWT audience.
TTL and token type (service, batch) are also controlled by the role. Choose a TTL that is not too short and decide whether to allow renewal, based on your app's refresh cadence and the cost of restarts.
| Role Design Pattern | When to Use | Risks / Considerations |
|---|---|---|
| Per-SA (fine-grained) | Grant least privilege per microservice | Role count grows; consistent naming and management become important |
| Per-namespace (medium-grained) | Share the same permissions across multiple Pods in one namespace | Risk of over-permissioning; requires solid namespace boundary discipline |
| Bundle multiple SAs into one role | Manage a group of services with similar requirements together | Poor fit when requirements diverge; future split costs go up |
How roles and policies are wired together
Role creation and policy example
# ポリシー: kv v2の特定パスのみ許可
tee kv-app.hcl <<'EOF'
path "kv/data/app/*" {
capabilities = ["read"]
}
EOF
vault policy write kv-app kv-app.hcl
# ロール: app Namespaceのweb SAにバインド
aud="vault"
vault write auth/kubernetes/role/app-web \
bound_service_account_names=web \
bound_service_account_namespaces=app \
bound_audiences="$aud" \
policies=kv-app \
ttl=1h \
token_type=defaultThe Vault Agent Injector automatically injects a sidecar and shared volume into a Pod just by adding annotations. It authenticates via Kubernetes Auth, evaluates templates, and writes files. The app simply reads them as environment-variable files or config files.
For certificates and short-lived tokens that need rotation, combining the Agent's auto-renewal with SIGHUP-based reloads typically yields a stable setup.
| Annotation Key | Example Value | Effect |
|---|---|---|
| vault.hashicorp.com/agent-inject | "true" | Injects the sidecar and a shared volume |
| vault.hashicorp.com/role | "app-web" | The Vault role used by Kubernetes Auth |
| vault.hashicorp.com/agent-inject-secret-config | "kv/data/app/config" | The secret path that serves as the data source for the template |
| vault.hashicorp.com/agent-inject-template-config | "{{ with secret \\"kv/data/app/config\\" }}{{ .Data.data | toJSON }}{{ end }}" | Template for the file content (Go template syntax) |
In-Pod layout produced by the Injector
Minimal Deployment annotation example (generates config.json from kv v2)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: app
spec:
replicas: 1
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app-web"
# 出力ファイル名は注釈の末尾と一致
vault.hashicorp.com/agent-inject-secret-config: "kv/data/app/config"
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "kv/data/app/config" -}}{{ .Data.data | toJSON }}{{- end -}}
spec:
serviceAccountName: web
containers:
- name: app
image: ghcr.io/example/web:1.0
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
readOnly: true
volumes:
- name: vault-secrets
emptyDir:
medium: MemoryVault tokens issued via Kubernetes Auth are automatically renewable within the role's ttl and max_ttl. The sidecar Agent renews before expiry and retries on failure. If renewal keeps failing, template re-evaluation stops, and the app continues to reference the last file the Agent produced.
For stable operation, combine monitoring (remaining token TTL, template update timestamps), a Pod restart strategy, and SIGHUP-based config reloads. This limits the blast radius if an auth break ever occurs.
| Failure Scenario | Typical Symptoms | Mitigation |
|---|---|---|
| Kubernetes API unreachable | Auth failures, TokenReview errors, continuous retries | Check network and firewall, refresh the API endpoint and CA, add redundant paths |
| SA token audience mismatch | Login fails with an Invalid audience error | Make bound_audiences match the aud in the Pod's Projected Token |
| Policy misconfiguration | Permission denied during template evaluation | Re-check read/list on the required paths and watch out for the /data vs. /metadata split in kv v2 |
Simplified renewal loop
Template example (environment-variable file) and reload
# テンプレート例: .env 形式
{{- with secret "kv/data/app/db" -}}
DB_USER={{ .Data.data.username }}
DB_PASS={{ .Data.data.password }}
{{- end -}}
# アプリ側: ファイル変更検知でSIGHUP
# inotifywait等で /vault/secrets/.env の更新を監視し、プロセスにSIGHUP送出The Associate exam tests terminology and flow. Make sure you firmly grasp the role of the reviewer token, the role binding conditions, what each Injector annotation does, and kv v2 path conventions.
Common pitfalls include login failures from audience or namespace/SA name mismatches, and confusing /data with /metadata in kv v2 paths.
| Topic | Key Point | Common Mistake |
|---|---|---|
| Meaning of TokenReview | Vault verifies the legitimacy of a K8s-issued JWT | Accidentally handing the reviewer token to the app |
| Role conditions | Specify both SA name and namespace | Over-permissioning via excessive namespace wildcards |
| Injector annotations | The role / secret / template trio | Getting the path hierarchy wrong in kv v2 |
Mini glossary diagram
Manual login check via the CLI (for troubleshooting)
# Pod内での手動テスト例(デバッグ用途)
SA_JWT=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
vault write auth/kubernetes/login role=app-web jwt="$SA_JWT"
# auth成功後に VAULT_TOKEN を使って読み取り
echo $VAULT_TOKEN | vault kv get -format=json kv/app/configAssociate
問題 1
You are connecting a Kubernetes app to Vault using the Vault Agent Injector sidecar pattern. From a security and operations perspective, which design is correct?
正解: B
The reviewer token is used by Vault itself to call TokenReview against the Kubernetes API — it is not for the app or the sidecar. The sidecar logs in to auth/kubernetes with the Pod's SA JWT, and the Vault role is wired up via bound_service_account_names and bound_service_account_namespaces. kv v2 paths must include /data/...
Is a dedicated reviewer Service Account always required?
Yes. Vault validates Pod JWTs through the Kubernetes API's TokenReview, so a least-privilege reviewer SA (with matching RBAC) is required. Its token is registered as token_reviewer_jwt in auth/kubernetes/config.
Should I use the Injector sidecar or an Init container?
If you need post-startup rotation or automatic renewal, use the Injector (sidecar). For static settings that only need to be fetched at startup and can tolerate a Pod restart on update, an Init container is also a valid choice.
How do I tell kv v1 and v2 apart, and what should I watch out for?
You can tell from the mount options. kv v2 supports versioning and splits API paths into /data/ and /metadata/. When using Injector annotations or the CLI, remember to include /data in kv v2 paths (e.g. secret/data/...).
Practice with certification-focused question sets
無料で問題を解いてみる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.
Vault Core Concepts: Sealed/Unsealed, Auth, Secrets (2026)
Vault fundamentals — sealed/unsealed state, auth methods, se...
Vault Operations Professional (VOP-003): Complete Guide (2026)
Pass the Vault Operations Professional exam — enterprise pat...
Vault Path-Based Routing: API URL Structure (2026)
How Vault's path-based routing works — mount points, sub-pat...
Vault Tokens: Auth Token Mechanics (2026)
Token fundamentals — service vs. batch tokens, accessor, ren...
Vault Token Types: Service, Batch, Periodic (2026)
Service vs. batch tokens compared — performance, ACL behavio...