Namespace Amazon.CDK.AWS.KMS
AWS Key Management Service Construct Library
Define a KMS key:
new Key(this, "MyKey", new KeyProps {
EnableKeyRotation = true,
RotationPeriod = Duration.Days(180)
});
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.
var key = new Key(this, "MyKey", new KeyProps {
PendingWindow = Duration.Days(10)
});
Add a couple of aliases:
var key = new 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.
var key = new Key(this, "MyKey", new KeyProps {
KeySpec = KeySpec.ECC_SECG_P256K1, // Default to SYMMETRIC_DEFAULT
KeyUsage = KeyUsage.SIGN_VERIFY
});
Create a multi-Region primary key:
var key = new Key(this, "MyKey", new KeyProps {
MultiRegion = true
});
Sharing keys between stacks
To use a KMS key in a different stack in the same CDK application, pass the construct to the other stack:
/**
* Stack that defines the key
*/
class KeyStack : Stack
{
public Key Key { get; }
public KeyStack(App scope, string id, StackProps? props=null) : base(scope, id, props)
{
Key = new Key(this, "MyKey", new KeyProps { RemovalPolicy = RemovalPolicy.DESTROY });
}
}
class UseStackProps : StackProps
{
public IKey Key { get; set; }
}
/**
* Stack that uses the key
*/
class UseStack : Stack
{
public UseStack(App scope, string id, UseStackProps props) : base(scope, id, props)
{
// Use the IKey object here.
// Use the IKey object here.
new Alias(this, "Alias", new AliasProps {
AliasName = "alias/foo",
TargetKey = props.Key
});
}
}
var keyStack = new KeyStack(app, "KeyStack");
new UseStack(app, "UseStack", new UseStackProps { Key = keyStack.Key });
Importing existing keys
Import key by ARN
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)
:
var myKeyImported = 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.
Import key by alias
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.
using Amazon.CDK.AWS.CloudTrail;
var myKeyAlias = Alias.FromAliasName(this, "myKey", "alias/aws/s3");
var trail = new Trail(this, "myCloudTrail", new TrailProps {
SendToCloudWatchLogs = true,
EncryptionKey = 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.
Lookup key by alias
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:
var myKeyLookup = Key.FromLookup(this, "MyKeyLookup", new KeyLookupOptions {
AliasName = "alias/KeyAlias"
});
var role = new Role(this, "MyRole", new RoleProps {
AssumedBy = new 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.
If the target key is not found in your account, an error will be thrown.
To prevent the error in the case, you can receive a dummy key without the error
by setting returnDummyKeyOnMissing
to true
. The dummy key has a keyId
of
1234abcd-12ab-34cd-56ef-1234567890ab
. The value of the dummy key id can also be
referenced using the Key.DEFAULT_DUMMY_KEY_ID
variable, and you can check if the
key is a dummy key by using the Key.isLookupDummy()
method.
var dummy = Key.FromLookup(this, "MyKeyLookup", new KeyLookupOptions {
AliasName = "alias/NonExistentAlias",
ReturnDummyKeyOnMissing = true
});
if (Key.IsLookupDummy(dummy))
{
}
Key Policies
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 Key(this, "MyKey", new KeyProps { 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.
var key = new Key(this, "MyKey");
var user = new User(this, "MyUser");
key.GrantEncrypt(user);
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.)
Appending to or replacing the default key policy
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.
var myTrustedAdminRole = Role.FromRoleArn(this, "TrustedRole", "arn:aws:iam:....");
var key = new Key(this, "MyKey", new KeyProps {
Admins = new [] { myTrustedAdminRole }
});
var secondKey = new 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.
var myTrustedAdminRole = Role.FromRoleArn(this, "TrustedRole", "arn:aws:iam:....");
// Creates a limited admin policy and assigns to the account root.
var myCustomPolicy = new PolicyDocument(new PolicyDocumentProps {
Statements = new [] { new PolicyStatement(new PolicyStatementProps {
Actions = new [] { "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*" },
Principals = new [] { new AccountRootPrincipal() },
Resources = new [] { "*" }
}) }
});
var key = new Key(this, "MyKey", new KeyProps {
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.
Signing and Verification key policies
Creating signatures and verifying them with KMS requires specific permissions.
The respective policies can be attached to a principal via the grantSign
and grantVerify
methods.
var key = new Key(this, "MyKey");
var user = new User(this, "MyUser");
key.GrantSign(user); // Adds 'kms:Sign' to the principal's policy
key.GrantVerify(user);
If both sign and verify permissions are required, they can be applied with one method called grantSignVerify
.
var key = new Key(this, "MyKey");
var user = new User(this, "MyUser");
key.GrantSignVerify(user);
HMAC specific key policies
HMAC keys have a different key policy than other KMS keys. They have a policy for generating and for verifying a MAC.
The respective policies can be attached to a principal via the grantGenerateMac
and grantVerifyMac
methods.
var key = new Key(this, "MyKey");
var user = new User(this, "MyUser");
key.GrantGenerateMac(user); // Adds 'kms:GenerateMac' to the principal's policy
key.GrantVerifyMac(user);
Classes
Alias | Defines a display name for a customer master key (CMK) in AWS Key Management Service (AWS KMS). |
AliasAttributes | Properties of a reference to an existing KMS Alias. |
AliasProps | Construction properties for a KMS Key Alias object. |
CfnAlias | The |
CfnAliasProps | Properties for defining a |
CfnKey | The |
CfnKeyProps | Properties for defining a |
CfnReplicaKey | The |
CfnReplicaKeyProps | Properties for defining a |
Key | Defines a KMS key. |
KeyLookupOptions | Properties for looking up an existing Key. |
KeyProps | Construction properties for a KMS Key object. |
KeySpec | The key spec, represents the cryptographic configuration of keys. |
KeyUsage | The key usage, represents the cryptographic operations of keys. |
ViaServicePrincipal | A principal to allow access to a key if it's being used through another AWS service. |
Interfaces
IAlias | A KMS Key alias. |
IAliasAttributes | Properties of a reference to an existing KMS Alias. |
IAliasProps | Construction properties for a KMS Key Alias object. |
ICfnAliasProps | Properties for defining a |
ICfnKeyProps | Properties for defining a |
ICfnReplicaKeyProps | Properties for defining a |
IKey | A KMS Key, either managed by this CDK app, or imported. |
IKeyLookupOptions | Properties for looking up an existing Key. |
IKeyProps | Construction properties for a KMS Key object. |