Why choose Panoptica?
Four reasons you need the industry’s leading cloud-native security solution.
AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to create and control the cryptographic keys used to protect your data. This service easily integrates with other AWS services, such as Secrets Manager, RDS, and S3 (the full list can be found here), to facilitate the encryption of your data. For auditing purposes, you can use AWS CloudTrail to log all API calls made on your keys. If you use AWS cloud services, you most certainly will encounter an option to set encryption for an S3 bucket or an EC2 volume. This encryption is done with KMS.
The primary resource of AWS KMS is the keys. They are used for encryption, decryption, and re-encryption of data. A KMS key is a logical representation of a cryptographic key. It contains metadata, such as the key ID, key spec, key usage, creation date, description, key state, and a reference to the key material that is used when you run cryptographic operations. By default, key material is generated by AWS, but it can also be imported (more information on importing key material).
There are three types of keys - customer managed keys, AWS managed keys, and AWS owned keys.
Below is a table that sums up the main differences between the three:
Customer managed keys are KMS keys that you create, own, and manage. You are responsible for every aspect - access, status, rotation, and more. You can use your customer managed key for cryptographic operations such as encrypt, decrypt, sign, and verify. All KMS operations (from kms:DescribeKey to kms:Decrypt) can be audited in AWS CloudTrail logs. In addition, many AWS services that integrate with AWS KMS let you specify a customer managed key to protect the data stored and managed for you. For instance, when you want to enable default encryption for an S3 bucket, you can choose to use one of your customer managed keys.
Below is a CLI command that describes a customer managed KMS key. The “KeyManager” field value is set to “CUSTOMER”.
aws kms describe-key --key-id KEY-ID --region REGION
AWS managed keys are KMS keys in your account created, managed, and used on your behalf by another AWS service (their alias is aws/service-name). If we look again at the S3 example above, we can see that there is an option to choose the KMS key aws/s3; this is an AWS managed key for this service.
You can view the AWS managed keys in your account, check their key policies, and audit their use in AWS CloudTrail logs. However, you cannot manage these KMS keys, rotate them, or change their key policies. You also cannot use AWS managed keys in cryptographic operations directly; the service that creates them uses them on your behalf. All AWS managed keys are automatically rotated every year, that cannot be changed (Rotating Keys).
Below is a CLI command that describes an AWS managed KMS key. The “KeyManager” field value is set to “AWS”.
aws kms describe-key --key-id KEY-ID --region REGION
AWS owned keys are a collection of KMS keys that an AWS service owns and manages for use in multiple AWS accounts. Although AWS owned keys are not in your AWS account, an AWS service can use the associated AWS owned keys to protect the resources in your account. For enabling default encryption of a bucket, you can choose to use an AWS owned key:
You do not need to create or manage the AWS owned keys. You also cannot view, use, track, or audit them. We cannot get any information about an AWS owned key; therefore, we cannot use the describe-key command on them.
For this discussion, we will set aside the AWS owned keys, as we do not have any control over them.
So, should you go with customer managed or AWS managed keys? It depends. From a security perspective, neither one is better than the other. You can decide based on your needs. An AWS managed key can only be used to protect resources within the specific AWS service for which it is created, and there are less access control mechanisms that can be used (less room for human error and misconfigurations). On the other hand, customer managed keys give you more control over access and management. Moreover, if you need to import your own key material, customer managed keys are your only option.
Below is another chart to help you decide between the two:
To have any sort of access to KMS keys, from creating and viewing, to using keys in cryptographic operations, one must have valid AWS credentials for authentication. In terms of authorization, like all other AWS services and resources, there are no principals that have implicit KMS permissions. Permissions need to be actively provided. There are three access control mechanisms for managing access to AWS KMS resources – key policies, IAM (Identity Access Management) policies, and grants. For a principal to have access to a KMS key there must be an explicit allow in at least one of key policy, IAM policy or grants, and no deny in all of them (grants cannot deny access, so a deny statement can only appear in the key policy or in an IAM policy).
A key policy is a resource-based policy, and it is the primary way to control access to KMS keys. Each KMS key must have exactly one key policy. Resource-based policies determine who can perform certain actions on the resource to which they are attached. In this case, who is able to use the KMS key and what they can do with it. As mentioned, access to KMS keys can also be controlled using IAM policies. However, if the key policy (or a grant, as will be discussed further in the next sections) does not allow the use of IAM policies they will have no effect (unless they deny permissions).
When creating a new KMS key, you can specify a key policy. If you do not, AWS will use a key policy of their own – the default key policy. It is important to know that AWS's default key policy is not necessarily the same when you create a key using the console and using the KMS API. When you use the KMS API (CLI for instance) to create a KMS key, the default key policy will contain one statement that gives the AWS account that owns the KMS key permission to use IAM policies to allow access to all AWS KMS operations on the KMS key.
Below is a CLI command that creates a new customer managed KMS key with a default key policy.
aws kms create-key --region REGION
Checking the key policy:
aws kms get-key-policy --key-id KEY-ID --policy-name default --region REGION --output text | jq '.'
This key policy only contains one statement that allows the use of IAM policies to control access to the key.
When you use the console, the default key policy begins with the statement that enables the use of IAM permissions (statement number 1 in the picture below). It then adds more statements depending on the creation process. During the creation, you can specify users, roles, and accounts that will have administrating or using (or both) permissions. Administrating permissions refers to permissions to manage the KMS key (such as kms:EnableKey, kms:CreateGrant, and kms:EnableKeyRotation). Using permissions refers to permissions to use the KMS key in cryptographic operations (such as kms:Encrypt, and kms:Decrypt). Based on that, two policy statements will be added – one for the key administrators (statement number 2 in the picture below), and one for the key users (statement number 3 in the picture below). The last statement (statement number 4 in the picture below) that appears in the default key policy, allows principals to use the key with other AWS services. This statement allows the key user to create, view, and revoke grants on the KMS key, but only when the grant operation request comes from an AWS service.
Console key policy:
Grants are another KMS access control mechanism. A grant allows the grantee principals to call the specified grant operations on the KMS key, provided that all conditions specified in the grant are met. They are often used for temporary permissions because you can create a grant, use its permissions, and delete it without changing your key policy or IAM policies. Grants are commonly used by AWS services that integrate with AWS KMS to encrypt your data at rest. The service creates a grant on behalf of a user in the account, uses its permissions, and retires (deletes in grant terminology) the grant as soon as its task is completed.
Each grant allows access to a specific KMS key and can only allow access but not deny it. Access can be given to principals in the same AWS account or in another one. The use of grants does not require special action from the grantee; the grantee can use the permissions the same way they would use them if they came from a key policy or an IAM policy (the grant might not be effective immediately and for that, you might want to use a grant token). Deletion and creation of a grant can be done by authorized principals. The permission to create a grant is a powerful one, much like kms:PutKeyPolicy.
Principals that get the kms:CreateGrant permission from a key policy or from an IAM policy, can create grants for any grant operation on the KMS key, even if they do not have the permissions themselves. Distinctively, principals that get the kms:CreateGrant permission from a grant can only delegate the permissions that they were granted, even if they have other permissions from a key policy or an IAM policy (for more information, check Granting CreateGrant permission).
IAM policies can be used to control access to KMS keys. One of the following must exist:
The use of IAM policies is like all other AWS resources. You create a policy with KMS permissions and attach it to a user, group, or role.
Here is a link to all available KMS permissions - https://docs.aws.amazon.com/kms/latest/developerguide/kms-api-permissions-reference.html.
AWS KMS evaluates the following to authorize access:
To authorize access, AWS KMS takes all four and evaluates whether to allow or deny the request. Below is a flowchart from AWS’s documentation that describes the policy evaluation process:
To wrap up, we wanted to provide you with some security tips and best practices (this can also be helpful - kms-cheat-sheet)