Skip to content

Commit abdf4ea

Browse files
texastonyseebees
andauthored
feat(Keystore): Introduce additional KMSConfiguration options (#271)
* feat(Keystore): Introduce additional KMSConfiguration options The Hierarchical Keyring's Keystore now supports four (4) `KMSConfigurations`: - kmsKeyArn - kmsMRKeyArn - discovery - MRDiscovery Co-authored-by: seebees <[email protected]>
1 parent 66da9f3 commit abdf4ea

File tree

3 files changed

+452
-48
lines changed

3 files changed

+452
-48
lines changed

.markdownlint.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"MD013": false,
3+
"MD032": false,
4+
"MD041": false
5+
}
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved."
2+
[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0"
3+
4+
# Branch Keystore KMS Configuration of Discovery
5+
6+
## Affected Features
7+
8+
This serves as a reference of all features that this change affects.
9+
10+
| Feature |
11+
| ----------------------------------------------- |
12+
| [Keystore](../../framework/branch-key-store.md) |
13+
14+
## Affected Specifications
15+
16+
This serves as a reference of all specification documents that this change affects.
17+
18+
| Specification |
19+
| --------------------------------------------------------------------------------------- |
20+
| [Keystore](../../framework/branch-key-store.md) |
21+
| [AWS KMS Hierarchical Keyring](../../framework/aws-kms/aws-kms-hierarchical-keyring.md) |
22+
23+
## Affected Implementations
24+
25+
| Language | Version Introduced | Version Removed | Implementation |
26+
| -------- | ------------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27+
| Dafny | 1.4.0 | n/a | [AwsCryptographyKeyStoreOperations.dfy](https://github.com/aws/aws-cryptographic-material-providers-library/blob/main/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/src/AwsCryptographyKeyStoreOperations.dfy) |
28+
| Java | 1.4.0 | n/a | [KeyStore.java](https://github.com/aws/aws-cryptographic-material-providers-library/blob/main/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/KeyStore.java) |
29+
| .NET | 1.4.0 | n/a | [KeyStore.cs](https://github.com/aws/aws-cryptographic-material-providers-library/blob/main/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/KeyStore.cs) |
30+
31+
## Definitions
32+
33+
An "MPL Consumer" is a library, service, or other application
34+
that uses the AWS Cryptographic Material Providers Library (MPL)
35+
to manage cryptographic materials.
36+
An "MPL Consumer" may or may not be using an AWS Crypto Tools product,
37+
such as the AWS Encryption SDK or AWS Database Encryption SDK.
38+
39+
A "discovery Keystore" is a (Branch) Keystore with
40+
a KMS Configuration of Discovery or Multi-Region Discovery (MRDiscovery).
41+
42+
A "static Keystore" is a (Branch) Keystore with
43+
a KMS Configuration of KMS Key ARN.
44+
45+
A "strict Keystore" is a (Branch) Keystore with
46+
a KMS Configuration of KMS Multi-Region Key ARN or KMS Key ARN.
47+
48+
### Conventions used in this document
49+
50+
The key words
51+
"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
52+
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL"
53+
in this document are to be interpreted as described in
54+
[RFC 2119](https://tools.ietf.org/html/rfc2119).
55+
56+
## Summary
57+
58+
Allow MPL Consumers to easily configure
59+
a Hierarchical Keyring to use
60+
the KMS Key ARNs already persisted to a Logical Keystore.
61+
62+
Additionally, ensure a KMS Alias is not permitted as a KMS Key ARN.
63+
64+
## Out of Scope
65+
66+
- Administrative/Mutating operations for a Keystore with a KMS Configuration of Discovery;
67+
these are `VersionKey` & `CreateKey`.
68+
- Lifecycle operations for the Keystore
69+
- Changes to the Hierarchy Keyring to improve Caching performance across multiple Keystores
70+
71+
## Motivation
72+
73+
The (Branch) Keystore and the AWS KMS Hierarchical Keyring
74+
can be used to facilitate Client Side Encryption for
75+
a Multi-tenant environment where each tenant has at least one
76+
[Branch Key](../../framework/structures.md#branch-key-materials).
77+
However, Tenants may want an MPL Consumer to protect
78+
their data with a particular KMS Key that is NOT necessarily the same
79+
as other tenants.
80+
81+
Such a Multi-KMS Keystore is, prior to this change, difficult to use
82+
as a Keystore instance is restricted to one and only one KMS Key ARN.
83+
Many MPL Consumers have developed a work around to this restriction
84+
by constructing and then caching a Keystore per KMS Key ARN.
85+
These MPL Consumers than stand up their own "request-to-Keystore-to-BranchKeyID" logic.
86+
This workaround may require an additional lookup
87+
compared to the normal "Encryption Context determines Branch Key ID"
88+
path.
89+
90+
The goal then is to allow MPL Consumers to construct Keystore instances that
91+
MAY use the KMS Key ARNs already persisted to a Logical Keystore.
92+
93+
Put another way,
94+
usage of Branch Keys need only consider the Keystore's Logical Name
95+
(and therefore, backing persistance medium, which is currently always a DynamoDB table)
96+
and Branch Key ID.
97+
98+
Usage may not need the KMS ARN.
99+
100+
### KMS Alias
101+
102+
Because the Branch Key creation operation asserted the result
103+
of KMS `ReEncrypt` matched the Keystore's configured KMS Key ARN,
104+
a KMS Key Alias could never be used with a Keystore to successfully create a Branch Key.
105+
106+
However, the runtime exception thrown did not make it clear
107+
why `CreateKey` failed.
108+
109+
Rather than correct the exception,
110+
Keystore construction MUST fail if the KMS Configuration
111+
is "strict"
112+
(KMS Key ARN or KMS MRKey ARN)
113+
and the provided ARN is an Alias.
114+
115+
### Hierarchy Keyring Caching
116+
117+
Currently, the Hierarchy Keyring creates its own cache.
118+
119+
To facilitate Caching performance across Keystores/KMS Clients/KMS Keys,
120+
we could (optionally) break the Cache out of the Hierarchy Keyring.
121+
122+
The Hierarhcy Keyring would instead take a constructed a Cache as
123+
an arguement during initialization.
124+
125+
When writing to the Cache,
126+
the Hierarchy Keyring would include the Keystore's ID,
127+
which, ideally, uniquely identifies its KMS relationship.
128+
129+
By KMS Relationship, we mean any or all of the following:
130+
131+
- KMS Configuration
132+
- Credentials used when creating the KMS Client, and thus used when calling KMS
133+
- Other properties of the KMS Client, such as the region, or request headers
134+
135+
The changes proposed (and comitted to) here
136+
do not include such a Cache refactoring,
137+
as that would not address the stated goal
138+
of allowing one Keystore to work across multiple
139+
KMS ARNs.
140+
141+
## Operational Implications
142+
143+
For Keystore's usage by a AWS KMS Hierarchical Keyring,
144+
a "discovery Keystore" is identical to
145+
a "kmsKeyArn Keystore".
146+
147+
However, only a "strict Keystore" can Create
148+
or Version (rotate) Branch Keys.
149+
150+
Thus, all MPL Consumers MAY or MAY NOT
151+
adopt a "discovery Keystore" as best fits their needs.
152+
153+
## Reference-level Explanation
154+
155+
### Keystore [AWS KMS Configuration](../../framework/branch-key-store.md#aws-kms-configuration) Options
156+
157+
The following Options are introduced:
158+
159+
- Discovery
160+
- MRDiscovery
161+
162+
Which compliment the already exsisting options:
163+
164+
- KMS Key ARN (Single Region Compatability)
165+
- KMS MRKey ARN (Multi-Region Compatability)
166+
167+
API documentation MUST clarify the
168+
behavioral difference between these 4 options.
169+
170+
If a KMS Key ARN is provided,
171+
it MUST NOT be an Alias.
172+
173+
If the KMS Configuration is not Discovery or MRDiscovery,
174+
the KMS Configuration MUST distinguish between single region ARN compatibility
175+
(KMS Key ARN)
176+
and MRK ARN compatibility
177+
(KMS MRKey Arn).
178+
179+
A "strict" Keystore is a Keystore with a KMS Configuration of either:
180+
181+
- KMS Key ARN
182+
- KMS MRKey ARN
183+
184+
A "static" Keystore is a Keystore with a KMS Configuration of KMS Key ARN.
185+
186+
Discovery takes no additional arguements.
187+
188+
MRDiscovery requires a Region arguement,
189+
and Keystore contruction MUST FAIL if a Region is not provided.
190+
191+
### Keystore's [AWS Key Arn Compatibility](../../framework/branch-key-store.md#aws-key-arn-compatibility)
192+
193+
The following line is added at the end:
194+
If the [AWS KMS Configuration](#aws-kms-configuration) is Discovery or MRDiscovery,
195+
no comparison is ever made between ARNs.
196+
197+
### Keystore [DynamoDb Client](../../framework/branch-key-store.md#dynamodb-client)
198+
199+
If the AWS KMS Configuration is "strict",
200+
and no DynamoDb Client is provided,
201+
a new DynamoDb Client MUST be created
202+
with the region of the supplied KMS ARN.
203+
204+
If the AWS KMS Configuration is MRDiscovery,
205+
and no DynamoDb Client is provided,
206+
a new DynamoDb Client MUST be created
207+
with the region supplied in MRDiscovery.
208+
209+
If the AWS KMS Configuration is Discovery,
210+
and no DynamoDb Client is provided,
211+
a new DynamoDb Client MUST be created
212+
with the default configuration.
213+
214+
### Keystore [KMS Client](../../framework/branch-key-store.md#kms-client)
215+
216+
If the AWS KMS Configuration is "strict",
217+
and no KMS Client is provided,
218+
a new KMS Client MUST be created
219+
with the region of the supplied KMS ARN.
220+
221+
If the AWS KMS Configuration is MRDiscovery,
222+
and no KMS Client is provided,
223+
a new KMS Client MUST be created
224+
with the region supplied in MRDiscovery.
225+
226+
If the AWS KMS Configuration is Discovery,
227+
and no KMS Client is provided,
228+
a new KMS Client MUST be created
229+
with the default configuration.
230+
231+
### Keystore's [GetKeyStoreInfo](../../framework/branch-key-store.md#getkeystoreinfo)
232+
233+
MUST detail the KMS Configuration.
234+
235+
### Keystore's [CreateKey](../../framework/branch-key-store.md#createkey)
236+
237+
CreateKey MUST immediately fail if the KMS Configuration is NOT KMS Key ARN or KMS MRKey ARN ("strict").
238+
239+
### Keystore's [VersionKey](../../framework/branch-key-store.md#versionkey) MUST
240+
241+
VersionKey MUST immediately fail if the KMS Configuration is NOT KMS Key ARN or KMS MRKey ARN ("strict").
242+
243+
_The following paragraph has already been "logically" added to the Keystore specification as [AWS Key Arn Compatibility](../../framework/branch-key-store.md#aws-key-arn-compatibility)_.
244+
After calling DynamoDB `GetItem` but before authenticating the Keystore item,
245+
if the Keystore's KMS Configuration is `KMS Key ARN`,
246+
the `kms-arn` field of DDB response item MUST equal
247+
the Keystore's configured KMS Key ARN,
248+
or the operation MUST fail.
249+
250+
### Keystore's [AWS KMS Branch Key Decryption](../../framework/branch-key-store.md#aws-kms-branch-key-decryption)
251+
252+
After calling DynamoDB `GetItem`:
253+
If the Keystore's [AWS KMS Configuration](#aws-kms-configuration) is `KMS Key ARN` or `KMS MRKey ARN`,
254+
the `kms-arn` field of the DDB response item MUST be
255+
[compatible with](#aws-key-arn-compatibility) the configured `KMS ARN` in
256+
the [AWS KMS Configuration](#aws-kms-configuration) for this keystore,
257+
or the operation MUST fail.
258+
259+
If the Keystore's [AWS KMS Configuration](#aws-kms-configuration) is `Discovery` or `MRDiscovery`,
260+
the `kms-arn` field of DDB response item MUST NOT be an Alias
261+
or the operation MUST fail.
262+
263+
<!-- "For all Branch Keys created by any version of the MPL, an Alias for kms-arn is impossible." -->
264+
265+
When calling [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html),
266+
the keystore operation MUST call with a request constructed as follows:
267+
268+
- `KeyId` MUST be [compatible with](#aws-key-arn-compatibility) the configured `AWS KMS Key ARN` in the [AWS KMS Configuration](#aws-kms-configuration) for this keystore.
269+
- `KeyId`, if the KMS Configuration is Discovery, MUST be the `kms-arn` attribute value of the AWS DDB response item.
270+
If the KMS Configuration is MRDiscovery, `KeyId` MUST be the `kms-arn` attribute value of the AWS DDB response item, with the region replaced by the configured region.
271+
Otherwise, it MUST BE the Keystore's `KMS ARN`.
272+
- `CiphertextBlob` MUST be the `enc` attribute value on the AWS DDB response item
273+
- `EncryptionContext` MUST be the [encryption context](#encryption-context) constructed above
274+
- `GrantTokens` MUST be this keystore's [grant tokens](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token).

0 commit comments

Comments
 (0)