Skip to content
Back to main site

AWS KMS

Create key and alias records and exercise encryption and key-state API flows without real cryptography.

Plan: Free54 of 54 operations implemented5Known differences

Cryptography isn't real: ciphertext contains recoverable plaintext and the tested RSA output is not interoperable key material.

Example checked on Vera 1.2.2, 8 November 2026. Each coverage note names its own evidence and date.

This Free service needs no license key. Start Vera as in Get started, then run this in a terminal of its own, from an empty scratch directory. It gives the official AWS CLI dummy credentials and a config file of its own, so no AWS account is needed and your own AWS profile isn't touched.

Terminal window
export VERA_ENDPOINT="http://localhost:5003"
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test
export AWS_REGION=us-east-1 AWS_DEFAULT_REGION=us-east-1
export AWS_SHARED_CREDENTIALS_FILE=/dev/null
export AWS_EC2_METADATA_DISABLED=true
export AWS_PAGER="" AWS_CLI_AUTO_PROMPT=off
unset AWS_PROFILE AWS_DEFAULT_PROFILE
unset AWS_SESSION_TOKEN AWS_SECURITY_TOKEN
unset AWS_WEB_IDENTITY_TOKEN_FILE AWS_ROLE_ARN AWS_ROLE_SESSION_NAME
unset AWS_CONTAINER_CREDENTIALS_FULL_URI
unset AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
cat > vera-aws-config <<'EOF'
[default]
region = us-east-1
output = json
cli_binary_format = base64
s3 =
addressing_style = path
EOF
export AWS_CONFIG_FILE="$PWD/vera-aws-config"

When you've finished every example in this terminal, close it and delete vera-aws-config, not before.

The emulator serves KMS’s 2014-11-01 API over the AWS JSON protocol, through the AWS CLI’s kms commands. Key ARNs name the account configured on your Vera instance and the request’s region, such as arn:aws:kms:us-east-1:123456789012:key/77f42ffe-fc34-4bfa-81fc-b126c452ee9a.

Binary values are base64 both ways. The setup’s config sets cli_binary_format = base64, so --plaintext takes base64 text, and blob fields in responses, such as CiphertextBlob and Plaintext, come back as base64.

Create a key with an alias, and look it up by the alias:

Terminal window
KEY_ID=$(aws --endpoint-url "$VERA_ENDPOINT" kms create-key \
--description "Documentation example key" \
--tags '[{"TagKey":"purpose","TagValue":"documentation"}]' \
--query KeyMetadata.KeyId --output text)
aws --endpoint-url "$VERA_ENDPOINT" kms create-alias \
--alias-name alias/docs-example-key --target-key-id "$KEY_ID"
aws --endpoint-url "$VERA_ENDPOINT" kms describe-key --key-id alias/docs-example-key

The alias resolves to the new key, an enabled symmetric key. These are the main fields; the key ID differs on every run:

Output (selected fields)
{
"KeyMetadata": {
"KeyId": "77f42ffe-fc34-4bfa-81fc-b126c452ee9a",
"Arn": "arn:aws:kms:us-east-1:123456789012:key/77f42ffe-fc34-4bfa-81fc-b126c452ee9a",
"Enabled": true,
"KeyUsage": "ENCRYPT_DECRYPT",
"KeyState": "Enabled",
"KeySpec": "SYMMETRIC_DEFAULT"
}
}

Encrypt example.net, which is ZXhhbXBsZS5uZXQ= in base64, then decrypt it with the same encryption context:

Terminal window
CIPHERTEXT=$(aws --endpoint-url "$VERA_ENDPOINT" kms encrypt --key-id "$KEY_ID" \
--plaintext ZXhhbXBsZS5uZXQ= --encryption-context '{"purpose":"documentation"}' \
--query CiphertextBlob --output text)
aws --endpoint-url "$VERA_ENDPOINT" kms decrypt --ciphertext-blob "$CIPHERTEXT" \
--encryption-context '{"purpose":"documentation"}' --query Plaintext --output text

The decrypt prints the original plaintext, in base64:

Output
ZXhhbXBsZS5uZXQ=

The round trip works, but nothing was really encrypted: see Limitations.

To clean up, delete the alias, schedule the key’s deletion and clear the variables:

Terminal window
aws --endpoint-url "$VERA_ENDPOINT" kms delete-alias --alias-name alias/docs-example-key
aws --endpoint-url "$VERA_ENDPOINT" kms schedule-key-deletion --key-id "$KEY_ID" \
--pending-window-in-days 7
unset CIPHERTEXT KEY_ID

Scheduling doesn’t remove the key at once. The response has KeyState: PendingDeletion, PendingWindowInDays: 7 and a future DeletionDate.

  • Symmetric keys, created with a description and tags, and described by key ID or alias.
  • Aliases, created and deleted.
  • Encrypt and decrypt: decrypting returns the original plaintext. It isn’t real encryption.
  • Key state: after DisableKey, Encrypt with the key answers DisabledException, and EnableKey enables it again.
  • Scheduled deletion: ScheduleKeyDeletion puts a key in PendingDeletion, with its window and deletion date.
  • RSA signing, as API flows: for an RSA_2048 key with SIGN_VERIFY usage, GetPublicKey, Sign with RSASSA_PKCS1_V1_5_SHA_256 and Verify all answer, and Verify accepts the emulator’s own signature. Their output isn’t real RSA material: see Limitations.
  • Also served, not yet tested: rotating keys, data keys and key pairs, random bytes, re-encryption, grants, key policies, MACs, imported key material, custom key stores, multi-Region replicas and tags.

The main limits are below. A few more apply to every service, and the API coverage notes cover smaller differences.

  • Encryption isn’t real. The CiphertextBlob, decoded from base64, is a text envelope, v1|<key ID>|SYMMETRIC_DEFAULT|<base64 plaintext>. Decoding its last field gives back the plaintext without any key. Don’t rely on it for confidentiality, or compare its ciphertext with AWS’s.
  • The encryption context isn’t checked. Decrypt with a different encryption context from the one used to encrypt still returned the plaintext, with HTTP 200.
  • RSA output isn’t interoperable. For the RSA_2048 key, GetPublicKey returned a 64-byte PublicKey that doesn’t parse as a DER public key, and Sign returned a 64-byte signature, which the emulator’s Verify accepted. Use asymmetric keys to test API flows, not to check signatures or public keys with other tools. Other algorithms weren’t tested.
  • Key state checks are narrow. A disabled key refusing Encrypt is a key-state check, not authorization: key policies and grants weren’t tested.
  • Deletion wasn’t followed through. Whether the key is deleted when its window ends wasn’t tested, and neither were automatic rotation, MACs, imported key material or multi-Region keys.

Every operation in AWS's published 2014-11-01 API (SDK model, botocore 1.43.105), and whether the emulator implements it. Availability combines the earlier implementation inventory with the dated observations below; checking a page's example does not verify every operation. Each note names its evidence first; an observation given without a build or date comes from earlier testing, on 3 November 2026. What the statuses mean

OperationStatusNotes
CancelKeyDeletionImplemented
ConnectCustomKeyStoreImplemented
CreateAliasImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — created an alias that DescribeKey resolved to its key.
CreateCustomKeyStoreImplemented
CreateGrantImplemented
CreateKeyImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — created a SYMMETRIC_DEFAULT ENCRYPT_DECRYPT key with a description and tags, and an RSA_2048 SIGN_VERIFY key.
DecryptKnown differenceLocal observation: Vera 1.2.0 preview, 5 November 2026 — returned the original plaintext of the emulator's own ciphertext, and still returned it, with HTTP 200, when the request gave a different encryption context.
DeleteAliasImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — deleted the alias.
DeleteCustomKeyStoreImplemented
DeleteImportedKeyMaterialImplemented
DeriveSharedSecretImplemented
DescribeCustomKeyStoresImplemented
DescribeKeyImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — by alias, returned the key's ID and ARN with KeySpec: SYMMETRIC_DEFAULT, KeyUsage: ENCRYPT_DECRYPT, KeyState: Enabled and Enabled: true.
DisableKeyImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — disabled a key, after which Encrypt with it answered DisabledException. A key-state check, not authorization.
DisableKeyRotationImplemented
DisconnectCustomKeyStoreImplemented
EnableKeyImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — enabled a disabled key again.
EnableKeyRotationImplemented
EncryptKnown differenceLocal observation: Vera 1.2.0 preview, 5 November 2026 — the CiphertextBlob, decoded from base64, was the text envelope v1|<key ID>|SYMMETRIC_DEFAULT|<base64 plaintext>, so decoding its last field recovers the plaintext without a key. With the key disabled, it answered DisabledException.
GenerateDataKeyImplemented
GenerateDataKeyPairImplemented
GenerateDataKeyPairWithoutPlaintextImplemented
GenerateDataKeyWithoutPlaintextImplemented
GenerateMacImplemented
GenerateRandomImplemented
GetKeyLastUsageImplemented
GetKeyPolicyImplemented
GetKeyRotationStatusImplemented
GetParametersForImportImplemented
GetPublicKeyKnown differenceLocal observation: Vera 1.2.0 preview, 5 November 2026 — for an RSA_2048 SIGN_VERIFY key, returned a 64-byte PublicKey that doesn't parse as a DER public key. Source inspection: 3 November 2026 — Returns a hash-derived blob rather than the corresponding interoperable asymmetric public key.
ImportKeyMaterialImplemented
ListAliasesImplemented
ListGrantsImplemented
ListKeyPoliciesImplemented
ListKeyRotationsImplemented
ListKeysImplemented
ListResourceTagsImplemented
ListRetirableGrantsImplemented
PutKeyPolicyImplemented
ReEncryptImplemented
ReplicateKeyImplemented
RetireGrantImplemented
RevokeGrantImplemented
RotateKeyOnDemandImplemented
ScheduleKeyDeletionImplementedLocal observation: Vera 1.2.0 preview, 5 November 2026 — returned KeyState: PendingDeletion, PendingWindowInDays: 7 and a future DeletionDate. Whether the key is deleted when the window ends wasn't tested.
SignKnown differenceLocal observation: Vera 1.2.0 preview, 5 November 2026 — with an RSA_2048 key and RSASSA_PKCS1_V1_5_SHA_256, returned a 64-byte signature, which the emulator's Verify accepted. Source inspection: 3 November 2026 — Produces a deterministic HMAC-based emulator signature rather than the requested interoperable asymmetric signature. A local Sign/Verify round trip does not establish compatibility with external cryptographic tools.
TagResourceImplemented
UntagResourceImplemented
UpdateAliasImplemented
UpdateCustomKeyStoreImplemented
UpdateKeyDescriptionImplemented
UpdatePrimaryRegionImplemented
VerifyKnown differenceLocal observation: Vera 1.2.0 preview, 5 November 2026 — accepted the 64-byte signature the emulator's Sign returned for an RSA_2048 key. Source inspection: 3 November 2026 — Checks the emulator's deterministic HMAC-based signature calculation rather than interoperable verification for the advertised asymmetric algorithm.
VerifyMacImplemented