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

feat(KeyStoreAdmin)(WIP): Atomic Mutation #1335

Draft
wants to merge 1 commit into
base: imabhichow/AtomicMutations-WriteAtomicMutation
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
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
datatype ApplyMutationResult =
| ContinueMutation(ContinueMutation: MutationToken)
| CompleteMutation(CompleteMutation: MutationComplete)
datatype AtomicMutationInput = | AtomicMutationInput (
nameonly Identifier: string ,
nameonly Mutations: Mutations ,
nameonly Strategy: Option<KeyManagementStrategy> := Option.None ,
nameonly SystemKey: SystemKey ,
nameonly DoNotVersion: Option<bool> := Option.None
)
datatype AtomicMutationOutput = | AtomicMutationOutput (
nameonly MutatedBranchKeyItems: MutatedBranchKeyItems
)
datatype AwsKmsDecryptEncrypt = | AwsKmsDecryptEncrypt (
nameonly decrypt: Option<AwsCryptographyKeyStoreTypes.AwsKms> := Option.None ,
nameonly encrypt: Option<AwsCryptographyKeyStoreTypes.AwsKms> := Option.None
Expand Down Expand Up @@ -78,12 +88,14 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
InitializeMutation := [];
ApplyMutation := [];
DescribeMutation := [];
AtomicMutation := [];
}
ghost var CreateKey: seq<DafnyCallEvent<CreateKeyInput, Result<CreateKeyOutput, Error>>>
ghost var VersionKey: seq<DafnyCallEvent<VersionKeyInput, Result<VersionKeyOutput, Error>>>
ghost var InitializeMutation: seq<DafnyCallEvent<InitializeMutationInput, Result<InitializeMutationOutput, Error>>>
ghost var ApplyMutation: seq<DafnyCallEvent<ApplyMutationInput, Result<ApplyMutationOutput, Error>>>
ghost var DescribeMutation: seq<DafnyCallEvent<DescribeMutationInput, Result<DescribeMutationOutput, Error>>>
ghost var AtomicMutation: seq<DafnyCallEvent<AtomicMutationInput, Result<AtomicMutationOutput, Error>>>
}
trait {:termination false} IKeyStoreAdminClient
{
Expand Down Expand Up @@ -187,6 +199,21 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
ensures DescribeMutationEnsuresPublicly(input, output)
ensures History.DescribeMutation == old(History.DescribeMutation) + [DafnyCallEvent(input, output)]

predicate AtomicMutationEnsuresPublicly(input: AtomicMutationInput , output: Result<AtomicMutationOutput, Error>)
// The public method to be called by library consumers
method AtomicMutation ( input: AtomicMutationInput )
returns (output: Result<AtomicMutationOutput, Error>)
requires
&& ValidState()
modifies Modifies - {History} ,
History`AtomicMutation
// Dafny will skip type parameters when generating a default decreases clause.
decreases Modifies - {History}
ensures
&& ValidState()
ensures AtomicMutationEnsuresPublicly(input, output)
ensures History.AtomicMutation == old(History.AtomicMutation) + [DafnyCallEvent(input, output)]

}
datatype KeyStoreAdminConfig = | KeyStoreAdminConfig (
nameonly logicalKeyStoreName: string ,
Expand Down Expand Up @@ -481,6 +508,26 @@ abstract module AbstractAwsCryptographyKeyStoreAdminService
History.DescribeMutation := History.DescribeMutation + [DafnyCallEvent(input, output)];
}

predicate AtomicMutationEnsuresPublicly(input: AtomicMutationInput , output: Result<AtomicMutationOutput, Error>)
{Operations.AtomicMutationEnsuresPublicly(input, output)}
// The public method to be called by library consumers
method AtomicMutation ( input: AtomicMutationInput )
returns (output: Result<AtomicMutationOutput, Error>)
requires
&& ValidState()
modifies Modifies - {History} ,
History`AtomicMutation
// Dafny will skip type parameters when generating a default decreases clause.
decreases Modifies - {History}
ensures
&& ValidState()
ensures AtomicMutationEnsuresPublicly(input, output)
ensures History.AtomicMutation == old(History.AtomicMutation) + [DafnyCallEvent(input, output)]
{
output := Operations.AtomicMutation(config, input);
History.AtomicMutation := History.AtomicMutation + [DafnyCallEvent(input, output)];
}

}
}
abstract module AbstractAwsCryptographyKeyStoreAdminOperations {
Expand Down Expand Up @@ -569,4 +616,20 @@ abstract module AbstractAwsCryptographyKeyStoreAdminOperations {
ensures
&& ValidInternalConfig?(config)
ensures DescribeMutationEnsuresPublicly(input, output)


predicate AtomicMutationEnsuresPublicly(input: AtomicMutationInput , output: Result<AtomicMutationOutput, Error>)
// The private method to be refined by the library developer


method AtomicMutation ( config: InternalConfig , input: AtomicMutationInput )
returns (output: Result<AtomicMutationOutput, Error>)
requires
&& ValidInternalConfig?(config)
modifies ModifiesInternalConfig(config)
// Dafny will skip type parameters when generating a default decreases clause.
decreases ModifiesInternalConfig(config)
ensures
&& ValidInternalConfig?(config)
ensures AtomicMutationEnsuresPublicly(input, output)
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ service KeyStoreAdmin {
VersionKey,
InitializeMutation,
ApplyMutation,
DescribeMutation
DescribeMutation,
AtomicMutation
],
errors: [
KeyStoreAdminException,
Expand Down Expand Up @@ -562,6 +563,63 @@ structure DescribeMutationOutput {
MutationInFlight: MutationInFlight
}

// Atomic Mutation
operation AtomicMutation {
input: AtomicMutationInput
output: AtomicMutationOutput
errors: [
KeyStoreAdminException
MutationConflictException
MutationInvalidException
UnexpectedStateException
aws.cryptography.keyStore#VersionRaceException
aws.cryptography.keyStore#KeyStorageException
aws.cryptography.keyStore#BranchKeyCiphertextException
MutationVerificationException
MutationToException
MutationFromException
]
}

structure AtomicMutationInput {
@documentation("The identifier for the Branch Key to be mutated.")
@required
Identifier: String

@documentation("Describes the Mutation that will be applied to all Items of the Branch Key.")
@required
Mutations: Mutations

@documentation("Optional. Defaults to reEncrypt with a default KMS Client.")
Strategy: KeyManagementStrategy

// Smithy's Effective Docuemtnation will utilize System Key's documentation trait
@required
SystemKey: SystemKey

@documentation(
"Optional. Defaults to False, which Versions (or Rotates) the Branch Key,
creating a new Version that has only ever been in the terminal state.
Setting this value to True disables the rotation.
This is a Security vs Performance trade off.
Mutating a Branch Key can change the security domain of the Branch Key.
Some application's Threat Models benefit from ensuring a new Version
is created whenever a Mutation occurs,
allowing the application to track under which security domain data
was protected.
However, not all Threat Models call for this.
Particularly if Mutations are triggered in response to external actors,
creating a new Version for every Mutation request can needlessly grow
the item count of a Branch Key.")
DoNotVersion: Boolean
}

// TODO-Mutation-FF-Atomic: AtomicMutationOutput
structure AtomicMutationOutput {
@required
MutatedBranchKeyItems: MutatedBranchKeyItems
}

// Errors

@error("client")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ module {:options "/functionSyntax:4" } InternalApplyMutation {
return Success(());
}

// TODO-Atomic: Refactor with Atomic Mutation
method QueryForVersionsAndValidate(
input: InternalApplyMutationInput,
mutationToApply: StateStrucs.MutationToApply
Expand Down
Loading