HashiCorp Vault — Encryption as a Service

2 minute read

Vault Transit is “encryption as a service” — a centralized cryptographic service for your applications.


The Problem

Applications that handle their own encryption face multiple challenges:

  • Key management: Where do you store the encryption key?
  • Key rotation: How do you rotate keys without downtime?
  • Algorithm choice: Is AES-256-GCM the right choice? What about authenticated encryption?
  • Implementation bugs: Crypto libraries are easy to misuse
  • Audit: Who encrypted what, and when?

Transit Architecture

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  Web App    │    │  Mobile API │    │  Batch Job  │
│             │    │             │    │             │
└──────┬──────┘    └──────┬──────┘    └──────┬──────┘
       │                  │                  │
       │    ┌─────────────┴──────────────┐   │
       └───▶│       Vault Transit        │◀──┘
            │                            │
            │  ┌─────────┐ ┌──────────┐ │
            │  │ Key: app │ │ Key: pii │ │
            │  │ AES-256  │ │ ChaCha20 │ │
            │  └─────────┘ └──────────┘ │
            │                            │
            │  Encryption keys NEVER     │
            │  leave Vault's barrier     │
            └────────────────────────────┘

Key Types

Key Type Algorithm Use Case
aes128-gcm96 AES-128 with GCM General encryption
aes256-gcm96 AES-256 with GCM Default. Strong general encryption
chacha20-poly1305 ChaCha20-Poly1305 Software-optimized encryption
ed25519 Ed25519 Signing only
ecdsa-p256 ECDSA P-256 Signing only
ecdsa-p384 ECDSA P-384 Signing only
ecdsa-p521 ECDSA P-521 Signing only
rsa-2048 RSA 2048-bit Encryption + signing
rsa-3072 RSA 3072-bit Encryption + signing
rsa-4096 RSA 4096-bit Encryption + signing

Create Encryption Keys

# Enable transit
vault secrets enable transit

# Create a key with default settings (aes256-gcm96)
vault write -f transit/keys/my-app-key

# Create a key with specific type
vault write transit/keys/signing-key type=ed25519

# Create a key allowing export (for special cases)
vault write transit/keys/exportable-key type=aes256-gcm96 exportable=true

# Create a convergent encryption key (same plaintext = same ciphertext)
vault write transit/keys/deterministic-key \
    type=aes256-gcm96 \
    convergent_encryption=true \
    derived=true

Key Properties

vault read transit/keys/my-app-key

Expected output:

Key                       Value
---                       -----
allow_plaintext_backup    false
auto_rotate_period        0s
deletion_allowed          false
derived                   false
exportable                false
keys                      map[1:1705312800]
latest_version            1
min_available_version     0
min_decryption_version    1
min_encryption_version    0
name                      my-app-key
supports_decryption       true
supports_derivation       true
supports_encryption       true
supports_signing          false
type                      aes256-gcm96

Transit Operations

Operation Endpoint Description
Encrypt transit/encrypt/KEY Encrypt plaintext → ciphertext
Decrypt transit/decrypt/KEY Decrypt ciphertext → plaintext
Rewrap transit/rewrap/KEY Re-encrypt with latest key version
Rotate transit/keys/KEY/rotate Create new key version
Datakey transit/datakey/TYPE/KEY Generate a data encryption key
Sign transit/sign/KEY Create digital signature
Verify transit/verify/KEY Verify digital signature
HMAC transit/hmac/KEY Generate HMAC
Hash transit/hash Hash data (no key needed)

Convergent Encryption

Convergent encryption produces the same ciphertext for the same plaintext, enabling encrypted search:

# Create a convergent key
vault write transit/keys/search-key \
    type=aes256-gcm96 \
    convergent_encryption=true \
    derived=true

# Encrypt with a context (required for convergent)
vault write transit/encrypt/search-key \
    plaintext=$(echo -n "alice@example.com" | base64) \
    context=$(echo -n "email-lookup" | base64)
# Always returns the same ciphertext for "alice@example.com" with "email-lookup" context

Quick Reference

Command Description
vault secrets enable transit Enable Transit
vault write -f transit/keys/NAME Create key
vault write transit/keys/NAME type=TYPE Key with type
vault read transit/keys/NAME Read key info
vault list transit/keys List all keys

Next: Encrypt & Decrypt