UNPKG

7.94 kBMarkdownView Raw
1# AWS Key Management Service Construct Library
2<!--BEGIN STABILITY BANNER-->
3
4---
5
6![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
7
8![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)
9
10---
11
12<!--END STABILITY BANNER-->
13
14Define a KMS key:
15
16```ts
17new kms.Key(this, 'MyKey', {
18 enableKeyRotation: true,
19});
20```
21
22Define a KMS key with waiting period:
23
24Specifies the number of days in the waiting period before AWS KMS deletes a CMK that has been removed from a CloudFormation stack.
25
26```ts
27const key = new kms.Key(this, 'MyKey', {
28 pendingWindow: Duration.days(10), // Default to 30 Days
29});
30```
31
32
33Add a couple of aliases:
34
35```ts
36const key = new kms.Key(this, 'MyKey');
37key.addAlias('alias/foo');
38key.addAlias('alias/bar');
39```
40
41
42Define a key with specific key spec and key usage:
43
44Valid `keySpec` values depends on `keyUsage` value.
45
46```ts
47const key = new kms.Key(this, 'MyKey', {
48 keySpec: kms.KeySpec.ECC_SECG_P256K1, // Default to SYMMETRIC_DEFAULT
49 keyUsage: kms.KeyUsage.SIGN_VERIFY, // and ENCRYPT_DECRYPT
50});
51```
52
53## Sharing keys between stacks
54
55To use a KMS key in a different stack in the same CDK application,
56pass the construct to the other stack:
57
58[sharing key between stacks](test/integ.key-sharing.lit.ts)
59
60
61## Importing existing keys
62
63### Import key by ARN
64
65To use a KMS key that is not defined in this CDK app, but is created through other means, use
66`Key.fromKeyArn(parent, name, ref)`:
67
68```ts
69const myKeyImported = kms.Key.fromKeyArn(this, 'MyImportedKey', 'arn:aws:...');
70
71// you can do stuff with this imported key.
72myKeyImported.addAlias('alias/foo');
73```
74
75Note that a call to `.addToResourcePolicy(statement)` on `myKeyImported` will not have
76an affect on the key's policy because it is not owned by your stack. The call
77will be a no-op.
78
79### Import key by alias
80
81If a Key has an associated Alias, the Alias can be imported by name and used in place
82of the Key as a reference. A common scenario for this is in referencing AWS managed keys.
83
84```ts
85import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
86
87const myKeyAlias = kms.Alias.fromAliasName(this, 'myKey', 'alias/aws/s3');
88const trail = new cloudtrail.Trail(this, 'myCloudTrail', {
89 sendToCloudWatchLogs: true,
90 kmsKey: myKeyAlias,
91});
92```
93
94Note that calls to `addToResourcePolicy` and `grant*` methods on `myKeyAlias` will be
95no-ops, and `addAlias` and `aliasTargetKey` will fail, as the imported alias does not
96have a reference to the underlying KMS Key.
97
98### Lookup key by alias
99
100If 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()`.
101
102In 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.
103
104The result of the `Key.fromLookup()` operation will be written to a file
105called `cdk.context.json`. You must commit this file to source control so
106that the lookup values are available in non-privileged environments such
107as CI build steps, and to ensure your template builds are repeatable.
108
109Here's how `Key.fromLookup()` can be used:
110
111```ts
112const myKeyLookup = kms.Key.fromLookup(this, 'MyKeyLookup', {
113 aliasName: 'alias/KeyAlias',
114});
115
116const role = new iam.Role(this, 'MyRole', {
117 assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
118});
119myKeyLookup.grantEncryptDecrypt(role);
120```
121
122Note that a call to `.addToResourcePolicy(statement)` on `myKeyLookup` will not have
123an affect on the key's policy because it is not owned by your stack. The call
124will be a no-op.
125
126## Key Policies
127
128Controlling access and usage of KMS Keys requires the use of key policies (resource-based policies attached to the key);
129this is in contrast to most other AWS resources where access can be entirely controlled with IAM policies,
130and optionally complemented with resource policies. For more in-depth understanding of KMS key access and policies, see
131
132* https://docs.aws.amazon.com/kms/latest/developerguide/control-access-overview.html
133* https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html
134
135KMS keys can be created to trust IAM policies. This is the default behavior for both the KMS APIs and in
136the console. This behavior is enabled by the '@aws-cdk/aws-kms:defaultKeyPolicies' feature flag,
137which is set for all new projects; for existing projects, this same behavior can be enabled by
138passing the `trustAccountIdentities` property as `true` when creating the key:
139
140```ts
141new kms.Key(this, 'MyKey', { trustAccountIdentities: true });
142```
143
144With either the `@aws-cdk/aws-kms:defaultKeyPolicies` feature flag set,
145or the `trustAccountIdentities` prop set, the Key will be given the following default key policy:
146
147```json
148{
149 "Effect": "Allow",
150 "Principal": {"AWS": "arn:aws:iam::111122223333:root"},
151 "Action": "kms:*",
152 "Resource": "*"
153}
154```
155
156This policy grants full access to the key to the root account user.
157This enables the root account user -- via IAM policies -- to grant access to other IAM principals.
158With the above default policy, future permissions can be added to either the key policy or IAM principal policy.
159
160```ts
161const key = new kms.Key(this, 'MyKey');
162const user = new iam.User(this, 'MyUser');
163key.grantEncrypt(user); // Adds encrypt permissions to user policy; key policy is unmodified.
164```
165
166Adopting the default KMS key policy (and so trusting account identities)
167solves many issues around cyclic dependencies between stacks.
168Without this default key policy, future permissions must be added to both the key policy and IAM principal policy,
169which can cause cyclic dependencies if the permissions cross stack boundaries.
170(For example, an encrypted bucket in one stack, and Lambda function that accesses it in another.)
171
172### Appending to or replacing the default key policy
173
174The default key policy can be amended or replaced entirely, depending on your use case and requirements.
175A common addition to the key policy would be to add other key admins that are allowed to administer the key
176(e.g., change permissions, revoke, delete). Additional key admins can be specified at key creation or after
177via the `grantAdmin` method.
178
179```ts
180const myTrustedAdminRole = iam.Role.fromRoleArn(this, 'TrustedRole', 'arn:aws:iam:....');
181const key = new kms.Key(this, 'MyKey', {
182 admins: [myTrustedAdminRole],
183});
184
185const secondKey = new kms.Key(this, 'MyKey2');
186secondKey.grantAdmin(myTrustedAdminRole);
187```
188
189Alternatively, a custom key policy can be specified, which will replace the default key policy.
190
191> **Note**: In applications without the '@aws-cdk/aws-kms:defaultKeyPolicies' feature flag set
192and with `trustedAccountIdentities` set to false (the default), specifying a policy at key creation _appends_ the
193provided policy to the default key policy, rather than _replacing_ the default policy.
194
195```ts
196const myTrustedAdminRole = iam.Role.fromRoleArn(this, 'TrustedRole', 'arn:aws:iam:....');
197// Creates a limited admin policy and assigns to the account root.
198const myCustomPolicy = new iam.PolicyDocument({
199 statements: [new iam.PolicyStatement({
200 actions: [
201 'kms:Create*',
202 'kms:Describe*',
203 'kms:Enable*',
204 'kms:List*',
205 'kms:Put*',
206 ],
207 principals: [new iam.AccountRootPrincipal()],
208 resources: ['*'],
209 })],
210});
211const key = new kms.Key(this, 'MyKey', {
212 policy: myCustomPolicy,
213});
214```
215
216> **Warning:** Replacing the default key policy with one that only grants access to a specific user or role
217runs the risk of the key becoming unmanageable if that user or role is deleted.
218It is highly recommended that the key policy grants access to the account root, rather than specific principals.
219See https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html for more information.