Advanced Access Control
Mechanisms Using AWS KMS

Swwapnil Pawar
The Security Chef

--

Fig.1 AWS KMS

AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to create and control the cryptographic keys that are used to protect your data.

AWS KMS uses hardware security modules (HSM) to protect and validate your AWS KMS keys under the FIPS 140–2 Cryptographic Module Validation Program. The HSMs that AWS KMS uses to protect KMS keys in China (Beijing) and China (Ningxia) Regions comply with all pertinent Chinese regulations, but are not validated under the FIPS 140–2 Cryptographic Module Validation Program.

AWS KMS integrates with most other AWS services that encrypt your data. AWS KMS also integrates with AWS CloudTrail to log use of your KMS keys for auditing, regulatory, and compliance needs.

By controlling access to your AWS KMS encryption key, you can control access to the data that you protected with that key irrespective of how you access that data. You can use the AWS KMS API to create and manage KMS keys and special features, such as custom key stores, and use KMS keys in cryptographic operations.

To access an AWS resource, you need resource permissions granted through the resource or IAM policy and access to the corresponding AWS KMS encryption key you used to secure your data.

AWS KMS encryption keys in AWS are resources as well. AWS governs access to the encryption keys through AWS KMS (resource), AWS KMS
grants, or IAM policies.

There are two different ways to control access to your data:

  1. AWS KMS key policy
  2. AWS KMS key grants

We are going to learn more about AWS KMS key grants.

A grant is a policy instrument that allows AWS principals to use KMS keys in cryptographic operations. It also can let them view a KMS key (DescribeKey) and create and manage grants.

grants are just another mechanism for providing permissions. It is an alternative to using key policies and can be specific. It is much easier to create and revoke a grant than to modify a key policy, so they are typically used for temporary key access or more fine-grained access. They can also be used to programmatically delegate the use of a CMK to specific principals.

When you create a grant for a KMS key, the grant allows the grantee principal to call the specified grant operations on the KMS key provided that all conditions specified in the grant are met.

  • Each grant allows access to exactly one KMS key. You can create a grant for a KMS key in a different AWS account.
  • A grant can allow access to a KMS key, but not deny access.
  • Each grant has one grantee principal. The grantee principal can represent one or more identities in the same AWS account as the KMS key or in a different account.
  • A grant can only allow grant operations. The grant operations must be supported by the KMS key in the grant. If you specify an unsupported operation, the CreateGrant request fails with a ValidationError exception.
  • The grantee principal can use the permissions that the grant gives them without specifying the grant, just as they would if the permissions came from a key policy or IAM policy. However, when you create, retire, or revoke a grant, there might be a brief delay, usually less than five minutes, until the operation achieves eventual consistency. To use the permissions in a grant immediately, use a grant token.
  • An authorized principal can delete the grant (retire or revoke it). Deleting a grant eliminates all permissions that the grant allowed.
  • AWS KMS limits the number of grants on each KMS key. For details, see Grants per KMS key: 50,000.

Both, the AWS KMS grants and AWS KMS key policies are eventually consistent. When using AWS KMS grants, you have an option to provide a token for a strongly consistent authorization check.

This example below creates a grant that allows Bob, an IAM user in the
account, to call the GenerateDataKey operation on the CMK identified by the KeyId parameter:

Fig.2. KMS Grants

After you created a grant, To view the grant, use the ListGrants operation. You must specify the KMS key to which the grants apply. You can also filter the grant list by grant ID or grantee principal.

To view all grants in the AWS account and Region with a particular retiring principal, use ListRetirableGrants. The responses include details about each grant.

For example, the following command lists all of the grants for a KMS key.

$  aws kms list-grants --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
{
"Grants": [
{
"KeyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
"CreationDate": 1572216195.0,
"GrantId": "abcde1237f76e4ba7987489ac329fbfba6ad343d6f7075dbd1ef191f0120514a",
"Constraints": {
"EncryptionContextSubset": {
"Department": "IT"
}
},
"RetiringPrincipal": "arn:aws:iam::111122223333:role/adminRole",
"Name": "",
"IssuingAccount": "arn:aws:iam::111122223333:root",
"GranteePrincipal": "arn:aws:iam::111122223333:user/exampleUser",
"Operations": [
"Decrypt"
]
}
]
}

Best practices for AWS KMS grants

  • Limit the permissions in the grant to those that the grantee principal requires. Use the principle of least privileged access.
  • Use a specific grantee principal, such as an IAM role, and give the grantee principal permission to use only the API operations that they require.

Below is a specific example that grants AWS account #5651496432510 permission to call the GenerateDataKey and Decrypt APIs, but only if the supplied encryption context for customerID is 3369.

{
"GranteePrincipal": "5651496432510",
"Operations": [
"GenerateDataKey",
"Decrypt"
],
"Constraints": {
"EncryptionContextSubset": {
"customerID": "3369"
}
}
}

This grant could prevent your application from decrypting data belonging to customer “3369” without explicitly passing the expected customerID in the request to AWS KMS. This may be a useful defense-in-depth mechanism to prevent unauthorized access to your customers’ data if your application’s AWS credentials were compromised and used from a different caller who doesn’t know that encryption context is a required parameter for all reads and writes in order to encrypt and decrypt data.

  • Use the encryption context grant constraints to ensure that callers are using the KMS key for the intended purpose.
  • Delete duplicate grants. Duplicate grants have the same key ARN, API actions, grantee principal, encryption context, and name. If you retire or revoke the original grant but leave the duplicates, the leftover duplicate grants constitute unintended escalations of privilege. To avoid duplicating grants when retrying a CreateGrant request, use the Name parameter. To detect duplicate grants, use the ListGrants operation. If you accidentally create a duplicate grant, retire or revoke it as soon as possible.

References:

--

--

Swwapnil Pawar
The Security Chef

Entrepreneur, Cloud Evangelist, AWS/Google Certified Architect, Building Cool Things With Serverless. Avid Reader