Skip to main content

The CDK Construct Library for AWS::KMS

Project description

AWS Key Management Service Construct Library

---

cfn-resources: Stable

cdk-constructs: Stable


Define a KMS key:

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import aws_cdk.aws_kms as kms

kms.Key(self, "MyKey",
    enable_key_rotation=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.

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
key = kms.Key(self, "MyKey",
    pending_window=10
)

Add a couple of aliases:

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
key = kms.Key(self, "MyKey")
key.add_alias("alias/foo")
key.add_alias("alias/bar")

Define a key with specific key spec and key usage:

Valid keySpec values depends on keyUsage value.

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
key = kms.Key(self, "MyKey",
    key_spec=kms.KeySpec.ECC_SECG_P256K1, # Default to SYMMETRIC_DEFAULT
    key_usage=kms.KeyUsage.SIGN_VERIFY
)

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:

# Example automatically generated. See https://github.com/aws/jsii/issues/826
#
# Stack that defines the key
#
class KeyStack(cdk.Stack):

    def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, synthesizer=None, terminationProtection=None, analyticsReporting=None):
        super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting)
        self.key = kms.Key(self, "MyKey", removal_policy=cdk.RemovalPolicy.DESTROY)

#
# Stack that uses the key
#
class UseStack(cdk.Stack):
    def __init__(self, scope, id, *, key, description=None, env=None, stackName=None, tags=None, synthesizer=None, terminationProtection=None, analyticsReporting=None):
        super().__init__(scope, id, key=key, description=description, env=env, stackName=stackName, tags=tags, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting)

        # Use the IKey object here.
        kms.Alias(self, "Alias",
            alias_name="alias/foo",
            target_key=key
        )

key_stack = KeyStack(app, "KeyStack")
UseStack(app, "UseStack", key=key_stack.key)

Importing existing keys

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):

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_key_imported = kms.Key.from_key_arn(self, "MyImportedKey", "arn:aws:...")

# you can do stuff with this imported key.
my_key_imported.add_alias("alias/foo")

Note that a call to .addToPolicy(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.

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_key_alias = kms.Alias.from_alias_name(self, "myKey", "alias/aws/s3")
trail = cloudtrail.Trail(self, "myCloudTrail",
    send_to_cloud_watch_logs=True,
    kms_key=my_key_alias
)

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.

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:

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
kms.Key(stack, "MyKey", trust_account_identities=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.

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
key = kms.Key(stack, "MyKey")
user = iam.User(stack, "MyUser")
key.grant_encrypt(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.

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_trusted_admin_role = iam.Role.from_role_arn(stack, "TrustedRole", "arn:aws:iam:....")
key = kms.Key(stack, "MyKey",
    admins=[my_trusted_admin_role]
)

second_key = kms.Key(stack, "MyKey2")
second_key.grant_admin(my_trusted_admin_role)

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.

# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_trusted_admin_role = iam.Role.from_role_arn(stack, "TrustedRole", "arn:aws:iam:....")
# Creates a limited admin policy and assigns to the account root.
my_custom_policy = iam.PolicyDocument(
    statements=[iam.PolicyStatement(
        actions=["kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*"
        ],
        principals=[iam.AccountRootPrincipal()],
        resources=["*"]
    )]
)
key = kms.Key(stack, "MyKey",
    policy=my_custom_policy
)

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.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aws-cdk.aws-kms-1.110.1.tar.gz (82.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aws_cdk.aws_kms-1.110.1-py3-none-any.whl (80.7 kB view details)

Uploaded Python 3

File details

Details for the file aws-cdk.aws-kms-1.110.1.tar.gz.

File metadata

  • Download URL: aws-cdk.aws-kms-1.110.1.tar.gz
  • Upload date:
  • Size: 82.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.6.5

File hashes

Hashes for aws-cdk.aws-kms-1.110.1.tar.gz
Algorithm Hash digest
SHA256 51acfe348f4b6c8fddfe76e4c12a3c8cff723ae65430ab77457cedd1a319ba4e
MD5 646ce65d4d6dc1166c00b7bddf9e039f
BLAKE2b-256 7fa1ac0575a2a99d763533f4fa560e3f042c6aab3362836d22225d06e64f4a52

See more details on using hashes here.

File details

Details for the file aws_cdk.aws_kms-1.110.1-py3-none-any.whl.

File metadata

  • Download URL: aws_cdk.aws_kms-1.110.1-py3-none-any.whl
  • Upload date:
  • Size: 80.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.6.5

File hashes

Hashes for aws_cdk.aws_kms-1.110.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dade5a68c5d7413324e9649fba0ec40ae92f06996bebc81e57b9a9839647dfea
MD5 4771cb24090c1cc04eb02ce8ac9dc08e
BLAKE2b-256 14224efbc07cc9a815bd5c1ade6ba4c2176a6ee632baa55fcfefb9092ba8b882

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page