AWS KMS Key Policies vs Grants

Knowing these 7 differences could help you tighten your company’s security posture…and score higher on the “AWS Certified Security — Specialty” exam

Photo by Michael Dziedzic on Unsplash

1. A key can have multiple grants, but only one key policy

IAM Console help text for the `kms:PutKeyPolicy` action

2. You can lock yourself out with a mistaken key policy

{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Your AWS Account ID>:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}

3. Grants are better for programmatic permissions management

AWS console for IAM, permissions management options

4. Grants can be given a friendly name, like “foo.” The key policy is just the “key policy.”

aws kms create-grant \
--key-id d69a54b0-0250-467d-b7bd-f3a72f346c62 \
--grantee-principal arn:aws:iam::<Account ID>:user/yann_personal \
--operations Decrypt \
--name foo

5. Key policies allow you to specify the full range of KMS API actions. The range of actions you can specify in grants, however, is more limited.

aws kms create-grant \
--key-id d69a54b0-0250-467d-b7bd-f3a72f346c62 \
--grantee-principal yann_personal \
--operations "TagResource"
An error occurred (ValidationException) when calling the CreateGrant operation: 1 validation error detected: Value '[TagResource]' at 'operations' failed to satisfy constraint: Member must satisfy constraint: [Member must satisfy enum value set: [CreateGrant, GenerateDataKey, RetireGrant, Encrypt, ReEncryptTo, Decrypt, GenerateDataKeyWithoutPlaintext, DescribeKey, Verify, ReEncryptFrom, Sign]]
[CreateGrant, GenerateDataKey, RetireGrant, Encrypt, ReEncryptTo, Decrypt, GenerateDataKeyWithoutPlaintext, DescribeKey, Verify, ReEncryptFrom, Sign]
aws kms create-grant \
--key-id d69a54b0-0250-467d-b7bd-f3a72f346c62 \
--grantee-principal yann_personal \
--operations "Encrypt"
{
"GrantToken": "AQpAM2RhZTk1MGMyNTk2ZmZmMzEyYWVhOWViN2I1MWM4Mzc0MWFiYjc0ZDE1ODkyNGFlNTIzODZhMzgyZjBlNGY3NiKAAgEBAgB4Pa6VDCWW__MSrqnre1HIN0Grt00ViSSuUjhqOC8OT3YAAADXMIHUBgkqhkiG9w0BBwaggcYwgcMCAQAwgb0GCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM8AyPXJIfFCBpmRghAgEQgIGP48IGvk5g2TEKrCjAzcvY6rDOkGSkCHHGP0XDOqFNiubyOOvLa0WPE-sEKHvAKDLzBJPMGxLcKy3xFUM2JKp4-GnCfPGBejOJTGggykmPsRtSw29RilZA7xcG-KUGiYXf38fIpxAZPJPz6A9LJbPrpQtyFQNUpSrqCSzRmQ3zXw_xrcGUKuKVPOneGPV-tDEqIM_Q42hYwk_ALMqGbq4vkrHMk9gkb-EpmQ0cKHJdkAcW",
"GrantId": "cfd0e36858c24fc02cca866eae2f92b1cc93d8246fe129990d1c28725d900716"
}
{
"Sid": "Enable IAM User Permissions",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<Account ID>:root"
},
"Action": "kms:TagResource",
"Resource": "*"
}
AWS KMS console screenshot — tagging permissions denied

6. The key policy is in the console and in the API/CLI (programmatic). Grants are only programmatically accessible.

The console includes the key policy, not grants.

7. You can use grants to allow access to other AWS principles, but not deny. With the key policy, you can do both.

And what differences have you noticed?

Solutions Architect @Smartronix. 11x AWS, 6x Azure, and 1x in GCP, Docker & ITIL. Opinions expressed in this blog are my own. Find me on YouTube!