Skip to content

Encrypt and decrypt with KMS

KMS encrypt and decrypt operations are available for symmetric and RSA key types. Use them for envelope encryption in production and for direct encryption of small payloads in tooling.

Envelope encryption (recommended)

Envelope encryption keeps bulk data off the KMS API and is the recommended pattern for production:

  1. Generate a DEK — Your application creates a random data encryption key
  2. Encrypt data locally — Use the DEK to encrypt files, records, or payloads
  3. Wrap the DEK — Call KMS encrypt to wrap the DEK
  4. Store both — Persist the encrypted data and the wrapped DEK together
  5. Unwrap on read — Call KMS decrypt to recover the DEK, then decrypt data locally
┌────────────┐   wrap DEK    ┌─────────┐
│ Application│──────────────►│   KMS   │
│            │◄──────────────│         │
└─────┬──────┘   unwrap DEK  └─────────┘
      │
      │ encrypt/decrypt bulk data locally with DEK
      ▼
┌────────────┐
│  Storage   │
└────────────┘

This pattern limits KMS API calls to small key material, reduces latency for large files, and aligns with least-privilege access for application service accounts.

Direct encrypt and decrypt

Direct encrypt and decrypt is supported for:

  • Development and operational tooling
  • Small secrets and configuration values
  • Testing and migration scripts

Do not route large files or high-volume bulk data through the encrypt API in production.

API operations

OperationEndpoint
EncryptPOST /v1/kms/{region}/keys/{id}/encrypt
DecryptPOST /v1/kms/{region}/keys/{id}/decrypt

Replace {region} with the key’s region and {id} with the key identity or slug.

Encrypt request

{
  "plaintext": "<base64-encoded data>"
}
ConstraintValue
Plaintext encodingBase64
Decoded size1–65,535 bytes

Encrypt response

{
  "ciphertext": "thalassa:v1:...",
  "keyVersion": 1
}

Decrypt request

{
  "ciphertext": "thalassa:v1:..."
}

Decrypt response

{
  "plaintext": "<base64-encoded data>",
  "keyVersion": 1
}

Ciphertext format

Ciphertext returned by KMS uses the Thalassa format:

thalassa:v{version}:{payload}

The embedded version identifies which key version encrypted the data. After rotation, KMS decrypts older ciphertext automatically using the correct version.

Key version behaviour

  • New encrypt operations use the latest key version by default
  • Rotation adds a new version; existing ciphertext is not re-encrypted
  • Decrypt uses the version embedded in the ciphertext

You do not need to re-encrypt data when you rotate a key.

Supported key types

Key typeDirect encrypt / decrypt
aes128-gcm96, aes256-gcm96, chacha20-poly1305✓ Full payload range
rsa-2048, rsa-3072, rsa-4096✓ Small payloads only (~190 bytes for RSA-2048)

Signing-only types (ECDSA, Ed25519) and HMAC types do not support encrypt and decrypt.

Symmetric convergent encryption

Symmetric key types support convergent encryption when the same plaintext and encryption context are used. This can produce identical ciphertext for identical inputs. Use explicit encryption context in your application design when you rely on or need to avoid this behaviour.

Regional requirement

Encrypt and decrypt calls must target the region where the key was created:

/v1/kms/{region}/keys/{id}/encrypt

Cross-region key use is not supported.

Errors

HTTP statusTypical cause
400Key disabled or pending deletion; unsupported operation for key type; invalid plaintext size
404Key not found or insufficient IAM access
503KMS unavailable in the region

Related documentation

  • Key types — Choose symmetric vs RSA keys
  • Rotation — Version behaviour after rotation
  • Integrations — How Secrets Manager uses KMS encryption
  • Audit logkms.encrypt and kms.decrypt events