Skip to content
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

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions changes/2024-TBD_key-store-admin/background.md
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,
Copy link
Contributor

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

Copy link
Contributor

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.

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)
Copy link
Contributor

Choose a reason for hiding this comment

The 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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What Mutation Operations? ;)


## CreateKey

The CreateKey caller MUST provide:

- A `KMS Identifier`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we abstract this away,
in case the Key Management is not KMS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... this could be Key Identifier... we can come back to this before we GA.


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 -->
171 changes: 171 additions & 0 deletions changes/2024-TBD_key-store-admin/proposed.smithy
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this going?
Is it a new MPL subproject? i.e. <MPL root>/KeyStoreAdmin
Or is it a new localService inside the MPL-Core subproject? i.e. <MPL root>/AwsCryptographicMaterialProviders/KeyStoreAdmin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed in meeting.
New Local Service of the MPL, alongside the Key Store.

// 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 {
}
Loading
Loading