Introduction
Managing encryption in a multi-account setup is a common challenge for organizations operating on AWS. AWS Key Management Service (KMS) provides powerful tools for encryption, including the ability to define and control access to keys. One key feature that simplifies key management and improves scalability is the use of key aliases. In this post, we’ll explore how to configure IAM roles for cross-account access to KMS keys using aliases, discuss the benefits and limitations of this approach.
Purpose of the Solution
The goal is to enable secure cross-account access to KMS keys in a way that is maintainable, scalable, and aligned with AWS security best practices. By using key aliases instead of key IDs, the solution simplifies key lifecycle management and improves operational efficiency. This approach also ensures that organizations can benefit from features like key rotation without disrupting dependent applications or workflows.
Why Key Aliases?
Aliases act as friendly, human-readable references to KMS keys. Instead of hardcoding key IDs in policies or applications, aliases provide an abstraction layer that decouples resource identifiers from their usage. This is especially useful in cross-account setups where key rotation and account separation add complexity.
Benefits of Using Key Aliases
Maintainability: Key aliases eliminate the need to reference complex key IDs in policies or applications. If a key is rotated or replaced, the alias ensures continuity without requiring changes in downstream configurations.
Readability: Aliases provide clear context in IAM policies and documentation. For example, using alias/production-data-key
is far more descriptive than referencing a key ID like 1234abcd-12ab-34cd-56ef-1234567890ab
.
Scalability: In environments with multiple accounts or teams, aliases simplify collaboration and resource management by abstracting the complexity of key management.
The problem
Initially, I attempted to use the alias ARN directly, in the resource property of the IAM Identity Policy statement, thinking that the alias would refer to the KMS Key, thus allowing the kms:Decrypt and kms:Encrypt permissions. But that’s not the case.
The policy below will not work:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:Encrypt",
],
"Resource": "arn:aws:kms:{REGION}:{ACCOUNT_A_ID}:alias/production-data-key"
}
]
}
This policy does not have any effect because when you add an alias to the Resource property, you should use permissions related to aliases and not the underlying kms key. Im this case the applicable permissions would be: kms:CreateAlias, kms:UpdateAlias, or kms:DeleteAlias.
Solution
In this solution, we have two AWS accounts:
- Account A (Key Owner): Hosts the KMS key and its alias. Defines the Kms Key Resource Policy that grants permissions for cross-account access.
- Account B (Key User): Needs to use the KMS key for encrypting or decrypting data.
Key Components:
- KMS Key and Alias: Managed in Account A.
- IAM Role in Account B: Defines an Identity Policy that grants access to the alias in Account A.
- IAM Identity Policy and Key Resource Policy: Work together to enforce the principle of least privilege.
Configuring IAM Roles for Cross-Account KMS Access
To enable cross-account access using key aliases, follow these steps:
Step 1: Create the Kms Key
In account A create the Kms Key following these steps:
- In the AWS Console of Account A, access the Key Management Service page
- Click in the orange button Create Key (at the top right)
- Keep the default options: Key Type=Symmetric, Key usage=Encrypt and Decrypt
- CLick Next
- Fill the Alias field with
production-data-key
- Give a description to the Kms Key
- Click Next until you see the Review page
- Click Finish to create the Kms Key.
Step 2: Define the Kms Key Resource Policy
The Kms key resource policy is the foundation for granting cross-account permissions. Here’s an example policy:
{
"Version": "2012-10-17",
"Id": "key-policy",
"Statement": [
{
"Sid": "AllowAccountBAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::{ACCOUNT_B_ID}:root"
},
"Action": [
"kms:Decrypt",
"kms:Encrypt",
],
"Resource": "arn:aws:kms:{REGION}:{ACCOUNT_A_ID}:key/{replace-with-kms-key-id}"
}
]
}
Step 3: Configure IAM Role in Account B
Create an IAM role in Account B and attach a policy that grants permission to use the Kms Key identified by the Resource Alias.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:Encrypt",
],
"Resource": "arn:aws:kms:{REGION}:{ACCOUNT_A_ID}:key/*",
"Condition": {
"ForAnyValue:StringLike": {
"kms:ResourceAliases": "alias/production-data-key"
}
}
}
]
}
Best Practices for Permissions
Least Privilege
- Grant only the necessary actions (e.g.,
kms:Decrypt
orkms:Encrypt
) for the specific use case. - Limit resource access to specific aliases or keys wherever possible.
Resource Policies vs. IAM Identity Policies
AWS recommends using Resource Policies as the primary method for managing access to the KMS Key because they are directly associated with the resource. IAM Identity Policies can complement Kms Key Resource Policies, but cannot bypass key-specific restrictions.
Conclusion
Using key aliases for cross-account KMS access offers significant benefits in terms of maintainability, scalability, and operational simplicity. By following best practices for IAM roles and permissions, you can build a secure and efficient solution that adapts to changing requirements. While alternatives like direct key IDs have their place, aliases are the preferred choice for most scenarios.
Key Takeaway: Invest time in understanding and implementing KMS key aliases—they are a powerful tool for simplifying encryption management in AWS.