KMS Grants

There is one slide in the “Security Engineering on AWS” course which describes KMS Key Policies and Grants

The corresponding text is as follows:

In addition to using AWS IAM to protect key usage, AWS KMS provides two other security mechanisms for protecting your keys: key policies and grants. In order to define resource-based permissions, you need to attach policies to the keys. The policies let you specify who has permission to use the key and what actions they can perform. A key policy specifies who can manage a key and which user or role can encrypt or decrypt with the key. Typically, most users set key policies by using the Encryption Keys section of the IAM console. Either way, key policies share a common syntax with the IAM policy specification.

With grants you can programmatically delegate the use of KMS customer master keys (CMKs) to other AWS principals. You can use them to allow access, but not deny it. Grants are typically used to provide temporary permissions or more granular permissions. You can also use key policies to allow other principals to access a CMK, but key policies work best for relatively static permission assignments. Also, key policies use the standard permissions model for AWS policies in which users either have or do not have permission to perform an action with a resource.

Grants can be revoked (canceled) by any user who has the kms:RevokeGrant permission on the CMK

It may be a challenge to understand the difference between Key Policies and Grants. The text says that “key policies work best for relatively static permission assignments”. A grant does not expire automatically either, but can be revoked. Say you have a workflow where a component is granted access to a key, uses it, and then the access needs to be revoked. This could be achieved by changing the policy but such a frequent change could by mistake affect other users and roles.

Working with Grants uses CLI/SDK and not the console.

The following test assumes some knowledge of creating KMS keys using the console, and some knowledge of using the AWS CLI. A pre-requisite is that you have the AWS CLI installed and access keys configured. I am using an admin user with the AWS managed policy AdministratorAccess.

Using console or CLI, create a KMS CMK. I chose the administrator and user of the key to be my admin user.

Using console or CLI, create a test user with programmatic access but no permissions. I used the name “granttestuser”

Use aws configure to set up a profile for the test user. If you havn’t done this before, the command is:

aws configure –profile granttestuser.

Try to encrypt a file using the profile of the test user. I have a file “hello”for the test.

aws kms encrypt --plaintext "hello" --key-id <key_arn> --profile granttestuser

This will result in an error

An error occurred (AccessDeniedException) when calling the Encrypt operation: User: arn:aws:iam::xxxxxxxxxx:user/granttestuser is not authorized to perform: kms:Encrypt on resource: arn:aws:kms:eu-west-1:xxxxxxxxxx:key/xxxxxxxxx…

Create a grant of the user, with permissions to use the key for encryption.

aws kms create-grant --key-id <key_arn> --grantee-principal <granttestuser's_arn> --operations "Encrypt"

The command returns a grant token and grant id.
“GrantToken”: “AQpAMWIyNTQ4MjBi… <output omitted>,
“GrantId”: “c1b42687c23cf408a… <output omitted>”

The user supplies the grant token as an argument to the encrypt command

aws kms encrypt --plaintext "hello" --key-id <key_arn> --grant-tokens <grant_token_from_previous_command> --profile granttestuser

It should now work.

The grants can be listed:

aws kms list-grants --key-id <key_arn>

And revoked:

aws kms revoke-grant --key-id <key_arn> --grant-id <grant_id>