1. Auth Methods Overview
Auth Methods là cơ chế Vault sử dụng để xác thực (authenticate) clients — xác định "bạn là ai" trước khi cho phép truy cập secrets. Mỗi auth method được enable tại một path riêng và trả về một Vault token sau khi xác thực thành công.
Quy trình xác thực
┌──────────┐ 1. Login request ┌───────────────┐
│ Client │ ──────────────────────▶ │ Auth Method │
│ │ │ (AppRole, │
│ │ 4. Vault Token │ LDAP, K8s) │
│ │ ◀────────────────────── │ │
└──────────┘ └───────┬───────┘
│
2. Verify identity
│
3. Map to policies
▼
┌──────────────┐
│ Identity │
│ + Policies │
└──────────────┘
Các loại Auth Methods
| Nhóm | Auth Method | Đối tượng |
|---|---|---|
| Built-in | Token | Mọi client |
| Human | Userpass, LDAP, OIDC | Operators, developers |
| Machine | AppRole, JWT | CI/CD, applications |
| Cloud | AWS, Azure, GCP | Cloud workloads |
| Platform | Kubernetes, SPIFFE | Container workloads |
Enable Auth Method
# Enable auth method tại default path
vault auth enable userpass
# Enable tại custom path
vault auth enable -path=company-ldap ldap
# Liệt kê auth methods đã enable
vault auth list
# Disable auth method (cẩn thận - xóa toàn bộ data)
vault auth disable userpass
2. Token Auth Method
Token Auth Method là auth method duy nhất luôn được enable và không thể disable. Mọi auth method khác cuối cùng đều trả về một Vault token. Token là cơ chế xác thực cốt lõi của Vault.
Token Types
| Loại | Stored | Renewable | Child tokens | Use case |
|---|---|---|---|---|
| Service Token | Có (trong storage) | Có | Có | Long-lived operations |
| Batch Token | Không | Không | Không | High-volume, ephemeral |
Tạo tokens
# Tạo token với default policy
vault token create
# Tạo token với policies cụ thể
vault token create \
-policy="app-readonly" \
-policy="db-creds" \
-ttl=1h \
-display-name="app-service"
# Tạo orphan token (không có parent)
vault token create -orphan \
-policy="monitoring" \
-ttl=24h
# Tạo batch token
vault token create \
-type=batch \
-policy="app-readonly" \
-ttl=30m
# Tạo periodic token (không bao giờ expire nếu renew đúng hạn)
vault token create \
-policy="long-running-service" \
-period=24h
Root Tokens
Root token có quyền truy cập toàn bộ Vault. Chỉ nên sử dụng trong các trường hợp khẩn cấp:
# Tạo root token mới (cần quorum unseal keys)
vault operator generate-root -init
vault operator generate-root \
-nonce="..." \
-otp="..."
# Revoke root token sau khi dùng xong
vault token revoke <root-token>
Best practice: Không lưu trữ root token. Tạo khi cần, dùng xong thì revoke ngay.
Token Roles
# Tạo token role cho CI/CD
vault write auth/token/roles/ci-cd \
allowed_policies="ci-deploy,ci-readonly" \
disallowed_policies="admin,root" \
orphan=true \
renewable=true \
token_period=1h \
token_type=service \
token_bound_cidrs="10.0.0.0/8"
# Tạo token từ role
vault token create -role=ci-cd
Token Accessors
Token accessor cho phép quản lý token mà không cần biết giá trị token:
# Lookup token bằng accessor
vault token lookup -accessor <accessor>
# Revoke token bằng accessor
vault token revoke -accessor <accessor>
# Liệt kê tất cả token accessors
vault list auth/token/accessors
3. Userpass Auth Method
Userpass là auth method đơn giản nhất cho human users — xác thực bằng username và password. Phù hợp cho môi trường nhỏ hoặc testing.
Enable và cấu hình
# Enable userpass
vault auth enable userpass
# Tạo user với policies
vault write auth/userpass/users/john.doe \
password="s3cur3P@ssw0rd" \
policies="dev-readonly,dev-kv" \
token_ttl=8h \
token_max_ttl=24h
# Tạo user với CIDR binding
vault write auth/userpass/users/admin.user \
password="adm1nP@ss" \
policies="admin" \
token_ttl=2h \
token_bound_cidrs="10.10.0.0/16,192.168.1.0/24"
# Liệt kê users
vault list auth/userpass/users
# Đọc thông tin user
vault read auth/userpass/users/john.doe
Login
# Login qua CLI
vault login -method=userpass \
username=john.doe \
password="s3cur3P@ssw0rd"
# Login qua API
curl -s --request POST \
--data '{"password": "s3cur3P@ssw0rd"}' \
${VAULT_ADDR}/v1/auth/userpass/login/john.doe | jq .
Password Policies
Vault 1.5+ hỗ trợ password policies để enforce password complexity:
# Tạo password policy
vault write sys/policies/password/strong-password policy=-<<EOF
length=20
rule "charset" {
charset = "abcdefghijklmnopqrstuvwxyz"
min-chars = 2
}
rule "charset" {
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
min-chars = 2
}
rule "charset" {
charset = "0123456789"
min-chars = 2
}
rule "charset" {
charset = "!@#$%^&*()-_=+[]{}|;:,.<>?"
min-chars = 2
}
EOF
# Sinh password theo policy
vault read sys/policies/password/strong-password/generate
# Áp dụng password policy cho userpass
vault write auth/userpass/users/secure.user \
password="$(vault read -field=password sys/policies/password/strong-password/generate)" \
policies="dev-readonly"
Cập nhật và xóa user
# Cập nhật password
vault write auth/userpass/users/john.doe \
password="n3wP@ssw0rd!"
# Cập nhật policies (không thay đổi password)
vault write auth/userpass/users/john.doe/policies \
policies="dev-readonly,dev-kv,staging-deploy"
# Xóa user
vault delete auth/userpass/users/john.doe
4. AppRole Auth Method
AppRole là auth method được thiết kế cho machine-to-machine authentication. Đây là phương pháp phổ biến nhất để ứng dụng và CI/CD pipelines xác thực với Vault.
Khái niệm cốt lõi
┌─────────────────────────────────────────────────────────┐
│ AppRole Login │
│ │
│ RoleID (public identifier) │
│ + SecretID (private credential) │
│ = Vault Token (with assigned policies) │
│ │
│ Tương tự: username + password = session token │
└─────────────────────────────────────────────────────────┘
| Thành phần | Mô tả | Tương tự |
|---|---|---|
| RoleID | Identifier công khai của role | Username |
| SecretID | Credential bí mật, ngắn hạn | Password |
Enable và tạo Role
# Enable AppRole
vault auth enable approle
# Tạo role cho web application
vault write auth/approle/role/webapp \
token_policies="webapp-policy,db-readonly" \
token_ttl=1h \
token_max_ttl=4h \
secret_id_ttl=30m \
secret_id_num_uses=1 \
token_num_uses=0 \
bind_secret_id=true
# Tạo role cho CI/CD pipeline
vault write auth/approle/role/cicd-pipeline \
token_policies="cicd-deploy" \
token_ttl=30m \
token_max_ttl=1h \
secret_id_ttl=10m \
secret_id_num_uses=1 \
token_num_uses=10 \
bind_secret_id=true \
secret_id_bound_cidrs="10.0.0.0/8" \
token_bound_cidrs="10.0.0.0/8"
Các parameters quan trọng
| Parameter | Mô tả | Recommendation |
|---|---|---|
secret_id_ttl | TTL của SecretID | Càng ngắn càng tốt (5-30m) |
secret_id_num_uses | Số lần sử dụng SecretID | 1 (one-time use) |
token_ttl | TTL mặc định của token | Đủ cho operation |
token_max_ttl | TTL tối đa (kể cả renew) | Giới hạn hợp lý |
token_num_uses | Số lần token được sử dụng | 0 = unlimited |
secret_id_bound_cidrs | CIDR cho phép dùng SecretID | Restrict theo network |
token_bound_cidrs | CIDR cho phép dùng token | Restrict theo network |
Quy trình Login
# Bước 1: Lấy RoleID (thường được bake vào config/image)
vault read auth/approle/role/webapp/role-id
# role_id db02de05-fa39-4855-059b-67f86261c393
# Bước 2: Sinh SecretID (thường do trusted orchestrator sinh)
vault write -f auth/approle/role/webapp/secret-id
# secret_id 6a174c20-f6de-a53c-74d2-6018fcceff64
# secret_id_accessor c454f7e5-996e-7230-6074-6ef26b7bcf86
# Bước 3: Login
vault write auth/approle/login \
role_id="db02de05-fa39-4855-059b-67f86261c393" \
secret_id="6a174c20-f6de-a53c-74d2-6018fcceff64"
Response Wrapping cho SecretID
Response wrapping là cơ chế bảo mật quan trọng — SecretID được "gói" trong một wrapping token ngắn hạn. Chỉ application đích mới có thể unwrap:
# Sinh SecretID với response wrapping (TTL 120 giây)
vault write -wrap-ttl=120s -f auth/approle/role/webapp/secret-id
# Response chứa wrapping_token thay vì secret_id trực tiếp
# wrapping_token: hvs.CAES...
# wrapping_accessor: ...
# wrapping_token_ttl: 2m
# wrapping_token_creation_time: ...
# Application unwrap để lấy SecretID thật
vault unwrap hvs.CAES...
# secret_id 6a174c20-f6de-a53c-74d2-6018fcceff64
# Nếu ai đó đã unwrap trước → lỗi (phát hiện MITM)
vault unwrap hvs.CAES...
# Error: wrapping token is not valid or does not exist
Phát hiện tấn công
Nếu wrapping token bị unwrap bởi attacker trước application:
Application sẽ nhận lỗi khi unwrap → alert ngay lập tức
Kiểm tra audit log để tìm source IP của attacker
Revoke role và re-issue credentials
5. AppRole Best Practices cho CI/CD
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy with Vault
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Import Secrets from Vault
uses: hashicorp/vault-action@v3
with:
url: https://vault.company.com
method: approle
roleId: ${{ secrets.VAULT_ROLE_ID }}
secretId: ${{ secrets.VAULT_SECRET_ID }}
secrets: |
secret/data/production/db username | DB_USERNAME ;
secret/data/production/db password | DB_PASSWORD ;
secret/data/production/api key | API_KEY
- name: Deploy application
run: |
echo "Deploying with secrets..."
./deploy.sh
env:
DB_USERNAME: ${{ env.DB_USERNAME }}
DB_PASSWORD: ${{ env.DB_PASSWORD }}
GitLab CI
# .gitlab-ci.yml
stages:
- deploy
deploy-production:
stage: deploy
image: hashicorp/vault:1.21
variables:
VAULT_ADDR: "https://vault.company.com"
script:
- |
# Login với AppRole
VAULT_TOKEN=$(vault write -field=token auth/approle/login \
role_id="${VAULT_ROLE_ID}" \
secret_id="${VAULT_SECRET_ID}")
export VAULT_TOKEN
# Lấy secrets
DB_PASSWORD=$(vault kv get -field=password secret/production/db)
export DB_PASSWORD
# Deploy
./deploy.sh
only:
- main
Jenkins Pipeline
// Jenkinsfile
pipeline {
agent any
environment {
VAULT_ADDR = 'https://vault.company.com'
}
stages {
stage('Get Secrets') {
steps {
withVault(
configuration: [
vaultUrl: "${VAULT_ADDR}",
vaultCredentialId: 'vault-approle'
],
vaultSecrets: [
[
path: 'secret/production/db',
secretValues: [
[envVar: 'DB_USER', vaultKey: 'username'],
[envVar: 'DB_PASS', vaultKey: 'password']
]
]
]
) {
sh './deploy.sh'
}
}
}
}
}
6. AppRole Deployment Pattern
Trusted Orchestrator Pattern
┌──────────────┐ ┌──────────────┐
│ Terraform/ │ 1. Sinh SecretID │ Vault │
│ Ansible │ ──────────────────▶│ │
│ (Orchestrator)│◀──────────────────│ │
│ │ 2. Wrapped token │ │
└──────┬───────┘ └──────────────┘
│
│ 3. Deliver wrapped token
▼
┌──────────────┐ ┌──────────────┐
│ Application │ 4. Unwrap → │ Vault │
│ │ SecretID │ │
│ │ 5. Login │ │
│ │ (RoleID + │ │
│ │ SecretID) │ │
│ │ 6. Vault Token │ │
└──────────────┘ └──────────────┘
RoleID được bake vào AMI/Docker image hoặc config management
SecretID được sinh bởi trusted orchestrator (Terraform, Ansible, CI/CD)
SecretID được deliver dưới dạng wrapped token cho bảo mật
Application unwrap để lấy SecretID, rồi login với RoleID + SecretID
Pull vs Push model
| Model | Cách hoạt động | Ưu điểm | Nhược điểm |
|---|---|---|---|
| Pull | App tự login Vault, lấy secrets | App kiểm soát lifecycle | App cần biết Vault |
| Push | Orchestrator inject secrets vào app | App không cần biết Vault | Secrets trong env/file |
7. Bảo mật Auth Methods
Sai lầm thường gặp
❌ Sử dụng root token trong application
❌ SecretID có TTL quá dài hoặc unlimited uses
❌ Không set CIDR binding cho AppRole
❌ Hardcode RoleID + SecretID trong source code
❌ Dùng userpass cho machine authentication
Best practices tổng hợp
✅ SecretID:
num_uses=1,ttl=5m-30m✅ Luôn sử dụng response wrapping cho SecretID
✅ Set
secret_id_bound_cidrsvàtoken_bound_cidrs✅ Mỗi ứng dụng/service có role riêng
✅ Revoke root token sau khi sử dụng
✅ Enable audit logging để track mọi authentication
8. Tổng kết
Trong bài này, chúng ta đã tìm hiểu 3 auth methods cơ bản nhất của Vault:
Token Auth — auth method nền tảng, mọi auth method đều tạo token
Userpass Auth — đơn giản cho human users, hỗ trợ password policies
AppRole Auth — tiêu chuẩn cho machine authentication, hỗ trợ CI/CD workflows
AppRole với response wrapping là pattern được khuyến nghị nhất cho CI/CD pipelines. Trong bài tiếp theo, chúng ta sẽ tìm hiểu LDAP, OIDC và JWT Auth Methods — các phương pháp xác thực enterprise cho cả human và machine identities.