Chuyển đến nội dung chính

Bài 19: Vault Agent và Vault Proxy

Vault Agent overview, Auto-auth, Template rendering, File sink, Agent caching, Vault Proxy, API proxy mode. So sánh Agent vs Proxy, deployment patterns.

🔒 DevSecOps — Bài 19 Bài 19: Vault Agent và Vault Proxy

HashiCorp Vault từ Cơ bản đến Nâng cao

Phần 5: Vault Agent, Proxy và Kubernetes Integration

xdev.asia

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ăngVault AgentVault Proxy
Auto-auth✅✅
Template rendering✅❌
API Proxy✅✅
Caching✅✅
Process Supervisor✅❌
FootprintLớn hơnNhỏ gọn hơn
Use caseCần render filesChỉ 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.