Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
@aws-cdk/aws-kms
Advanced tools
@aws-cdk/aws-kms is an AWS CDK library that allows you to define and manage AWS Key Management Service (KMS) resources in your AWS infrastructure as code. It provides constructs for creating and managing KMS keys, aliases, and grants, enabling secure encryption and decryption of data.
Create a KMS Key
This code sample demonstrates how to create a new KMS key with key rotation enabled and an alias using the AWS CDK.
const cdk = require('@aws-cdk/core');
const kms = require('@aws-cdk/aws-kms');
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const key = new kms.Key(stack, 'MyKey', {
enableKeyRotation: true,
alias: 'alias/my-key'
});
app.synth();
Create a KMS Alias
This code sample demonstrates how to create a new KMS alias that points to an existing KMS key using the AWS CDK.
const cdk = require('@aws-cdk/core');
const kms = require('@aws-cdk/aws-kms');
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const key = new kms.Key(stack, 'MyKey');
const alias = new kms.Alias(stack, 'MyAlias', {
aliasName: 'alias/my-alias',
targetKey: key
});
app.synth();
Grant Permissions to a KMS Key
This code sample demonstrates how to grant encrypt and decrypt permissions to an IAM user for a KMS key using the AWS CDK.
const cdk = require('@aws-cdk/core');
const kms = require('@aws-cdk/aws-kms');
const iam = require('@aws-cdk/aws-iam');
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const key = new kms.Key(stack, 'MyKey');
const user = new iam.User(stack, 'MyUser');
key.grantEncryptDecrypt(user);
app.synth();
The aws-sdk package is the official AWS SDK for JavaScript, which provides a comprehensive set of tools for interacting with AWS services, including KMS. Unlike @aws-cdk/aws-kms, which is used for defining infrastructure as code, aws-sdk is used for making API calls to AWS services directly from your application code.
The serverless package is a framework for building and deploying serverless applications on AWS and other cloud providers. It includes support for managing AWS KMS keys as part of your serverless infrastructure. While it provides similar functionality for managing KMS keys, it is more focused on serverless architectures compared to the broader infrastructure management capabilities of @aws-cdk/aws-kms.
Terraform is an open-source infrastructure as code tool that allows you to define and manage cloud resources, including AWS KMS keys, using a declarative configuration language. It provides similar functionality to @aws-cdk/aws-kms but uses a different syntax and approach to infrastructure management.
Define a KMS key:
new kms.Key(this, 'MyKey', {
enableKeyRotation: true,
});
Define a KMS key with waiting period:
Specifies the number of days in the waiting period before AWS KMS deletes a CMK that has been removed from a CloudFormation stack.
const key = new kms.Key(this, 'MyKey', {
pendingWindow: Duration.days(10), // Default to 30 Days
});
Add a couple of aliases:
const key = new kms.Key(this, 'MyKey');
key.addAlias('alias/foo');
key.addAlias('alias/bar');
Define a key with specific key spec and key usage:
Valid keySpec
values depends on keyUsage
value.
const key = new kms.Key(this, 'MyKey', {
keySpec: kms.KeySpec.ECC_SECG_P256K1, // Default to SYMMETRIC_DEFAULT
keyUsage: kms.KeyUsage.SIGN_VERIFY, // and ENCRYPT_DECRYPT
});
To use a KMS key in a different stack in the same CDK application, pass the construct to the other stack:
To use a KMS key that is not defined in this CDK app, but is created through other means, use
Key.fromKeyArn(parent, name, ref)
:
const myKeyImported = kms.Key.fromKeyArn(this, 'MyImportedKey', 'arn:aws:...');
// you can do stuff with this imported key.
myKeyImported.addAlias('alias/foo');
Note that a call to .addToResourcePolicy(statement)
on myKeyImported
will not have
an affect on the key's policy because it is not owned by your stack. The call
will be a no-op.
If a Key has an associated Alias, the Alias can be imported by name and used in place of the Key as a reference. A common scenario for this is in referencing AWS managed keys.
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
const myKeyAlias = kms.Alias.fromAliasName(this, 'myKey', 'alias/aws/s3');
const trail = new cloudtrail.Trail(this, 'myCloudTrail', {
sendToCloudWatchLogs: true,
kmsKey: myKeyAlias,
});
Note that calls to addToResourcePolicy
and grant*
methods on myKeyAlias
will be
no-ops, and addAlias
and aliasTargetKey
will fail, as the imported alias does not
have a reference to the underlying KMS Key.
If you can't use a KMS key imported by alias (e.g. because you need access to the key id), you can lookup the key with Key.fromLookup()
.
In general, the preferred method would be to use Alias.fromAliasName()
which returns an IAlias
object which extends IKey
. However, some services need to have access to the underlying key id. In this case, Key.fromLookup()
allows to lookup the key id.
The result of the Key.fromLookup()
operation will be written to a file
called cdk.context.json
. You must commit this file to source control so
that the lookup values are available in non-privileged environments such
as CI build steps, and to ensure your template builds are repeatable.
Here's how Key.fromLookup()
can be used:
const myKeyLookup = kms.Key.fromLookup(this, 'MyKeyLookup', {
aliasName: 'alias/KeyAlias',
});
const role = new iam.Role(this, 'MyRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
myKeyLookup.grantEncryptDecrypt(role);
Note that a call to .addToResourcePolicy(statement)
on myKeyLookup
will not have
an affect on the key's policy because it is not owned by your stack. The call
will be a no-op.
Controlling access and usage of KMS Keys requires the use of key policies (resource-based policies attached to the key); this is in contrast to most other AWS resources where access can be entirely controlled with IAM policies, and optionally complemented with resource policies. For more in-depth understanding of KMS key access and policies, see
KMS keys can be created to trust IAM policies. This is the default behavior for both the KMS APIs and in
the console. This behavior is enabled by the '@aws-cdk/aws-kms:defaultKeyPolicies' feature flag,
which is set for all new projects; for existing projects, this same behavior can be enabled by
passing the trustAccountIdentities
property as true
when creating the key:
new kms.Key(this, 'MyKey', { trustAccountIdentities: true });
With either the @aws-cdk/aws-kms:defaultKeyPolicies
feature flag set,
or the trustAccountIdentities
prop set, the Key will be given the following default key policy:
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*",
"Resource": "*"
}
This policy grants full access to the key to the root account user. This enables the root account user -- via IAM policies -- to grant access to other IAM principals. With the above default policy, future permissions can be added to either the key policy or IAM principal policy.
const key = new kms.Key(this, 'MyKey');
const user = new iam.User(this, 'MyUser');
key.grantEncrypt(user); // Adds encrypt permissions to user policy; key policy is unmodified.
Adopting the default KMS key policy (and so trusting account identities) solves many issues around cyclic dependencies between stacks. Without this default key policy, future permissions must be added to both the key policy and IAM principal policy, which can cause cyclic dependencies if the permissions cross stack boundaries. (For example, an encrypted bucket in one stack, and Lambda function that accesses it in another.)
The default key policy can be amended or replaced entirely, depending on your use case and requirements.
A common addition to the key policy would be to add other key admins that are allowed to administer the key
(e.g., change permissions, revoke, delete). Additional key admins can be specified at key creation or after
via the grantAdmin
method.
const myTrustedAdminRole = iam.Role.fromRoleArn(this, 'TrustedRole', 'arn:aws:iam:....');
const key = new kms.Key(this, 'MyKey', {
admins: [myTrustedAdminRole],
});
const secondKey = new kms.Key(this, 'MyKey2');
secondKey.grantAdmin(myTrustedAdminRole);
Alternatively, a custom key policy can be specified, which will replace the default key policy.
Note: In applications without the '@aws-cdk/aws-kms:defaultKeyPolicies' feature flag set and with
trustedAccountIdentities
set to false (the default), specifying a policy at key creation appends the provided policy to the default key policy, rather than replacing the default policy.
const myTrustedAdminRole = iam.Role.fromRoleArn(this, 'TrustedRole', 'arn:aws:iam:....');
// Creates a limited admin policy and assigns to the account root.
const myCustomPolicy = new iam.PolicyDocument({
statements: [new iam.PolicyStatement({
actions: [
'kms:Create*',
'kms:Describe*',
'kms:Enable*',
'kms:List*',
'kms:Put*',
],
principals: [new iam.AccountRootPrincipal()],
resources: ['*'],
})],
});
const key = new kms.Key(this, 'MyKey', {
policy: myCustomPolicy,
});
Warning: Replacing the default key policy with one that only grants access to a specific user or role runs the risk of the key becoming unmanageable if that user or role is deleted. It is highly recommended that the key policy grants access to the account root, rather than specific principals. See https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html for more information.
1.155.0 (2022-05-04)
inOrganization
to ArnPrincipal (#20109) (c545bfe), closes /github.com/aws/aws-cdk/pull/19975#discussion_r857385168 #19975function.addAlias()
simplifies Alias creation (#20034) (a79bc47)DatabaseClusterFromSnapshot
(#20020) (abc3502), closes #12877FAQs
The CDK Construct Library for AWS::KMS
The npm package @aws-cdk/aws-kms receives a total of 107,251 weekly downloads. As such, @aws-cdk/aws-kms popularity was classified as popular.
We found that @aws-cdk/aws-kms demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.