Ngôn ngữ hiển thị:
Năm ngoái mình audit một hệ thống của khách hàng, phát hiện ra họ đang lưu toàn bộ database password, API key của bên thứ ba, và thậm chí cả private key RSA trong... application.properties commit thẳng lên Git. Không phải họ không biết bảo mật — họ chỉ không có quy trình và công cụ đúng. AWS có đủ cả, và bộ ba KMS + Secrets Manager + Macie chính là câu trả lời.

Nhiều người nghĩ chỉ cần một trong ba là đủ. Thực ra chúng giải quyết ba bài toán khác nhau:
AWS KMS (Key Management Service) lo việc mã hóa — tức là biến dữ liệu thành ciphertext mà không có key thì không đọc được. KMS quản lý vòng đời của Customer Master Key (CMK), tự động rotate, và mọi thao tác decrypt đều qua API có audit log đầy đủ.
AWS Secrets Manager lo việc lưu trữ và phân phối credential an toàn — database password, API key, OAuth token. Thay vì hardcode trong code hay .env file, ứng dụng gọi API lấy secret lúc runtime. Secrets Manager còn tự động rotate password của RDS mà không cần downtime.
Amazon Macie lo việc phát hiện dữ liệu nhạy cảm đang bị lộ — scan S3 bucket tìm credit card number, SSN, PII, source code có hardcode credential. Cái này đặc biệt quan trọng vì nhiều team không biết mình đang rò rỉ dữ liệu ở đâu.
Khổ nỗi là nếu chỉ dùng Macie mà không có KMS, Macie tìm ra vấn đề nhưng bạn không có cơ chế mã hóa. Nếu chỉ dùng KMS mà không có Secrets Manager, key vẫn phải lưu đâu đó. Ba dịch vụ bổ sung cho nhau hoàn hảo.
Điểm mạnh của KMS là envelope encryption — KMS không mã hóa data trực tiếp (với data lớn), thay vào đó tạo ra Data Encryption Key (DEK), dùng DEK mã hóa data, rồi dùng CMK mã hóa DEK. Kết quả là DEK được mã hóa lưu cùng data — chỉ ai có quyền dùng CMK mới decrypt được DEK và đọc được data.
Tạo CMK và alias:
aws kms create-key \
--description "CMK cho production database encryption" \
--key-usage ENCRYPT_DECRYPT
aws kms create-alias \
--alias-name alias/prod-db-key \
--target-key-id YOUR_KEY_IDMã hóa dữ liệu nhỏ dưới 4KB trực tiếp qua Python:
import boto3, base64
kms = boto3.client("kms", region_name="ap-northeast-1")
response = kms.encrypt(
KeyId="alias/prod-db-key",
Plaintext=b"sensitive-data-here"
)
ciphertext = base64.b64encode(response["CiphertextBlob"]).decode()
# Decrypt
response = kms.decrypt(
CiphertextBlob=base64.b64decode(ciphertext)
)
plaintext = response["Plaintext"].decode()Với data lớn hơn, dùng GenerateDataKey để sinh DEK rồi mã hóa data với DEK đó. Lưu encrypted DEK cùng data, xóa plaintext DEK khỏi memory ngay sau khi dùng xong.
Nguyên tắc xương máu: KHÔNG bao giờ log CiphertextBlob hay plaintext DEK. Audit log của KMS đủ để trace ai đã decrypt gì — đừng tự tạo thêm điểm lộ lọt.
Key Policy là nơi nhiều người mắc lỗi nhất. Phải luôn có statement cho phép root account — nếu không, không ai có thể sửa Key Policy nữa và phải raise ticket AWS support để recover.
Trước khi có Secrets Manager, mình thấy mọi người giải quyết vấn đề credential theo nhiều cách không cái nào ổn: hardcode trong code (tệ nhất), lưu trong .env file rồi share qua Slack (vẫn tệ), lưu trong SSM Parameter Store plaintext (khá hơn nhưng không có auto-rotation).
Tạo secret cho RDS và chỉ định CMK tự tạo:
aws secretsmanager create-secret \
--name "prod/myapp/db-credentials" \
--description "RDS MySQL credentials cho production" \
--secret-string '{"username":"admin","password":"SecretPass!","host":"mydb.rds.amazonaws.com","port":3306,"dbname":"myappdb"}' \
--kms-key-id alias/prod-db-keyChú ý tham số --kms-key-id — mình luôn chỉ định CMK tự tạo thay vì dùng default key của AWS. Điều này cho phép kiểm soát chi tiết qua Key Policy.
Lấy secret trong ứng dụng Python lúc runtime:
import boto3, json
def get_db_credentials():
client = boto3.client("secretsmanager", region_name="ap-northeast-1")
response = client.get_secret_value(SecretId="prod/myapp/db-credentials")
return json.loads(response["SecretString"])
creds = get_db_credentials()
conn = mysql.connector.connect(
host=creds["host"],
user=creds["username"],
password=creds["password"],
database=creds["dbname"]
)
Tính năng mình dùng nhiều nhất là automatic rotation cho RDS — cứ 30 ngày Secrets Manager tự thay password mới, cập nhật vào RDS, và ứng dụng lấy password mới lần gọi tiếp theo. Zero downtime, zero manual work.
aws secretsmanager rotate-secret \
--secret-id "prod/myapp/db-credentials" \
--rotation-lambda-arn arn:aws:lambda:ap-northeast-1:123456789:function:SecretsManagerRDSMySQLRotationSingleUser \
--rotation-rules AutomaticallyAfterDays=30Mẹo: Dùng cache cho Secrets Manager client. AWS SDK hỗ trợ cache sẵn. Secret thay đổi 30 ngày một lần, cache 5 phút là hợp lý — tránh gọi API mỗi request vừa tốn cost vừa chậm.
Macie dùng ML để scan S3 bucket và phát hiện dữ liệu nhạy cảm. Enable Macie và tạo discovery job:
aws macie2 enable-macie
aws macie2 create-classification-job \
--job-type ONE_TIME \
--name "Initial-sensitive-data-discovery" \
--s3-job-definition '{"bucketDefinitions":[{"accountId":"123456789","buckets":["my-app-bucket","my-logs-bucket"]}]}'Macie phân loại findings theo severity: Critical, High, Medium, Low. Các loại dữ liệu Macie phát hiện được rất đa dạng: API key và private key (Credentials), credit card và bank account (Financial), thông tin y tế PHI, PII bao gồm email, phone, SSN, passport number.
Nghĩ mà xem — Macie scan cả nội dung file .py, .js, .java, .properties, .yaml. Nếu developer upload source code archive lên S3 mà trong đó có hardcode credential, Macie sẽ flag ngay. Đây là lý do mình luôn recommend enable Macie từ ngày đầu dự án.
Kết hợp Macie với EventBridge để tự động quarantine bucket khi phát hiện critical finding — Lambda nhận event, bật Block Public Access, revoke bucket policy, gửi alert Slack.
1. Dùng default KMS key cho Secrets Manager: Key aws/secretsmanager AWS tạo sẵn không customize Key Policy được. Luôn tạo CMK riêng.
2. Không enable CloudTrail: KMS tự log vào CloudTrail nhưng cần có trail active. Không có log thì không biết ai decrypt gì — vi phạm hầu hết compliance framework.
3. Cache secret quá lâu: Cache 24h nhưng rotation xảy ra sau 12h → ứng dụng dùng password cũ → connection fail. Recommended: cache 5-15 phút với stale-while-revalidate pattern.
4. Quên exclude Macie output bucket: Macie scan cả bucket chứa findings của chính nó, tạo ra vòng lặp findings. Exclude bucket output trong job configuration.
5. Key Policy không có root statement: Nếu Key Policy lock out root account, không ai sửa được Policy nữa. Phải raise ticket AWS support. Luôn test trong non-production trước.
Q: Secrets Manager vs SSM Parameter Store — khi nào dùng cái nào?A: Parameter Store rẻ hơn (SecureString miễn phí với standard tier) nhưng không có auto-rotation tích hợp và giới hạn 4KB. Secrets Manager đắt hơn (~0.4 USD/secret/tháng) nhưng có rotation tự động, versioning, cross-account sharing. Credential database, third-party service → Secrets Manager. Config không nhạy cảm, feature flag → Parameter Store.
Q: KMS Key Rotation có ảnh hưởng data đã mã hóa không?A: Không. AWS giữ lại key material cũ để decrypt data cũ, data mới được encrypt bằng key material mới. Bạn không cần re-encrypt data ngay — nhưng với data critical, re-encrypt thủ công là best practice để đảm bảo dùng key material mới nhất.
Q: Macie có scan được S3 bucket ở tất cả region không?A: Macie là regional service — mỗi region cần enable riêng. Nếu dùng multi-region, phải enable Macie và tạo job ở từng region. Có thể dùng AWS Organizations để enable Macie tập trung qua delegated administrator account.
Ba dịch vụ này không phức tạp để setup — cái khó là thay đổi thói quen của team. Khi xảy ra incident đầu tiên (credential lộ qua Git history, S3 bucket misconfiguration), chi phí giải quyết hậu quả tốn kém hơn nhiều so với chi phí setup đúng từ đầu.
Nếu bạn đang bắt đầu, thứ tự mình gợi ý: enable Macie để biết mình đang ở đâu → migrate credential vào Secrets Manager → enable KMS encryption cho S3 bucket và RDS → setup alerting tự động. Từng bước nhỏ, không cần làm tất cả trong một ngày. Nhưng đừng bỏ qua bước nào.