Skip to content

feat(keystore) Define Branch Key Store read consistency semantics #302

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved."
[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0"

# Define Branch Key Store read consistency semantics

# 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 [branch key store](../../framework/branch-key-store.md) persists branch key versions
in a persistent data store such as a DynamoDb table.

These distributed data stores often offer configurable read consistency,
Copy link
Contributor

Choose a reason for hiding this comment

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

For posterity, this is sometimes referred to as "read after write". Which is the specific kind of consistency we are after here.

allowing customers to choose eventually consistent reads
for optimal cost and performance
if stale results are acceptable for their use-case.

The current specification does not specify when agents should expect
the results of the read operations to reflect the updated state caused by mutation operations.

The current implementation utilizes eventually consistent reads in all current usage.

Consequently, a read operation will not necessarily reflect the latest results
of a mutation operation
even if performed by the same agent in a serialized manner.

This change adds the option to require consistent reads and
clarifies the required consistent read behavior for read operations.

## Detailed Explanation

The Branch Key Store's `GetActiveBranchKey`, `GetBranchKeyVersion`, and `GetBeaconKey` operations
utilize AWS DDB `GetItem` calls which
do not set the `ConsistentRead` flag.

When the `ConsistentRead` flag is unset or `false`,
DynamoDb only provides eventually consistent read guarantees.

This eventually consistent behavior is intentional
in order to optimize performance and cost.

However,
customers may have non-standard situations
which explicitly require consistent reads to be performed.

While key management operations SHOULD occur in control plane operations,
those same control plane operations MAY need to perform encryption operations.

Usage of consistent reads ensures that encryption operations
immediately following the `CreateKey` operation
will be able to find the created keys.

Similarly,
key rotation and re-encryption operations
performed due to key compromise
MAY want use consistent reads to ensure that
the encryption operations utilize the new branch key version.
For this to work local caches would need to be flushed as well.
So this may be prohibitively complicated.

However, trying to pick and chose which read operations need consistent reads
creates sharp edges in complicated customer systems.
So all operations MUST use the same configuration setting.

# Changes

The change is to introduce a new, optional `Require Consistent Reads` option
to the Branch Key Store specification.

This updates:

- The [Branch Key Store's Initialization](../../framework/branch-key-store.md#initialization)
- The [Branch Key Store's GetActiveBranchKey operation](../../framework/branch-key-store.md#getactivebranchkey)
- The [Branch Key Store's GetBranchKeyVersion operation](../../framework/branch-key-store.md#getbranchkeyversion)
- The [Branch Key Store's GetBeaconKey operation](../../framework/branch-key-store.md#getbeaconkey)

This update clarifies the existing behavior in a backwards-compatible manner
while allowing agents to opt-in to consistent reads when needed.
36 changes: 35 additions & 1 deletion framework/branch-key-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

## Version

0.9.0
0.10.0

### Changelog

- 0.10.0
- [Define Branch Key Store read consistency semantics](../changes/2025-07-24_define-branch-key-store-read-consistency-semantics/background.md)
- 0.9.0
- Re-add [Mitigate Version Race Condition in the Branch Key Store](../changes/2025-01-16_key-store-mitigate-update-race/background.md) with DynamoDB as the only branch key storage option
- 0.8.0
Expand Down Expand Up @@ -76,6 +78,7 @@ The following inputs MAY be specified to create a KeyStore:
- [ID](#keystore-id)
- [AWS KMS Grant Tokens](#aws-kms-grant-tokens)
- [DynamoDb Client](#dynamodb-client)
- [Require Consistent Reads](#require-consistent-reads)
- [KMS Client](#kms-client)

The following inputs MUST be specified to create a KeyStore:
Expand Down Expand Up @@ -112,6 +115,20 @@ and no DynamoDb Client is provided,
a new DynamoDb Client MUST be created
with the region configured in the MRDiscovery.

### Require Consistent Reads

Whether read operations are required to perform consistent reads,
ensuring that recent write operations are reflected in their response.

If set to `true`,
read operations MUST return results
which reflect the result of
the most recently executed write operations.

If unset or set to `false`,
read operations MAY return stale results
which are caused by eventual consistency.

### KMS Client

The KMS Client used when wrapping and unwrapping keys.
Expand Down Expand Up @@ -247,6 +264,7 @@ This MUST include:
- [logical Keystore name](#logical-keystore-name)
- [AWS KMS Grant Tokens](#aws-kms-grant-tokens)
- [AWS KMS Configuration](#aws-kms-configuration)
- [Require Consistent Reads](#require-consistent-reads)

### CreateKeyStore

Expand Down Expand Up @@ -436,6 +454,10 @@ VersionKey MUST first get the active version for the branch key from the keystor
by calling AWS DDB `GetItem`
using the `branch-key-id` as the Partition Key and `"branch:ACTIVE"` value as the Sort Key.

The [Require Consistent Reads](#require-consistent-reads) configuration MUST be honored
by setting `ConsistentRead` to `true`
when consistent reads are required.

The `kms-arn` field of DDB response item MUST be [compatible with](#aws-key-arn-compatibility)
the configured `KMS ARN` in the [AWS KMS Configuration](#aws-kms-configuration) for this keystore.

Expand Down Expand Up @@ -527,6 +549,10 @@ To get the active version for the branch key id from the keystore
this operation MUST call AWS DDB `GetItem`
using the `branch-key-id` as the Partition Key and `"branch:ACTIVE"` value as the Sort Key.

The [Require Consistent Reads](#require-consistent-reads) configuration MUST be honored
by setting `ConsistentRead` to `true`
when consistent reads are required.

The AWS DDB response MUST contain the fields defined in the [branch keystore record format](#record-format).
If the record does not contain the defined fields, this operation MUST fail.

Expand All @@ -549,6 +575,10 @@ On invocation, the caller:
To get a branch key from the keystore this operation MUST call AWS DDB `GetItem`
using the `branch-key-id` as the Partition Key and "branch:version:" + `branchKeyVersion` value as the Sort Key.

The [Require Consistent Reads](#require-consistent-reads) configuration MUST be honored
by setting `ConsistentRead` to `true`
when consistent reads are required.

The AWS DDB response MUST contain the fields defined in the [branch keystore record format](#record-format).
If the record does not contain the defined fields, this operation MUST fail.

Expand All @@ -570,6 +600,10 @@ On invocation, the caller:
To get a branch key from the keystore this operation MUST call AWS DDB `GetItem`
using the `branch-key-id` as the Partition Key and "beacon:ACTIVE" value as the Sort Key.

The [Require Consistent Reads](#require-consistent-reads) configuration MUST be honored
by setting `ConsistentRead` to `true`
when consistent reads are required.

The AWS DDB response MUST contain the fields defined in the [branch keystore record format](#record-format).
If the record does not contain the defined fields, this operation MUST fail.

Expand Down