Tuần trước, team mình deploy một Lambda xử lý payment data. Security review hỏi: key encryption ở đâu, ai có quyền decrypt? Cả team im lặng. Mọi service AWS dùng KMS: S3 encryption, RDS, Secrets Manager, Lambda env vars, DynamoDB. KMS là nền tảng — hiểu nó để kiểm soát ai decrypt được data.
| Key Type | Quản lý | Key Policy | Rotation | Cost |
|---|---|---|---|---|
| AWS-managed | AWS | AWS-set | Auto 1 năm | Free |
| Customer-managed (CMK) | Bạn | Bạn viết | Optional 1 năm | $1/key/tháng |
aws kms create-key --description "MyApp encryption key" --key-usage ENCRYPT_DECRYPT
aws kms create-alias --alias-name alias/myapp-key --target-key-id xxx
aws kms enable-key-rotation --key-id alias/myapp-key
Envelope Encryption
const { Plaintext, CiphertextBlob } = await kms.send(
new GenerateDataKeyCommand({
KeyId: "alias/myapp-key",
KeySpec: "AES_256",
})
);
// Dùng Plaintext encrypt data → lưu CiphertextBlob cùng encrypted data
// Khi cần decrypt: decrypt CiphertextBlob → lấy Plaintext → decrypt data
Lưu CiphertextBlob (data key đã mã hoá) kèm encrypted data, không lưu Plaintext. Khi decrypt, gửi CiphertextBlob cho KMS decrypt lấy Plaintext, rồi dùng Plaintext decrypt data. Không bao giờ lưu Plaintext xuống disk.
Key Policy ≠ IAM Policy
Key policy là gatekeeper — nếu key policy không allow, IAM policy có kms:* cũng vô ích. Key policy mandatory: ít nhất phải allow account root hoặc user/role cụ thể.
Mình từng gặp case key policy sai, IAM có kms:* nhưng vẫn access denied — mất 2 ngày mới nhận ra key policy block hết.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/lambda-execution-role"
},
"Action": "kms:Decrypt",
"Resource": "*"
}
]
}
Key policy default chỉ allow root. Nếu muốn IAM role Lambda được decrypt, phải add Principal vào key policy.
Bài sau: Phần 36: ElastiCache — Redis managed