1. Vault Agent Overview
Vault Agent là một daemon client chạy bên cạnh application, tự động xử lý authentication, token renewal, và secret retrieval. Agent giải quyết "Secret Zero" problem — application không cần biết cách xác thực với Vault.
Chức năng chính
Auto-auth — tự động xác thực và renew tokens
Template rendering — render secrets vào config files
Caching — cache responses để giảm load cho Vault server
API Proxy — ứng dụng gọi Agent thay vì gọi Vault trực tiếp
Kiến trúc
┌─────────────────────────────────────────────────┐
│ Application Host │
│ │
│ ┌──────────┐ ┌───────────────┐ │
│ │ App │ Read files │ Vault Agent │ │
│ │ │ ◀──────────── │ │ │
│ │ │ (rendered │ Auto-auth │ │
│ │ │ templates) │ Templates │ │
│ │ │ │ Caching │ │
│ └──────────┘ └───────┬───────┘ │
│ │ │
└──────────────────────────────────────┼─────────┘
│
Vault API (HTTPS)
│
▼
┌──────────────┐
│ Vault Server │
└──────────────┘
2. Auto-auth
Auto-auth tự động xác thực với Vault và renew tokens. Hỗ trợ tất cả auth methods:
# vault-agent.hcl
vault {
address = "https://vault.company.com:8200"
tls_skip_verify = false
}
auto_auth {
method "kubernetes" {
mount_path = "auth/kubernetes"
config = {
role = "webapp"
}
}
# Lưu token vào file
sink "file" {
config = {
path = "/tmp/vault-token"
mode = 0640
}
}
# Lưu token vào file khác (wrapped)
sink "file" {
wrap_ttl = "5m"
config = {
path = "/tmp/vault-token-wrapped"
}
}
}
Auto-auth với AppRole
auto_auth {
method "approle" {
mount_path = "auth/approle"
config = {
role_id_file_path = "/etc/vault/role-id"
secret_id_file_path = "/etc/vault/secret-id"
remove_secret_id_file_after_reading = true
}
}
sink "file" {
config = {
path = "/tmp/vault-token"
}
}
}
Auto-auth với AWS IAM
auto_auth {
method "aws" {
mount_path = "auth/aws"
config = {
type = "iam"
role = "webapp"
header_value = "vault.company.com"
}
}
sink "file" {
config = {
path = "/tmp/vault-token"
}
}
}
3. Template Rendering
Vault Agent sử dụng Consul Template syntax để render secrets vào config files. Templates tự động re-render khi secrets thay đổi.
Cấu hình Template
# vault-agent.hcl (tiếp)
template {
source = "/etc/vault/templates/app.conf.tpl"
destination = "/etc/app/app.conf"
perms = 0640
command = "systemctl reload app" # Chạy sau khi render
error_on_missing_key = true
}
template {
source = "/etc/vault/templates/db.env.tpl"
destination = "/etc/app/db.env"
perms = 0600
}
# Inline template (không cần file tpl)
template {
contents = "{{ with secret \"secret/data/app/config\" }}DB_HOST={{ .Data.data.host }}{{ end }}"
destination = "/etc/app/db-host"
}
Template Syntax
# /etc/vault/templates/app.conf.tpl
# KV v2 secret
{{ with secret "secret/data/production/db" }}
DB_HOST={{ .Data.data.host }}
DB_PORT={{ .Data.data.port }}
DB_NAME={{ .Data.data.database }}
DB_USER={{ .Data.data.username }}
DB_PASS={{ .Data.data.password }}
{{ end }}
# Dynamic database credentials
{{ with secret "database/creds/app-role" }}
DB_DYNAMIC_USER={{ .Data.username }}
DB_DYNAMIC_PASS={{ .Data.password }}
# Lease: {{ .LeaseID }} ({{ .LeaseDuration }}s)
{{ end }}
# PKI certificate
{{ with secret "pki/issue/app-cert" "common_name=app.company.com" "ttl=24h" }}
{{ .Data.certificate }}
{{ .Data.private_key }}
{{ end }}
# Conditional
{{ with secret "secret/data/production/feature-flags" }}
{{ if .Data.data.enable_cache }}
CACHE_ENABLED=true
CACHE_TTL={{ .Data.data.cache_ttl }}
{{ else }}
CACHE_ENABLED=false
{{ end }}
{{ end }}
Environment Variable Template
# /etc/vault/templates/db.env.tpl
{{ with secret "secret/data/production/db" -}}
export DB_HOST="{{ .Data.data.host }}"
export DB_PORT="{{ .Data.data.port }}"
export DB_USER="{{ .Data.data.username }}"
export DB_PASS="{{ .Data.data.password }}"
{{- end }}
4. Agent Caching
# Caching configuration
cache {
use_auto_auth_token = true
persist {
type = "kubernetes"
path = "/vault/agent-cache"
}
}
listener "tcp" {
address = "127.0.0.1:8100"
tls_disable = true
}
Applications gọi Agent (localhost:8100) thay vì gọi Vault server trực tiếp. Agent cache responses và tự động handle authentication.
5. Vault Proxy
Vault Proxy (Vault 1.14+) là phiên bản simplified của Vault Agent, tập trung vào API proxying và caching mà không có template rendering.
# vault-proxy.hcl
vault {
address = "https://vault.company.com:8200"
}
auto_auth {
method "kubernetes" {
mount_path = "auth/kubernetes"
config = {
role = "webapp"
}
}
}
api_proxy {
use_auto_auth_token = "force"
}
cache {
use_auto_auth_token = true
persist {
type = "kubernetes"
path = "/vault/proxy-cache"
}
}
listener "tcp" {
address = "127.0.0.1:8100"
tls_disable = true
}
Static Secret Caching
# Cache static secrets (KV v2)
cache {
use_auto_auth_token = true
persist {
type = "kubernetes"
path = "/vault/proxy-cache"
}
# Static secret caching (mới)
static_secret_token_wait = "5s"
}
6. Agent vs Proxy — Khi nào dùng cái nào?
| Tính năng | Vault Agent | Vault Proxy |
|---|---|---|
| Auto-auth | ✅ | ✅ |
| Template rendering | ✅ | ❌ |
| API Proxy | ✅ | ✅ |
| Caching | ✅ | ✅ |
| Process Supervisor | ✅ | ❌ |
| Footprint | Lớn hơn | Nhỏ gọn hơn |
| Use case | Cần render files | Chỉ cần API proxy |
Agent: Khi application đọc secrets từ files (config files, env files)
Proxy: Khi application gọi Vault API trực tiếp, cần caching và auto-auth
7. Deployment Patterns
Systemd Service
# /etc/systemd/system/vault-agent.service
[Unit]
Description=Vault Agent
Requires=network-online.target
After=network-online.target
[Service]
User=vault
Group=vault
ExecStart=/usr/bin/vault agent -config=/etc/vault/agent.hcl
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGTERM
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Docker Sidecar
# docker-compose.yml
services:
vault-agent:
image: hashicorp/vault:1.21
command: vault agent -config=/vault/config/agent.hcl
volumes:
- ./agent.hcl:/vault/config/agent.hcl:ro
- ./templates:/vault/templates:ro
- shared-secrets:/vault/secrets
restart: unless-stopped
webapp:
image: myapp:latest
volumes:
- shared-secrets:/etc/app/secrets:ro
depends_on:
- vault-agent
volumes:
shared-secrets:
Kubernetes Init Container
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
initContainers:
- name: vault-agent-init
image: hashicorp/vault:1.21
command: ["vault", "agent", "-config=/vault/config/agent.hcl", "-exit-after-auth"]
volumeMounts:
- name: vault-config
mountPath: /vault/config
- name: vault-secrets
mountPath: /vault/secrets
containers:
- name: webapp
image: myapp:latest
volumeMounts:
- name: vault-secrets
mountPath: /etc/app/secrets
readOnly: true
volumes:
- name: vault-config
configMap:
name: vault-agent-config
- name: vault-secrets
emptyDir:
medium: Memory
8. Tổng kết
Vault Agent — full-featured daemon: auto-auth, templates, caching, API proxy
Vault Proxy — lightweight proxy: auto-auth, caching, API proxy (no templates)
Auto-auth — tự động xác thực và renew tokens, giải quyết Secret Zero
Templates — render secrets vào config files, auto re-render khi secrets thay đổi
Deployment patterns — systemd, Docker sidecar, K8s init/sidecar container
Bài tiếp theo sẽ đi sâu vào Vault trên Kubernetes — Helm chart, Vault Secrets Operator, CSI Provider và Agent Injector.