Guide · AWS KMS · Multi-Region Keys

AWS KMS Multi-Region Keys for MCP Servers — Cross-Region Decrypt, DR Failover

AWS KMS multi-region keys (MRKs) are a set of KMS keys in different AWS regions that share the same key material and key ID suffix — a ciphertext envelope encrypted with the primary key in us-east-1 can be decrypted by a replica key in eu-west-1 without sending the ciphertext across regions and without a cross-region KMS API call, because both keys are cryptographically identical. For MCP servers this matters in two specific scenarios: (1) global active-active deployments where a user in Europe cannot afford the 100–150ms round-trip to a KMS endpoint in us-east-1, and (2) disaster recovery where the primary region becomes unavailable and an encrypted database replica in the secondary region must be readable. For all other cases, single-region keys with cross-region replication of encrypted data are simpler and cheaper.

TL;DR

Create a multi-region primary key with --multi-region, replicate it to secondary regions with replicate-key, and point each region's MCP server deployment at its local replica. For DR failover use update-primary-region to promote a replica. Each region's key costs $1/month independently. See the KMS overview for single-region key basics, the envelope encryption guide for the ciphertext portability mechanics, the key policies guide for per-region policy management, and the CloudTrail monitoring guide for cross-region event aggregation.

Multi-region key concepts

A multi-region key family consists of one primary key and one or more replica keys. All keys in the family share the same key material, meaning a ciphertext produced by any key in the family can be decrypted by any other key in the family. The key ID suffix (mrk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) is identical across all replicas; the ARN differs only in the region segment.

PropertySingle-region keyMulti-region key
Key ID formatabc12345-1234-1234-1234-abcdef123456mrk-abc123def456... (32 hex chars after "mrk-")
Key ARNarn:aws:kms:us-east-1:123456789012:key/abc12345-...arn:aws:kms:us-east-1:123456789012:key/mrk-abc123...
Cross-region decryptNot possible — ciphertext can only be decrypted in the region where the key existsPossible — replica in eu-west-1 can decrypt ciphertext made by primary in us-east-1
Key rotationAutomatic annual or on-demandManual only (create new MRK, migrate; automatic rotation not supported on MRKs)
Pricing$1/month per key$1/month per key per region ($1 primary + $1 per replica)
Key policySingle policy per keyIndependent policy per region — each replica has its own key policy

The critical distinction: multi-region keys share key material, not key policies. You must configure access control independently in each region. If you add a new IAM role to the key policy in us-east-1, the eu-west-1 replica's policy is unchanged — you must run PutKeyPolicy separately in each region where that role needs access.

Create a primary MRK and replicate to secondary regions

# Create a multi-region primary key in us-east-1
aws kms create-key \
  --description "MCP server multi-region secrets key" \
  --key-usage ENCRYPT_DECRYPT \
  --key-spec SYMMETRIC_DEFAULT \
  --multi-region \
  --region us-east-1 \
  --tags TagKey=Service,TagValue=mcp-server TagKey=MultiRegion,TagValue=true \
  --policy file://key-policy.json
# Output includes:
#   KeyMetadata.KeyId: "mrk-1234abcd5678efgh9012ijkl3456mnop"
#   KeyMetadata.MultiRegion: true
#   KeyMetadata.MultiRegionConfiguration.MultiRegionKeyType: "PRIMARY"
#   KeyMetadata.MultiRegionConfiguration.PrimaryKey.Arn: "arn:aws:kms:us-east-1:123456789012:key/mrk-..."
#   KeyMetadata.MultiRegionConfiguration.ReplicaKeys: [] (none yet)

PRIMARY_KEY_ARN="arn:aws:kms:us-east-1:123456789012:key/mrk-1234abcd5678efgh9012ijkl3456mnop"

# Create aliases in primary region
aws kms create-alias \
  --alias-name alias/mcp-server-mrk-prod \
  --target-key-id $PRIMARY_KEY_ARN \
  --region us-east-1

# Replicate the primary key to eu-west-1
# This copies key material; not possible to replicate existing single-region key
aws kms replicate-key \
  --key-id $PRIMARY_KEY_ARN \
  --replica-region eu-west-1 \
  --description "MCP server MRK replica — eu-west-1" \
  --tags TagKey=Service,TagValue=mcp-server TagKey=MultiRegion,TagValue=true \
  --policy file://key-policy.json
# Replication takes ~30 seconds; check status:
aws kms describe-key \
  --key-id $PRIMARY_KEY_ARN \
  --region us-east-1 \
  --query 'KeyMetadata.MultiRegionConfiguration.ReplicaKeys'

# Create alias in the replica region
REPLICA_KEY_ARN="arn:aws:kms:eu-west-1:123456789012:key/mrk-1234abcd5678efgh9012ijkl3456mnop"
aws kms create-alias \
  --alias-name alias/mcp-server-mrk-prod \
  --target-key-id $REPLICA_KEY_ARN \
  --region eu-west-1

# Replicate to ap-southeast-1 as well (same command, different --replica-region)
aws kms replicate-key \
  --key-id $PRIMARY_KEY_ARN \
  --replica-region ap-southeast-1 \
  --policy file://key-policy.json

Note that both the primary and all replicas share the same alias name (alias/mcp-server-mrk-prod) in their respective regions. This allows application code to always use alias/mcp-server-mrk-prod regardless of which region it is running in — the same alias name resolves to the local region's key. If you replicate to a new region later, create the alias in that region before deploying the application.

Cross-region ciphertext portability

The key feature of MRKs is that ciphertext produced in one region is decryptable in another without any re-encryption step. The KMS ciphertext format embeds the key ID (not the full ARN including region) in the ciphertext metadata — when a replica in eu-west-1 receives a ciphertext that references key ID mrk-1234abcd..., it recognizes this as a key it manages and decrypts it successfully.

// MCP server example: encrypt in us-east-1 (e.g., data written by US users)
// and decrypt in eu-west-1 (e.g., same data read by EU users, zero cross-region KMS latency)

// Write path — application running in us-east-1
const kmsUS = new KMSClient({ region: 'us-east-1' });
const { Plaintext, CiphertextBlob } = await kmsUS.send(new GenerateDataKeyCommand({
  KeyId: 'alias/mcp-server-mrk-prod', // resolves to primary key in us-east-1
  KeySpec: 'AES_256',
  EncryptionContext: { tenantId: 'tenant-abc', env: 'production' },
}));
// ... encrypt payload locally, store encryptedPayload + CiphertextBlob in database

// Read path — same application running in eu-west-1 (database replica)
const kmsEU = new KMSClient({ region: 'eu-west-1' });
const { Plaintext: dataKey } = await kmsEU.send(new DecryptCommand({
  CiphertextBlob: storedCiphertextBlob, // blob produced by us-east-1 primary key
  EncryptionContext: { tenantId: 'tenant-abc', env: 'production' },
  // No KeyId needed — KMS extracts key ID from ciphertext blob metadata
  // KMS matches mrk-1234abcd... to the eu-west-1 replica automatically
}));
// ... decrypt payload locally with recovered data key

This portability is not available with single-region keys — a ciphertext encrypted with a us-east-1 single-region key cannot be decrypted in eu-west-1 even if an identical key policy exists there, because there is no shared key material. The only workaround with single-region keys is to call ReEncrypt via the source region, which requires a network round-trip and the source region to be available.

DR failover with update-primary-region

If the primary region (us-east-1) becomes unavailable due to an AWS regional outage, existing replicas can continue to serve Decrypt operations independently — they do not depend on the primary for day-to-day cryptographic work. The primary designation only affects which region can run management operations (CreateGrant, PutKeyPolicy on all replicas simultaneously). For cryptographic operations, a replica works the same as the primary.

# Promote eu-west-1 replica to primary during a DR scenario
# Run this command from the REPLICA region you want to promote
aws kms update-primary-region \
  --key-id mrk-1234abcd5678efgh9012ijkl3456mnop \
  --primary-region eu-west-1 \
  --region eu-west-1
# The old primary (us-east-1) becomes a replica
# The eu-west-1 replica becomes the new primary
# This operation can be run from any active replica region

# After failover: verify new primary configuration
aws kms describe-key \
  --key-id mrk-1234abcd5678efgh9012ijkl3456mnop \
  --region eu-west-1 \
  --query 'KeyMetadata.MultiRegionConfiguration'

# After the original primary region recovers, it will show as a replica:
aws kms describe-key \
  --key-id mrk-1234abcd5678efgh9012ijkl3456mnop \
  --region us-east-1 \
  --query 'KeyMetadata.MultiRegionConfiguration.MultiRegionKeyType'
# Output: "REPLICA" (was PRIMARY before the failover)

Important: update-primary-region does not affect the key material or the ability of any region to process Decrypt calls — it only changes which key is the administrative "source of truth". During a full regional outage of us-east-1, your eu-west-1 MCP server deployment continues to decrypt data transparently. The update-primary-region call is needed if you want to run management operations (add a new replica, rotate key material) from a different region during the outage.

Rotation for multi-region keys

Automatic key rotation is not supported for multi-region keys. This is intentional — rotating key material on a primary would need to synchronize new material to all replicas atomically, which KMS cannot guarantee across regions. The correct rotation approach for MRKs is a manual process of creating a new MRK, migrating ciphertext with ReEncrypt, and eventually deleting the old MRK family.

# Manual MRK rotation process
# Step 1: Create a new MRK family (new key material)
aws kms create-key \
  --description "MCP server MRK v2 (rotation from v1)" \
  --key-usage ENCRYPT_DECRYPT \
  --key-spec SYMMETRIC_DEFAULT \
  --multi-region \
  --region us-east-1
NEW_MRK_ID="mrk-newkey..."

# Step 2: Replicate new key to all regions where old key had replicas
aws kms replicate-key --key-id $NEW_MRK_ID --replica-region eu-west-1
aws kms replicate-key --key-id $NEW_MRK_ID --replica-region ap-southeast-1

# Step 3: Update alias to point to new key in each region
aws kms update-alias --alias-name alias/mcp-server-mrk-prod --target-key-id $NEW_MRK_ID --region us-east-1
aws kms update-alias --alias-name alias/mcp-server-mrk-prod --target-key-id mrk-newkey-eu --region eu-west-1
aws kms update-alias --alias-name alias/mcp-server-mrk-prod --target-key-id mrk-newkey-ap --region ap-southeast-1

# Step 4: Run ReEncrypt on existing data key blobs to wrap them under the new MRK
# (do this in batches; existing blobs still decryptable by old key during transition)
aws kms re-encrypt \
  --ciphertext-blob fileb://old-data-key-blob.bin \
  --destination-key-id alias/mcp-server-mrk-prod \
  --destination-encryption-context '{"tenantId":"abc","env":"production"}'

# Step 5: After all blobs migrated, schedule deletion of old MRK primary
# (must delete all replicas first — cannot delete a primary while replicas exist)
aws kms schedule-key-deletion --key-id $OLD_MRK_ID --region eu-west-1 --pending-window-in-days 30
aws kms schedule-key-deletion --key-id $OLD_MRK_ID --region ap-southeast-1 --pending-window-in-days 30
aws kms schedule-key-deletion --key-id $OLD_MRK_ID --region us-east-1 --pending-window-in-days 30

Failure modes reference

FailureSymptomFix
Replica not yet available after replicate-keyDecrypt in eu-west-1 fails with NotFoundException seconds after replicate-key returnsReplication takes ~30 seconds; poll describe-key in the replica region until KeyState = Enabled; add retry logic in deployment scripts with exponential backoff
AccessDeniedException in replica regionDecrypt succeeds in us-east-1 primary but fails in eu-west-1 replicaKey policies are NOT replicated — each replica has an independent policy; run PutKeyPolicy in eu-west-1 with the same policy that works in us-east-1
enable-key-rotation returns UnsupportedOperationException on MRKAttempting automatic rotation on MRK failsAutomatic rotation not supported on MRKs; use manual rotation process (create new MRK, ReEncrypt existing blobs, update alias, delete old MRK)
Cannot delete primary while replicas existschedule-key-deletion on primary returns MRKInvalidStateExceptionDelete all replica keys first (in each replica region), wait for deletion to complete, then schedule primary deletion
update-primary-region fails during DRAttempting to promote eu-west-1 during us-east-1 outage fails with error referencing primary regionupdate-primary-region requires the current primary region to be reachable; if it is unavailable, the replicas still process Decrypt independently — defer promotion until primary recovers, or escalate to AWS support
Ciphertext from single-region key rejected in other regionDecrypt fails in eu-west-1 with InvalidCiphertextException for blobs encrypted with a non-MRKSingle-region key ciphertext cannot cross regions; MRK ciphertext portability only works within the same MRK family; must re-encrypt using source region KMS, not replica
Alias not created in replica regionApplication code using alias/mcp-server-mrk-prod fails in eu-west-1 with NotFoundExceptionAliases are not replicated; create alias in each replica region explicitly after replication; automation: iterate all regions where replica exists and create alias in each