AwsEncryptionSdk.Keyring.AwsKmsMrkDiscovery (AWS Encryption SDK v0.7.0)
View SourceAWS KMS MRK Discovery Keyring implementation.
Combines discovery keyring behavior with Multi-Region Key (MRK) awareness. Enables cross-region decryption of data encrypted with MRK keys without knowing the specific key ARN in advance.
Use Cases
- Cross-region disaster recovery: Decrypt in any region with MRK replicas
- Global applications: Access encrypted data from any region
- Region failover: Transparent failover to replica regions
MRK vs Non-MRK Behavior
| Key Type | Behavior |
|---|---|
| MRK (mrk-*) | Reconstructs ARN with keyring's region, enables cross-region |
| Non-MRK | Only decrypts if key is in same region as keyring |
Example: MRK Cross-Region
Data encrypted with arn:aws:kms:us-east-1:123:key/mrk-abc can be decrypted
by a keyring configured for us-west-2 because:
- Keyring detects MRK key ID (mrk-abc)
- Reconstructs ARN:
arn:aws:kms:us-west-2:123:key/mrk-abc - Calls KMS Decrypt in us-west-2 using the regional replica
Operations
Encryption
MRK Discovery keyrings cannot encrypt. wrap_key/2 always returns
{:error, :discovery_keyring_cannot_encrypt}.
Decryption (unwrap_key)
- Filters EDKs by provider ID "aws-kms"
- Validates ARN format and applies discovery filter
- For MRK keys: reconstructs ARN with configured region
- For non-MRK keys: only proceeds if regions match
- Calls KMS Decrypt with the (possibly reconstructed) ARN
Required Parameters
Unlike standard discovery keyring, MRK discovery requires a region:
| Parameter | Description |
|---|---|
kms_client | KMS client for API calls |
region | AWS region for MRK ARN reconstruction |
IAM Permissions Required
The principal needs kms:Decrypt on both the original key AND any
MRK replicas that might be used:
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": [
"arn:aws:kms:us-east-1:123456789012:key/mrk-*",
"arn:aws:kms:us-west-2:123456789012:key/mrk-*"
]
}Examples
Basic MRK Discovery
alias AwsEncryptionSdk.Keyring.AwsKmsMrkDiscovery
alias AwsEncryptionSdk.Keyring.KmsClient.ExAws
alias AwsEncryptionSdk.Cmm.Default
alias AwsEncryptionSdk.Client
# Create MRK discovery keyring for us-west-2
{:ok, kms_client} = ExAws.new(region: "us-west-2")
{:ok, keyring} = AwsKmsMrkDiscovery.new(kms_client, "us-west-2")
# Create client
cmm = Default.new(keyring)
client = Client.new(cmm)
# Decrypt data encrypted in ANY region with an MRK
{:ok, {plaintext, context}} = Client.decrypt(client, ciphertext)With Discovery Filter
{:ok, keyring} = AwsKmsMrkDiscovery.new(kms_client, "us-west-2",
discovery_filter: %{
partition: "aws",
accounts: ["123456789012"]
}
)Cross-Region Decryption Setup
# Data was encrypted in us-east-1 with:
# arn:aws:kms:us-east-1:123:key/mrk-abc
# Decrypt in us-west-2 (DR region)
{:ok, west_client} = ExAws.new(region: "us-west-2")
{:ok, keyring} = AwsKmsMrkDiscovery.new(west_client, "us-west-2",
discovery_filter: %{partition: "aws", accounts: ["123456789012"]}
)
# This works because mrk-abc has a replica in us-west-2
{:ok, {plaintext, _}} = Client.decrypt(Client.new(Default.new(keyring)), ciphertext)Spec Reference
Summary
Functions
Creates a new AWS KMS MRK Discovery Keyring.
Unwraps a data key using AWS KMS MRK Discovery.
MRK Discovery keyrings cannot encrypt - this always fails.
Types
Functions
Creates a new AWS KMS MRK Discovery Keyring.
Parameters
kms_client- KMS client struct implementing KmsClient behaviourregion- AWS region string for this keyring (e.g., "us-west-2")opts- Optional keyword list::discovery_filter- Map with:partition(string) and:accounts(list of strings):grant_tokens- List of grant tokens for KMS API calls
Returns
{:ok, keyring}on success{:error, reason}on validation failure
Examples
{:ok, client} = KmsClient.Mock.new(%{})
{:ok, keyring} = AwsKmsMrkDiscovery.new(client, "us-west-2")
# With discovery filter
{:ok, keyring} = AwsKmsMrkDiscovery.new(client, "us-west-2",
discovery_filter: %{partition: "aws", accounts: ["123456789012"]}
)
@spec unwrap_key(t(), AwsEncryptionSdk.Materials.DecryptionMaterials.t(), [ AwsEncryptionSdk.Materials.EncryptedDataKey.t() ]) :: {:ok, AwsEncryptionSdk.Materials.DecryptionMaterials.t()} | {:error, term()}
Unwraps a data key using AWS KMS MRK Discovery.
For MRK EDKs, reconstructs the ARN with the keyring's configured region before calling KMS Decrypt, enabling cross-region decryption.
For non-MRK EDKs, filters out any where the region doesn't match.
Returns
{:ok, materials}- Data key successfully decrypted{:error, :plaintext_data_key_already_set}- Materials already have key{:error, {:unable_to_decrypt_any_data_key, errors}}- All decryption attempts failed
Examples
{:ok, result} = AwsKmsMrkDiscovery.unwrap_key(keyring, materials, edks)
@spec wrap_key(t(), AwsEncryptionSdk.Materials.EncryptionMaterials.t()) :: {:error, :discovery_keyring_cannot_encrypt}
MRK Discovery keyrings cannot encrypt - this always fails.
Returns
Always returns {:error, :discovery_keyring_cannot_encrypt}