-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: Key Store Admin #282
base: master
Are you sure you want to change the base?
Changes from all commits
6894364
bbd4b8e
c1cf829
ac838b3
0e732d9
7be75ac
af1bccf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." | ||
[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" | ||
|
||
# Key Store Administration Client & Configuration | ||
|
||
# Definitions | ||
|
||
## Conventions used in this document | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be | ||
interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). | ||
|
||
# Background | ||
|
||
The parameters needed to fetch Branch Keys for usage (encrypt, decrypt) | ||
are distinct from the parameters needed to administrate them | ||
(create, version/rotate, any future operations). | ||
|
||
The permissions needed for the persistence medium, | ||
which is DynamoDB by default, | ||
and to Key Management Service, | ||
which currently can only be AWS KMS, | ||
are also different between usage and administration activities. | ||
|
||
As such, it makes sense to create a | ||
new Branch Key Store Administration Client, | ||
that cannot facilitate usage, | ||
only administrative operations. | ||
|
||
## Alternatives to a new Client/Local Service? | ||
|
||
### Refactor Key Store | ||
|
||
Rather than creating a new Client/Local Service, | ||
Crypto Tools could refactor the existing | ||
Key Store Client to behave in the manner described below. | ||
|
||
This would be a breaking change, | ||
and is therefore not recommended. | ||
|
||
### Static Methods on the MPL | ||
|
||
A non-breaking change is to add the behaviors | ||
described below to the Material Provider's Local Service/Client, | ||
rather than creating a new Client. | ||
|
||
The advantage of such an approach is less software | ||
maintained and documented by Crypto Tools. | ||
|
||
However, | ||
this approach forces the Material Provider's Client | ||
to directly reference DynamoDB. | ||
texastony marked this conversation as resolved.
Show resolved
Hide resolved
|
||
In the long run, | ||
Crypto Tools MAY want allow MPL Consumers to optionally | ||
depend on the AWS SDK, | ||
as the original AWS Encryption SDK afforded that. | ||
Adding a direct reference to DynamoDB | ||
to the Material Provider's Client | ||
complicates such an ambition. | ||
|
||
# Name of the Client? | ||
|
||
It is best that we bike shed on this early. | ||
|
||
The proposed name for this client is | ||
`the Key Store Admin Client` | ||
though we may often refer to it as | ||
just the `Key Store Admin`. | ||
|
||
# Proposed Construction | ||
|
||
The Key Store Admin requires the following arguments: | ||
|
||
- Storage Reference | ||
- Logical Key Store Name | ||
|
||
See [Key Store Persistence Changes](changes/2024-6-17_key-store-persistance/background.md) for details | ||
on Storage Reference. | ||
|
||
# Common Parameters and their defaults | ||
|
||
## `KMS Identifier` | ||
|
||
`KMS Identifier` is a KMS ARN which identifies the KMS Key | ||
that will be used for the operation. | ||
This ARN MUST NOT be an Alias. | ||
This ARN MUST be a valid | ||
[AWS KMS Key ARN](./aws-kms/aws-kms-key-arn.md#a-valid-aws-kms-arn). | ||
This ARN MAY be a Multi-Region Key (MRK) or Single Region Key. | ||
|
||
## Key Management | ||
texastony marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
`Key Management` is a union, | ||
such that additional options may be added at a later date. | ||
|
||
Members of `Key Management` are elements that | ||
authorize the use of Branch Key Cryptographic Materials | ||
by decrypting them in a manner that | ||
authenticates all attributes of the Branch Key. | ||
|
||
They are also used to create Branch Key Encrypted Cryptographic Materials, | ||
and when doing so MUST cryptographically bind all attributes of the Branch Key | ||
to the cipher-text. | ||
|
||
Currently, there is only one `Key Management` option. | ||
|
||
`Key Management` is never used directly by the Key Store Admin. | ||
|
||
However, it was introduced into the Key Store | ||
as part of the [Key Store Persistence Changes](changes/2024-6-17_key-store-persistance/background.md). | ||
It is, at least at this time, | ||
not visible to any MPL Consumer facing operations. | ||
|
||
### `AwsKms` | ||
|
||
`AwsKms` is the only `Key Management` option currently | ||
supported by the Key Store or Key Store Admin. | ||
|
||
This option is provided by default, | ||
if no other `Key Management` is provided. | ||
|
||
`AwsKms` represents AWS Key Management Service (KMS). | ||
|
||
The structure has two optional fields: | ||
|
||
- `grantTokenList`, a list of strings | ||
- `kmsClient`, a reference to an AWS SDK KMS client | ||
|
||
If no `grantTokenList` is provided, | ||
it defaults to an empty list. | ||
|
||
If no `kmsClient` is provided, | ||
the default KMS client is constructed via the AWS SDK. | ||
|
||
## Key Management Strategy | ||
|
||
`Key Management Strategy` is a union, | ||
such that additional options may be added at a later date. | ||
|
||
`Key Management Strategy` determines which Operations | ||
of a `Key Management` are used by the Client. | ||
|
||
For example, | ||
an MPL Consumer MAY want to avoid calling `kms:ReEncrypt`, | ||
and would rather use `kms:Decrypt` followed by `kms:Encrypt` | ||
texastony marked this conversation as resolved.
Show resolved
Hide resolved
|
||
to re-wrap a new DECRYPT_ONLY Branch Key as a ACTIVE Branch Key. | ||
|
||
At this time, | ||
there are only two | ||
`Key Management Strategy`s. | ||
|
||
### AWS KMS ReEncrypt (default) | ||
|
||
`AwsKmsReEncrypt` dictates the Key Store Operation use | ||
AWS KMS' ReEncrypt Operation to | ||
[authenticate a Key Store Item](../../framework/branch-key-store.md#authenticating-a-keystore-item) | ||
or re-wrap Branch Keys | ||
during [Wrapped Branch Key Creation](../../framework/branch-key-store.md#wrapped-branch-key-creation). | ||
|
||
`AwsKmsReEncrypt` is a structure that holds a `AwsKms`, | ||
which MAY contain the KMS Client | ||
or Grant Tokens the Key Store, | ||
if they are set, | ||
will use when calling KMS. | ||
|
||
`AwsKmsReEncrypt` is the default option if | ||
`Key Management Strategy` is marked as optional | ||
and the parameter is unfilled. | ||
|
||
### AWS KMS Decrypt Encrypt | ||
|
||
`AwsKmsDecryptEncrypt` dictates the Key Store Operation to use | ||
AWS KMS' Decrypt Operation followed by AWS KMS Encrypt Operation | ||
to re-wrap Branch Keys | ||
during [Wrapped Branch Key Creation](../../framework/branch-key-store.md#wrapped-branch-key-creation). | ||
|
||
`AwsKmsDecryptEncrypt` is a structure that holds two `AwsKms`, | ||
one designated for Decrypt, | ||
one designated for Encrypt. | ||
|
||
This allows MPL Consumers to configure different | ||
credentials or request headers for the KMS Operations. | ||
|
||
# Modified Operations from the original [Branch Key Store Specification](../../framework/branch-key-store.md#operations) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any reason why the mutation operations are not part of this Key Store Admin? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What Mutation Operations? ;) |
||
|
||
## CreateKey | ||
|
||
The CreateKey caller MUST provide: | ||
|
||
- A `KMS Identifier` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we abstract this away, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... this could be |
||
|
||
The CreateKey caller MAY provide: | ||
|
||
- A Branch Key ID | ||
- Encryption Context | ||
- A Key Management Strategy | ||
|
||
The behavior is mostly identical. | ||
|
||
However, | ||
during the [Wrapped Branch Key Creation](../../framework/branch-key-store.md#wrapped-branch-key-creation), | ||
the Key Management Strategy MUST be respected. | ||
|
||
## Version Key | ||
|
||
The VersionKey caller MUST provide: | ||
|
||
- A `KMS Identifier` | ||
- A `branch-key-id` | ||
|
||
The VersionKey caller MAY provide: | ||
|
||
- A Key Management Strategy | ||
|
||
The behavior is mostly identical. | ||
|
||
However, | ||
during the [Wrapped Branch Key Creation](../../framework/branch-key-store.md#wrapped-branch-key-creation), | ||
the Key Management Strategy MUST be respected. | ||
|
||
<!-- LocalWords: MRK AwsKms grantTokenList kmsClient ReEncrypt --> | ||
<!-- LocalWords: AwsKmsReEncrypt keystore AwsKmsDecryptEncrypt --> | ||
<!-- LocalWords: Admin ReEncrypt --> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this going? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed in meeting. |
||
// SPDX-License-Identifier: Apache-2.0 | ||
namespace aws.cryptography.keyStoreAdmin | ||
|
||
// The top level namespace for this project. | ||
// Contains an entry-point for helper methods, | ||
// and common structures used throughout this project. | ||
|
||
use aws.polymorph#localService | ||
|
||
use com.amazonaws.dynamodb#DynamoDB_20120810 | ||
use com.amazonaws.kms#TrentService | ||
|
||
use aws.cryptography.keyStore#EncryptionContext | ||
|
||
@localService( | ||
sdkId: "KeyStoreAdmin", | ||
config: KeyStoreAdminConfig, | ||
dependencies: [ | ||
DynamoDB_20120810, | ||
TrentService | ||
] | ||
) | ||
service KeyStoreAdmin { | ||
version: "2023-04-01", | ||
operations: [ | ||
CreateKey | ||
VersionKey | ||
], | ||
errors: [ | ||
KeyStoreAdminException | ||
aws.cryptography.keyStore#VersionRaceException | ||
] | ||
} | ||
|
||
structure KeyStoreAdminConfig { | ||
@required | ||
@documentation( | ||
"The logical name for this Key Store, | ||
which is cryptographically bound to the keys it holds. | ||
This appears in the Encryption Context of KMS requests as `tablename`. | ||
|
||
There SHOULD be a one to one mapping between the Storage's physical name, | ||
i.e: DynamoDB Table Names, | ||
and the Logical KeyStore Name. | ||
This value can be set to the DynamoDB table name itself | ||
(Storage's physical name), | ||
but does not need to. | ||
|
||
Controlling this value independently enables restoring from DDB table backups | ||
even when the table name after restoration is not exactly the same.") | ||
logicalKeyStoreName: String, | ||
|
||
@required | ||
@documentation("The storage configuration for this Key Store.") | ||
storage: aws.cryptography.keyStore#Storage | ||
} | ||
|
||
// KMS Arn validation MUST occur in Dafny | ||
union KMSIdentifier { | ||
@documentation( | ||
"Key Store is restricted to only this KMS Key ARN. | ||
If a different KMS Key ARN is encountered | ||
when creating, versioning, or getting a Branch Key or Beacon Key, | ||
KMS is never called and an exception is thrown. | ||
While a Multi-Region Key (MKR) may be provided, | ||
the whole ARN, including the Region, | ||
is persisted in Branch Keys and | ||
MUST strictly equal this value to be considered valid.") | ||
kmsKeyArn: String, | ||
|
||
@documentation( | ||
"If an MRK ARN is provided, | ||
and the persisted Branch Key holds an MRK ARN, | ||
then those two ARNs may differ in region, | ||
although they must be otherwise equal. | ||
If either ARN is not an MRK ARN, then | ||
kmsMRKeyArn behaves exactly as kmsKeyArn.") | ||
kmsMRKeyArn: String, | ||
} | ||
|
||
structure AwsKmsDecryptEncrypt { | ||
@documentation("The KMS Client (and Grant Tokens) used to Decrypt Branch Key Store Items.") | ||
decrypt: aws.cryptography.keyStore#AwsKms | ||
@documentation( | ||
"The KMS Client (and Grant Tokens) used to Encrypt Branch Key Store Items | ||
and to Generate new Cryptographic Material.") | ||
encrypt: aws.cryptography.keyStore#AwsKms | ||
} | ||
|
||
@documentation( | ||
"This configures which Key Management Operations will be used | ||
AND the Key Management Clients (and Grant Tokens) used to invoke those Operations.") | ||
union KeyManagementStrategy { | ||
@documentation( | ||
"Key Store Items are authenicated and re-wrapped via KMS ReEncrypt, | ||
executed with the provided Grant Tokens and KMS Client. | ||
This is one request to Key Management, as compared to two. | ||
But only one set of credentials can be used.") | ||
AwsKmsReEncrypt: aws.cryptography.keyStore#AwsKms | ||
@documentation( | ||
"Key Store Items are authenicated and re-wrapped via a Decrypt and then Encrypt request. | ||
This is two separate requests to Key Management, as compared to one. | ||
But the Decrypt requests will use the Decrypt KMS Client (and Grant Tokens), | ||
while the Encrypt requests will use the Encrypt KMS Client (and Grant Tokens). | ||
This option affords for different credentials to be utilized, | ||
based on the operation. | ||
When Generating new material, | ||
KMS GenerateDataKeyWithoutPlaintext will be executed against | ||
the Encrypt option.") | ||
AwsKmsDecryptEncrypt: AwsKmsDecryptEncrypt | ||
} | ||
|
||
@documentation( | ||
"Create a new Branch Key in the Key Store. | ||
Additionally create a Beacon Key that is tied to this Branch Key.") | ||
operation CreateKey { | ||
input: CreateKeyInput, | ||
output: CreateKeyOutput | ||
} | ||
|
||
structure CreateKeyInput { | ||
@documentation("The identifier for the created Branch Key.") | ||
branchKeyIdentifier: String, | ||
|
||
@documentation( | ||
"Custom encryption context for the Branch Key. | ||
Required if branchKeyIdentifier is set.") | ||
encryptionContext: aws.cryptography.keyStore#EncryptionContext | ||
|
||
@required | ||
@documentation( | ||
"Multi-Region or Single Region AWS KMS Key | ||
used to protect the Branch Key, but not aliases!") | ||
kmsArn: KMSIdentifier | ||
|
||
strategy: KeyManagementStrategy | ||
} | ||
|
||
structure CreateKeyOutput { | ||
@required | ||
@documentation("A identifier for the created Branch Key.") | ||
branchKeyIdentifier: String | ||
} | ||
|
||
@documentation( | ||
"Create a new ACTIVE version of an existing Branch Key, | ||
along with a complementing Version (DECRYT_ONLY) in the Key Store. | ||
This generates a fresh AES-256 key which all future encrypts will use | ||
for the Key Derivation Function, | ||
until VersionKey is executed again.") | ||
operation VersionKey { | ||
input: VersionKeyInput, | ||
output: VersionKeyOutput, | ||
errors: [aws.cryptography.keyStore#VersionRaceException] | ||
} | ||
|
||
structure VersionKeyInput { | ||
@required | ||
@documentation("The identifier for the Branch Key to be versioned.") | ||
branchKeyIdentifier: String | ||
|
||
@required | ||
@documentation("Multi-Region or Single Region AWS KMS Key used to protect the Branch Key, but not aliases!") | ||
kmsArn: KMSIdentifier | ||
|
||
strategy: KeyManagementStrategy | ||
} | ||
|
||
structure VersionKeyOutput { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we're adding new API operations,
then it isn't necessarily a breaking change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like there are better reasons why it makes sense to have separate Admin vs. Cryptography/Dataplane/whatever,
for the sake of allowing customers to more easily enable separation of permissions between the two.