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:
- Generate a DEK — Your application creates a random data encryption key
- Encrypt data locally — Use the DEK to encrypt files, records, or payloads
- Wrap the DEK — Call KMS encrypt to wrap the DEK
- Store both — Persist the encrypted data and the wrapped DEK together
- 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
| Operation | Endpoint |
|---|---|
| Encrypt | POST /v1/kms/{region}/keys/{id}/encrypt |
| Decrypt | POST /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>"
}| Constraint | Value |
|---|---|
| Plaintext encoding | Base64 |
| Decoded size | 1–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 type | Direct 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}/encryptCross-region key use is not supported.
Errors
| HTTP status | Typical cause |
|---|---|
400 | Key disabled or pending deletion; unsupported operation for key type; invalid plaintext size |
404 | Key not found or insufficient IAM access |
503 | KMS 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 log —
kms.encryptandkms.decryptevents