This chapter covers AWS KMS key policies and grants, two mechanisms to control access to customer master keys (CMKs). Key policies are resource-based policies that define who can use and manage a CMK, while grants are a more flexible, temporary delegation mechanism. For the SAA-C03 exam, understanding the differences, use cases, and limitations of key policies versus grants is critical, as questions on KMS access control appear frequently (approximately 5-10% of the exam). Mastering this topic ensures you can design secure architectures that comply with the principle of least privilege.
Jump to a section
Think of an AWS KMS customer master key (CMK) as a bank vault containing a secure box. The vault has a strict access policy: only specific people on a list (the key policy) can open it. The bank manager (the AWS account root user) can add or remove names from that list. Now, suppose you need to let a trusted courier (an AWS service like Lambda) access the box once to deliver documents, but you don’t want to add the courier to the permanent list because that would give them ongoing access. The bank allows a mechanism called a “grant”: you, as an authorized person, can issue a temporary ticket that says “this courier may open the vault exactly once between 2 PM and 3 PM, and only to retrieve Document X, not to view the key.” The courier presents the ticket to the bank guard (KMS), who checks the ticket against the vault’s policy (which must allow you to issue grants). If valid, the guard opens the vault for the courier without modifying the permanent access list. The grant can be retired at any time, and it never alters the base policy. This is exactly how KMS grants work: they allow delegated, temporary, and fine-grained access to a CMK without changing the key policy, useful for cross-account access or temporary operations.
What Are KMS Key Policies?
AWS Key Management Service (KMS) uses key policies as the primary way to control access to customer master keys (CMKs). A key policy is a JSON document attached to a CMK that defines which principals (users, roles, AWS services) can perform which actions on the key. Every CMK must have exactly one key policy. The key policy, combined with IAM policies, determines the effective permissions. If the key policy explicitly denies access, no IAM policy can override it.
Why Key Policies Exist
Key policies exist because CMKs are resources that need independent access control separate from IAM. This allows cross-account access and ensures that even if an IAM policy grants broad permissions, the key itself can restrict usage. For example, you can allow an IAM role in another account to use a CMK by adding a statement in the key policy that grants the external role access. Without key policies, you would need to rely solely on IAM policies, which cannot grant access to principals outside your account.
Key Components of a Key Policy
A key policy contains the following elements:
- Version: Always 2012-10-17 (the policy language version).
- Id: Optional identifier.
- Statement: One or more statements, each with:
- Sid: Optional statement ID.
- Effect: Allow or Deny.
- Principal: The entity to which the policy applies. Can be an AWS account, IAM user, IAM role, or AWS service. For cross-account access, use the ARN of the external principal.
- Action: KMS API actions like kms:Encrypt, kms:Decrypt, kms:CreateGrant, etc.
- Resource: Always * because the policy is attached to the CMK.
- Condition: Optional conditions (e.g., IP address, MFA, encryption context).
Default Key Policy
When you create a CMK using the AWS Management Console, KMS applies a default key policy. This policy gives the AWS account root user full access to the CMK and grants IAM users and roles in the account access if they have an IAM policy that allows KMS actions. The default policy looks like this:
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}This policy allows the root user to delegate permissions via IAM. Without this statement, IAM policies alone cannot grant access to the CMK.
How KMS Evaluates Access
KMS evaluates access by combining the key policy and any applicable IAM policies. The evaluation logic is:
If the key policy explicitly denies access (Effect: Deny), the request is denied regardless of IAM.
If the key policy allows access and the principal has an IAM policy that allows the action, access is granted.
If the key policy does not mention the principal, IAM policies are not considered (unless the default policy is used).
For cross-account access, the key policy must explicitly grant access to the external principal. The external account's IAM policy must also allow the action. Both policies must allow; this is a two-way permission.
What Are KMS Grants?
A grant is an alternative way to grant access to a CMK. It is a temporary, fine-grained permission that can be created and retired without modifying the key policy. Grants are often used to delegate access to AWS services (like Lambda, S3, or DynamoDB) or to allow cross-account access for specific operations.
How Grants Work
When you create a grant, you specify:
Grantee principal: The entity that gets the permissions.
Operations: The list of KMS operations allowed (e.g., Encrypt, Decrypt, GenerateDataKey).
Constraints: Optional restrictions such as encryption context or a retiring principal.
Name: Optional friendly name.
Grants are created using the CreateGrant API. The grant is valid until it is retired or revoked. To create a grant, the caller must have kms:CreateGrant permission on the CMK, and the key policy must allow it (either via the default policy or an explicit statement).
Grant vs. Key Policy
Granularity: Grants can restrict operations to specific encryption contexts, while key policies cannot (except via conditions).
Temporary: Grants can be retired, whereas key policy changes require updating the policy document.
Cross-account: Both can be used for cross-account access, but grants are easier for temporary access.
Delegation: Grants allow the grantee to create further grants (if RetireGrant permission is given), but key policies do not delegate policy creation.
Creating a Grant
Example using AWS CLI:
aws kms create-grant \
--key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
--grantee-principal arn:aws:iam::123456789012:role/MyRole \
--operations Encrypt Decrypt \
--constraints EncryptionContextSubset={Department=Finance}This creates a grant allowing the role to encrypt and decrypt only when the encryption context includes Department=Finance.
Retiring a Grant
To retire a grant, use:
aws kms retire-grant \
--grant-token <token> \
--key-id 1234abcd-12ab-34cd-56ef-1234567890abOr the grantee can retire it if they have RetireGrant permission.
Revoking a Grant
Only the key owner can revoke a grant:
aws kms revoke-grant \
--key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
--grant-id <id>Interaction with IAM and Key Policies
Grants are an additional layer. Even if a grant allows an action, the grantee must have an IAM policy that allows the KMS action (unless the key policy explicitly allows the grantee principal without requiring IAM). However, for cross-account grants, the grantee principal in the external account must have an IAM policy allowing the action; the key policy must allow the external account to create grants (or allow the grantee principal via the key policy).
Use Cases
AWS Services: S3 uses grants to allow KMS keys for SSE-KMS. DynamoDB uses grants for encryption at rest.
Cross-account temporary access: Grant a role in another account access to decrypt data for a limited time.
Delegated administration: Allow a security tool to rotate keys by granting kms:ScheduleKeyDeletion temporarily.
Best Practices
Use key policies for permanent, broad access (e.g., allow the account root).
Use grants for temporary, fine-grained access.
Regularly review and retire unused grants.
Never grant kms:* in a grant; specify only needed operations.
Use encryption context constraints to limit grant usage.
Limitations
Grants cannot be used to allow kms:CreateKey or kms:PutKeyPolicy.
A grant cannot be modified after creation; you must revoke and recreate.
There is a limit of 10,000 grants per CMK (soft limit, can be increased).
Grants are not supported for asymmetric CMKs (as of 2023).
Grants do not support conditions beyond encryption context (e.g., IP address).
Monitoring Grants
Use AWS CloudTrail to log CreateGrant and RetireGrant events. Use ListGrants API to view active grants:
aws kms list-grants --key-id 1234abcd-12ab-34cd-56ef-1234567890abSummary of Differences
| Feature | Key Policy | Grant | |---------|------------|-------| | Persistence | Permanent until edited | Temporary, can be retired | | Granularity | Actions, principals, conditions | Actions, principals, encryption context constraints | | Cross-account | Yes | Yes | | Delegation | No | Yes (can delegate to create grants) | | Modification | Edit policy JSON | Revoke and recreate | | Use case | Permanent access control | Temporary, fine-grained delegation |
Identify the CMK and Access Needs
First, determine which CMK you need to control access to. Consider whether the access is for users within your account, cross-account, or for an AWS service. Decide if the access is permanent (use key policy) or temporary (use grant). For example, if you need to allow an external auditor to decrypt data once a month, a grant is appropriate. If you need to allow all developers in your account to encrypt with a key, a key policy with IAM delegation is better.
Write or Modify the Key Policy
If using a key policy, craft a JSON policy document. For intra-account access, the default policy that delegates to IAM is often sufficient. For cross-account access, add a statement with the external principal ARN. Ensure the policy includes the necessary actions (e.g., kms:Encrypt, kms:Decrypt) and any conditions. Use the AWS Management Console, CLI, or SDK to attach the policy to the CMK. The key policy is evaluated immediately; any changes take effect within minutes.
Create an IAM Policy for the Principal
If using the default key policy, the principal (IAM user/role) must have an IAM policy that allows the KMS actions. For example, an IAM policy allowing kms:Decrypt on the specific CMK ARN. Without this IAM policy, the key policy alone does not grant access (except for the root user). For cross-account access, the external account must also have an IAM policy allowing the actions, and the key policy must explicitly allow the external principal.
Create a Grant if Temporary Access Needed
If a grant is more suitable, call the CreateGrant API. Specify the key ID, grantee principal ARN, list of operations, and optional encryption context constraints. The caller must have kms:CreateGrant permission on the CMK. The grant is created immediately and the grantee can start using it. The grant is not visible in the key policy; it is stored separately. Use the grant token or grant ID to retire or revoke later.
Monitor and Audit Access
After setting up access, monitor usage via CloudTrail logs. For key policies, any policy changes are logged. For grants, CreateGrant, RetireGrant, and RevokeGrant events are logged. Use ListGrants to review active grants. Regularly audit to ensure no excessive permissions. For sensitive keys, consider using key rotation and automatic grant retirement using AWS Config rules.
Enterprise Scenario 1: Cross-Account Data Sharing
A large enterprise has separate AWS accounts for development, staging, and production. The production account stores sensitive customer data encrypted with a CMK. The analytics team in the staging account needs to decrypt this data for reporting once a month. The security team wants to avoid giving permanent cross-account access. They create a grant in the production account's CMK that allows a specific IAM role in the staging account to perform kms:Decrypt, with an encryption context constraint that limits the operation to a specific dataset. The grant is retired after the monthly report is generated. This ensures least privilege and temporary access. A common mistake is to instead modify the key policy to allow the staging account's root, which would give permanent access to all roles in that account. The grant approach avoids this.
Enterprise Scenario 2: Delegating Key Rotation to a Security Tool
A company uses a third-party security tool that requires permission to rotate CMKs. The tool runs as an IAM role in the same account. The security team wants to allow only the rotation operation (kms:ScheduleKeyDeletion, kms:CancelKeyDeletion, kms:EnableKey, kms:DisableKey) but not encrypt/decrypt. They create a grant that allows these specific operations to the tool's role. The key policy remains restrictive, allowing only the security team to manage the key policy itself. This prevents the tool from accessing data but allows it to manage key lifecycle. Without grants, the security team would have to update the key policy, which is riskier and less granular.
Performance and Scale Considerations
Grants are stored in KMS and count towards service limits. Each CMK can have up to 10,000 grants (default limit). Creating many grants can impact performance slightly due to internal storage, but for most use cases this is negligible. For high-frequency operations, using a key policy with IAM is more efficient because grants require an additional lookup. In production, it is common to use key policies for broad access and grants for narrow, temporary needs. Misconfiguration often occurs when administrators forget to retire grants, leading to lingering access. Automated scripts should be used to retire grants after a defined period.
What SAA-C03 Tests
The exam focuses on understanding when to use key policies versus grants, and how they interact with IAM. Key objective codes: Domain 2 (Secure Architectures), Objective 2.1 (Design secure access to AWS resources). Specific topics include:
Cross-account access: You must know that both the key policy and the external account's IAM policy must allow the action. A common question asks: "An IAM role in Account B needs to decrypt data encrypted with a CMK in Account A. What must be configured?" Answer: The key policy in Account A must allow the role, and the role's IAM policy must allow kms:Decrypt.
Default key policy: The exam tests that the default key policy allows the root user and delegates to IAM. A question might ask: "Why can an IAM user with kms:* in their IAM policy still not access a CMK?" Answer: The key policy must include the statement that enables IAM user permissions.
Grant constraints: The exam likes to test encryption context constraints. For example: "A grant allows Decrypt only when the encryption context includes 'Project=Alpha'. What happens if the encryption context is missing?" Answer: The decryption fails.
Common wrong answers: Candidates often confuse grants with key policies. A typical wrong answer is: "Create an IAM policy for the external account." But that alone doesn't work; the key policy must also allow. Another wrong answer: "Modify the key policy to allow the external account root." This is too permissive; using a grant or specific role is better.
Edge cases: The exam may test that grants cannot be used for asymmetric CMKs. Also, that grants cannot grant permission to create or delete keys. Another edge case: If a key policy explicitly denies access, a grant cannot override it.
Numbers and terms: Remember the default limit of 10,000 grants per CMK. Know the API actions: CreateGrant, RetireGrant, RevokeGrant, ListGrants. The encryption context constraint is EncryptionContextSubset or EncryptionContextEquals.
How to Eliminate Wrong Answers
If a question involves cross-account access, check if the answer mentions both a key policy and an IAM policy. If only one is mentioned, it's likely wrong. If the question involves temporary access, look for "grant" in the answer. If the question involves permanent access, look for "key policy". Also, remember that grants support encryption context constraints; if the question requires filtering by encryption context, grants are the answer.
Every CMK must have exactly one key policy, which is the primary access control mechanism.
The default key policy allows the root user and delegates to IAM; without it, IAM policies alone cannot grant access.
For cross-account access, the key policy must explicitly allow the external principal, and the external account's IAM policy must also allow the action.
Grants are used for temporary, fine-grained access and support encryption context constraints.
Grants cannot be used for asymmetric CMKs or for key management actions.
A grant can be retired by the grantee (if allowed) or revoked by the key owner at any time.
The default limit is 10,000 grants per CMK.
Use grants for AWS service integrations (e.g., S3 SSE-KMS) and temporary cross-account access.
These come up on the exam all the time. Here's how to tell them apart.
Key Policy
Resource-based policy attached to the CMK.
Permanent until explicitly modified.
Supports all condition keys (IP, MFA, etc.).
Can allow any KMS action, including key management.
Changes require updating the policy document.
Grant
Separate permission object, not part of the key policy.
Temporary; can be retired or revoked.
Only supports encryption context constraints.
Cannot allow key management actions (e.g., CreateKey).
Created and retired via API; no policy editing needed.
Mistake
Key policies and IAM policies are interchangeable; you can use either to grant access to a CMK.
Correct
Key policies are resource-based and are always evaluated. IAM policies alone cannot grant access to a CMK unless the key policy explicitly allows it (e.g., via the default policy). For cross-account access, the key policy must explicitly allow the external principal.
Mistake
Grants are a type of key policy statement.
Correct
Grants are separate from key policies. They are stored independently and do not appear in the key policy JSON. They are created via the CreateGrant API and can be retired without modifying the key policy.
Mistake
A grant can be used to allow any KMS action, including creating and deleting keys.
Correct
Grants cannot allow kms:CreateKey, kms:PutKeyPolicy, kms:ScheduleKeyDeletion, or kms:CancelKeyDeletion. These actions require key policy or IAM permissions.
Mistake
Once a grant is created, it cannot be revoked; only the grantee can retire it.
Correct
The key owner can revoke a grant at any time using RevokeGrant. The grantee can also retire the grant if they have the RetireGrant permission, but revocation is always possible by the owner.
Mistake
Grants support all condition keys that key policies support.
Correct
Grants only support encryption context constraints (EncryptionContextSubset and EncryptionContextEquals). They do not support other condition keys like IP address or MFA.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
A key policy is a resource-based policy attached directly to a CMK. It defines who can access the key and what actions they can perform. An IAM policy is attached to an IAM user, group, or role and defines what AWS resources they can access. For KMS, both may be required: the key policy must allow the principal, and the IAM policy must allow the KMS action. The key policy is always evaluated; IAM policies are only considered if the key policy allows it (e.g., via the default policy statement).
Yes, grants can be used for cross-account access. The grantee principal must be an IAM role or user in the external account. However, the grantee must also have an IAM policy that allows the KMS actions. Additionally, the key policy must allow the external account to create grants (or allow the grantee principal directly). Grants are often easier for temporary cross-account access than modifying key policies.
Use the `EncryptionContextSubset` or `EncryptionContextEquals` constraint when creating the grant. For example, `EncryptionContextSubset={Department=Finance}` ensures that the grantee can only decrypt if the encryption context contains the key-value pair `Department=Finance`. The grantee's request must include that encryption context; otherwise, KMS denies the operation.
If a grant is retired or revoked while an operation is in progress, the operation may fail if it is still pending. For operations that have already started, they may complete depending on the timing. It is best to avoid retiring grants in use. Use CloudTrail to monitor grant usage before retiring.
No, grants are immutable after creation. To change the permissions, you must revoke the existing grant and create a new one with the desired parameters. This is by design to ensure that grants are temporary and cannot be altered without explicit action.
Grants are supported for symmetric CMKs only. As of 2023, asymmetric CMKs (RSA or ECC) do not support grants. For asymmetric keys, you must use key policies and IAM policies for access control.
Use the `ListGrants` API or the AWS CLI command: `aws kms list-grants --key-id <key-id>`. This returns a list of grants with their details, including grantee principal, operations, and constraints. You can also use the AWS Management Console under the KMS key's details page.
You've just covered KMS Key Policies and Grants — now see how well it sticks with free SAA-C03 practice questions. Full explanations included, no account needed.
Done with this chapter?