Series HashiCorp Vault Thực chiến | Bài 3: AppRole - "Giấy thông hành" chuyên dụng cho Backend Microservices
Chào anh em!
Ở Bài 2, chúng ta đã cất giấu thành công thông tin Database vào Vault KV Secrets Engine và thao tác qua CLI bằng root_token_123.
Nhưng hãy nhớ một quy tắc vàng trong bảo mật: Không bao giờ dùng Root Token cho ứng dụng Production. Root Token giống như chìa khóa master mở toàn bộ tòa nhà; nếu một Microservice bị lộ token này, hacker sẽ kiểm soát toàn bộ hệ thống.
Vậy Backend Service (ví dụ: Node.js, Go, hoặc Laravel Service) làm sao để xác thực với Vault một cách an toàn? Câu trả lời chính là AppRole Authentication Method.
1. AppRole là gì? Cơ chế hoạt động ra sao?
AppRole là phương thức xác thực sinh ra dành riêng cho các ứng dụng tự động, dịch vụ ngầm (Background Workers) hoặc Microservices chạy trên server vật lý/cloud.
Thay vì dùng username/password tĩnh, AppRole sử dụng cặp đôi giá trị để xác thực, tương tự như khái niệm Client ID và Client Secret trong OAuth2:
- RoleID: Giống như tên định danh của service (Ví dụ:
afc-ticket-service-role). Giá trị này tương đối công khai, không quá nhạy cảm. - SecretID: Giống như một dạng mật khẩu dùng một lần hoặc có thời hạn, cực kỳ nhạy cảm và chỉ cấp cho service trong quá trình deploy.
Quy trình xác thực diễn ra như sau:
- Ứng dụng Backend khởi động, mang theo
RoleIDvàSecretIDgọi lên Vault. - Vault đối chiếu, xác nhận đúng là Service được phép.
- Vault cấp trả về một Client Token ngắn hạn (Short-lived Token).
- Ứng dụng dùng Client Token này để đọc các Secrets cần thiết từ Vault (như thông tin Database) rồi tự hủy hoặc tự gia hạn token.
2. Thực hành cấu hình AppRole trên Vault Dev Server
Hãy quay trở lại terminal đang chạy container vault-dev của chúng ta (hoặc dùng lệnh docker exec -it vault-dev sh) để thiết lập AppRole từ A-Z.
Bước A: Bật tính năng xác thực AppRole
Mặc định Vault chưa bật sẵn AppRole cho mọi đường dẫn, ta cần kích hoạt nó:
vault auth enable approle
Terminal sẽ báo thành công: Success! Enabled approle auth method at: approle/
Bước B: Tạo một Policy (Luật phân quyền) cho Service
Như đã nói ở Bài 1, chúng ta áp dụng nguyên tắc tối thiểu đặc quyền (Least Privilege). Service bán vé chỉ được ĐỌC dữ liệu ở đường dẫn secret/data/afc-system/mysql.
Tạo file policy tên là ticket-policy.hcl bằng lệnh vi hoặc tạo trực tiếp nội dung:
# Cho phép đọc (read) các secret tại đường dẫn mysql
path "secret/data/afc-system/mysql" {
capabilities = ["read"]
}
Đưa policy này lên Vault:
vault policy write ticket-policy ticket-policy.hcl
Bước C: Tạo AppRole gắn với Policy vừa tạo
Bây giờ, chúng ta khai báo một AppRole tên là ticket-service-role và gắn policy ticket-policy vào nó:
vault write auth/approle/role/ticket-service-role \
secret_id_ttl=30m \
token_ttl=1h \
token_max_ttl=4h \
policies="ticket-policy"
Giải thích các tham số:
secret_id_ttl=30m: SecretID sinh ra sẽ hết hạn sau 30 phút (tăng tính bảo mật).token_ttl=1h: Token cấp cho service có thời hạn sống 1 tiếng.policies="ticket-policy": Gắn luật phân quyền ở Bước B vào role này.
3. Lấy RoleID và SecretID để đưa vào Backend
Bây giờ cấu hình đã xong, chúng ta cần lấy thông tin để cấu hình cho ứng dụng Backend của bạn.
1. Lấy RoleID:
vault read auth/approle/role/ticket-service-role/role-id
Kết quả trả về sẽ hiển thị một chuỗi UUID, ví dụ: role-id: a1b2c3d4-e5f6-... -> Đây chính là RoleID.
2. Sinh SecretID:
Vì SecretID là bí mật tuyệt đối, ta dùng lệnh sau để Vault cấp mới:
vault write -f auth/approle/role/ticket-service-role/secret-id
Kết quả trả về sẽ sinh ra một chuỗi secret-id, ví dụ: secret-id: 9z8y7x6w-v5u4-... -> Đây chính là SecretID.
Giả sử ứng dụng Backend của bạn đã khởi động và nhận được 2 thông số trên (thường được cấp qua biến môi trường hoặc hệ thống CI/CD lúc deploy). Ứng dụng sẽ gọi lệnh đăng nhập để lấy Client Token:
vault write auth/approle/login role_id="<RoleID_vừa_lấy>" secret_id="<SecretID_vừa_lấy>"
Ngay lập tức, Vault sẽ trả về một bảng thông tin chứa token (Client Token).
Ứng dụng của bạn sẽ dùng token này để gọi lệnh đọc mật khẩu Database:
# Gán token tạm thời vừa nhận được
export VAULT_TOKEN='<Client_Token_Vừa_Nhận>'
# Gọi đọc secret
vault kv get secret/afc-system/mysql
Thành công! Dù không dùng Root Token, ứng dụng của bạn vẫn lấy được thông tin Database nhờ cơ chế xác thực AppRole cực kỳ chặt chẽ.
Tổng kết Bài 3
Anh em đã nắm được cách cô lập quyền hạn của ứng dụng bằng AppRole:
- Không còn rủi ro lộ Root Token.
- Phân quyền rõ ràng ứng dụng nào được đọc đường dẫn nào (Policies).
- Quản lý vòng đời thông tin xác thực (TTL).
All Rights Reserved