Agent cần secret để hoạt động: OpenAI API key, token database, credential gọi API thanh toán. Secret bị lộ = danh tính bị chiếm. Bài này chỉ cho bạn cách cất giữ và cấp phát secret sao cho ngay cả khi code hay log rò rỉ, secret vẫn an toàn.
Nguyên tắc vàng: secret không bao giờ nằm cạnh code
Secret không được xuất hiện ở:
- Source code (kể cả comment).
- File cấu hình commit lên Git.
- Prompt gửi cho LLM (đây là lỗi đặc thù của agent!).
- Log và output trả về người dùng.
- Biến môi trường (
.envkhông commit) — mức tối thiểu. - Secret manager (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager) — chuẩn production.
- Ephemeral / dynamic secret — Vault sinh credential dùng-một-lần, tự hết hạn.
Ví dụ: từ hardcode tệ hại đến Vault
Tệ (secret trong code):
client = OpenAI(api_key="sk-live-Abc123RealKey") # KHÔNG BAO GIỜ
Cơ bản (biến môi trường):
import os
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# .gitignore PHẢI có dòng này
.env
Production (lấy động từ secret manager, không lưu ổ đĩa):
import hvac
vault = hvac.Client(url="https://vault.internal:8200")
vault.auth.approle.login(role_id=ROLE_ID, secret_id=SECRET_ID)
secret = vault.secrets.kv.v2.read_secret_version(path="agent/openai")
api_key = secret["data"]["data"]["api_key"] # chỉ nằm trong RAM
Agent tự xác thực với Vault bằng danh tính riêng (AppRole), rồi lấy key vào bộ nhớ — không có file .env chứa key thật trên server.
Các bước thiết lập quản lý secret
- Kiểm kê mọi secret agent cần và mức nhạy cảm từng cái.
- Đưa secret ra khỏi code: dùng env var cho dev, secret manager cho prod.
- Cấp cho agent một danh tính để tự lấy secret (AppRole, IAM role, workload identity).
- Bật rotation tự động: key xoay định kỳ (ví dụ 30 ngày) hoặc dùng dynamic secret.
- Quét rò rỉ: chạy
gitleaks/trufflehogtrong CI để chặn commit chứa secret. - Lọc secret khỏi prompt và log bằng lớp redaction.
Chống rò rỉ secret vào prompt/log
Lỗi kinh điển của agent: nhét cả biến môi trường vào context, hoặc log full request. Hãy thêm bộ lọc:
import re
SECRET_PATTERNS = [r"sk-[A-Za-z0-9]{20,}", r"AKIA[0-9A-Z]{16}"]
def redact(text: str) -> str:
for p in SECRET_PATTERNS:
text = re.sub(p, "[REDACTED]", text)
return text
logger.info(redact(prompt)) # log đã được che
Khung tư duy: vòng đời secret
Mỗi secret đi qua 5 giai đoạn — kiểm soát cả 5:
Sinh → Lưu → Cấp phát → Xoay (rotate) → Thu hồi (revoke).
Nếu bạn chỉ lo khâu "lưu" mà quên "xoay" và "thu hồi", secret cũ vẫn là cửa hậu mãi mãi.
Dynamic secret: đỉnh cao của quản lý secret
Mức trưởng thành nhất là không lưu secret cố định nào cả. Vault có thể sinh credential database dùng-một-lần mỗi khi agent cần, tự hủy sau vài phút:
# Vault sinh user/pass database tạm, TTL 5 phút
creds = vault.secrets.database.generate_credentials(
name="agent-analytics-role")
user, pwd = creds["data"]["username"], creds["data"]["password"]
# dùng xong Vault tự thu hồi, không còn gì để lộ
Với cách này, không có "key vàng" nào tồn tại lâu để đánh cắp. Mỗi phiên agent dùng một bộ credential riêng, tự hết hạn — kết hợp hoàn hảo với danh tính riêng ở Bài 4. Nếu chưa dùng được dynamic secret, tối thiểu hãy đảm bảo mỗi môi trường (dev/staging/prod) và mỗi agent có secret khác nhau, để một lần lộ không kéo theo toàn bộ hệ thống.
Checklist secret
- [ ] Không secret nào nằm trong code/Git (đã quét bằng gitleaks).
- [ ] Prod dùng secret manager, không phải file
.envtrần. - [ ] Agent lấy secret bằng danh tính riêng, không dùng chung.
- [ ] Có rotation tự động hoặc dynamic secret.
- [ ] Prompt và log được lọc secret (redaction).
- [ ] Có quy trình thu hồi khẩn khi nghi lộ.
Sai lầm thường gặp
- Commit
.envlên Git rồi mới xóa — nhưng secret còn nguyên trong lịch sử commit. Phải rotate ngay. - Đưa API key vào system prompt để "agent tự gọi API" — LLM có thể lặp lại key trong câu trả lời.
- Một key dùng cho mọi agent và mọi môi trường — lộ một chỗ, mất tất cả, và không biết ai gây ra.
- Không bao giờ rotate: key sống 3 năm, nhân viên nghỉ việc vẫn giữ được.
- Log full HTTP request kèm header
Authorization— token nằm chình ình trong log tập trung.