Quản Lý Secrets Trong DevOps: Đừng Để API Key Trong Code

Secrets Trong Code — Lỗ Hổng Đáng Sợ
Một developer push API key lên GitHub. 12 phút sau, hàng nghìn USD AWS bill. GitHub ghi nhận hơn 1.3 triệu secrets bị leak mỗi năm.
Secrets nằm trong code, config file hoặc environment variable là rủi ro bảo mật lớn nhất. Hardcoded credentials vi phạm best practice của mọi cloud provider.
Secret Manager Là Gì?
Secret Manager là nơi duy nhất lưu credentials. Thay vì phân tán credentials khắp codebase, mọi service truy xuất từ một endpoint trung tâm. Có 3 nhóm chính:
- Cloud-managed: AWS Secrets Manager, GCP Secret Manager, Azure Key Vault — managed service, tự rotate, auto-scaling.
- Self-hosted: HashiCorp Vault — control mọi thứ, chạy trên Kubernetes hoặc VM.
- Lightweight: SOPS (Mozilla) — mã hóa file secrets trong Git, đơn giản cho team nhỏ.
Tại Sao Không Nên Hardcode Secrets?
1. Git history vẫn giữ lại
Một khi secrets nằm trong commit, xóa file không đủ. Git history vẫn giữ lại. Attacker chỉ cần clone repo là có toàn bộ credentials.
2. CI/CD có thể leak
Pipeline thường log output. Secrets trong env vars có thể bị log ra console, leak qua artifact, hoặc hiển thị trong error message.
3. Insider threat
Developer nào cũng có thể truy cập secrets trong code. Không có cơ chế audit ai đã dùng secret, khi nào và ở đâu.
4. Rotation cực kỳ khó
Khi muốn thay đổi API key, phải sửa code ở mọi nơi, test lại, deploy lại. Với secret manager, chỉ cần update ở một chỗ — mọi service tự động lấy version mới.
3 Công Cụ Quản Lý Secrets Phổ Biến
HashiCorp Vault — Full-Featured
Vault là standard de facto cho secret management trong DevOps. Nó mã hóa secrets ở rest, audit mọi request, hỗ trợ dynamic secrets (tạo credentials tạm thời cho từng service).
# Vault CLI — đọc secrets
vault kv get -field=password secret/myapp/database
# Dynamic secrets — Vault tạo MySQL credentials tạm thời
vault read database/creds/myapp-read
# → username: v-app-role-xyz123
# → password: A1b2-C3d4-E5f6
Dynamic secrets là điểm mạnh nhất. Vault tự tạo credentials mới mỗi khi service request. Khi service restart, credentials cũ tự hết hạn.
SOPS — Đơn Giản Cho Git
SOPS mã hóa giá trị trong YAML/JSON/ENV file bằng AWS KMS, GCP KMS, hoặc PGP. File vẫn commit vào Git — nhưng giá trị đã mã hóa.
# Mã hóa file
sops --encrypt --kms arn:aws:kms:... secrets.yaml > secrets.enc.yaml
# Giải mã khi cần
sops --decrypt secrets.enc.yaml
Ưu điểm: Git workflow giữ nguyên. Nhược điểm: không có dynamic secrets, không có audit log chi tiết.
External Secrets Operator — Kubernetes Native
External Secrets Operator (ESO) kết nối Vault hoặc cloud secret manager với Kubernetes. Developer viết ExternalSecret manifest, ESO tự động sync thành Kubernetes Secret.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: db-credentials
data:
- secretKey: password
remoteRef:
key: secret/myapp/db
property: password
Service chỉ đọc Kubernetes Secret bình thường. ESO xử lý phần sync và rotation phía sau.
Best Practices Cho Team
- Không bao giờ commit secrets — dùng
.gitignorehoặc SOPS encryption. - Audit log bật mọi nơi — biết ai đọc secrets, khi nào, từ đâu.
- Rotate định kỳ — thiết lập policy tự động thay đổi credentials mỗi 90 ngày.
- Least privilege — mỗi service chỉ được quyền đọc secrets nó cần.
- Dynamic secrets ưu tiên — thay vì static password, dùng Vault dynamic secrets để credentials tự hết hạn.
Bài viết được hỗ trợ bởi AI (Amy 🌸). Nội dung đã được kiểm duyệt bởi tác giả.