Vault Encryption as a Service: Tenant-Isolated Data Encryption with the Transit Engine
Direct answer
Vault's Transit secrets engine provides encryption as a service or cryptography as a service. Applications send plaintext data to Vault, receive ciphertext back, and never touch the encryption keys directly. For multi-tenant platforms, the Transit engine enables cryptographic isolation between tenants, users, and even sessions—all derived from a single master key. OpenTenant automates the tenant lifecycle: each tenant receives its own transit key or derived key scope, with policies that prevent cross-tenant access and rotation procedures that don't require application downtime.
The Transit engine does not store the data sent to it—it performs cryptographic operations and returns the result. Your application remains responsible for storing the ciphertext in its primary data store.
What the Transit engine provides
The Transit secrets engine handles cryptographic functions on data in transit, including:
- Encrypt and decrypt data with AES-GCM, ChaCha20-Poly1305, or RSA
- Sign and verify data with ECDSA, Ed25519, or RSA
- Generate hashes and HMACs for data integrity
- Generate cryptographically secure random bytes
Key management capabilities include:
- Centralized key management—all encryption keys are managed within Vault
- Key rotation without re-encrypting all data immediately
- Audit logging—every cryptographic operation is logged
- Access control—policies define which services can use which keys
The Transit engine is optimized for high throughput, handling thousands of transactions per second with minimal latency. Since it does not store data, it scales horizontally.
The use case: tenant-isolated encryption without key sprawl
Before adopting Vault, many platforms rely on application-level encryption with manually managed keys stored in environment variables. This creates several problems:
- No tenant isolation—a single compromised key exposes all tenants' data
- No key rotation—rotating keys requires coordinated downtime and re-encryption
- No audit trail—cryptographic operations are invisible to security teams
- Key sprawl—each service manages its own keys independently
The Transit engine solves these problems by providing a single, centralized encryption service that supports:
- Multi-tenant key derivation—context-based derivation for secure multi-tenancy
- Convergent encryption—deterministic encryption for deduplication
- Batch operations—high-throughput processing for enterprise workloads
Reference architecture
tenant encryption profile
→ validate tenant identity and isolation level
→ create or reference tenant-scoped transit key
→ derive tenant-specific encryption context
→ application encrypts data via Vault API
→ ciphertext stored in tenant database
→ decrypt on read with same context
→ rotate keys without application downtime
The key insight is envelope encryption: a master key never leaves Vault. For each encryption operation, Vault derives a tenant-specific data encryption key (DEK) based on the tenant context. The application never sees the raw key material.
Multi-tenant isolation patterns
Pattern 1: Per-tenant transit keys
Each tenant receives a dedicated transit key. This provides strong isolation but requires managing one key per tenant.
tenant: acme
→ transit/keys/tenant-acme
tenant: beta
→ transit/keys/tenant-beta
When to use: Small number of tenants, strongest isolation required.
Pattern 2: Single key with context-based derivation
A single master key with context-based key derivation provides tenant isolation without managing thousands of individual keys. Vault derives a new key based on a user-supplied context value.
tenant: acme, user: alice
→ transit/encrypt/my-key?context=acme:alice
tenant: acme, user: bob
→ transit/encrypt/my-key?context=acme:bob
When to use: Large number of tenants, multiple isolation levels needed (organization, user, session).
Ariso.ai achieved three isolation levels—organization, user, and session—derived from a single master key with sub-millisecond latency (0.46ms median, 0.63ms at p99).
Pattern 3: Convergent encryption for deduplication
Convergent encryption produces the same ciphertext for the same plaintext, enabling deduplication and searchable encrypted fields.
When to use: Storage optimization, encrypted search, compliance with deduplication requirements.
Illustrative tenant declaration
tenant: acme
encryption:
engine: transit
# Pattern 1: Dedicated key per tenant
key: tenant-acme
# Pattern 2: Context-based derivation (alternative)
# masterKey: platform-master
# context: "tenant:acme"
isolation:
level: tenant # tenant | user | session
algorithms:
encrypt: aes256-gcm96
sign: ecdsa-p256
rotation:
policy: scheduled
interval: 90d
secretScope: tenants/acme/encryption
This is an architectural example. Production declarations should reference specific key configurations and policies.
Production decisions before onboarding
Isolation level. Decide the granularity of cryptographic isolation. Ariso.ai needed three levels—organization, user, and session—each derived from a single master key. The more granular the isolation, the more contexts you manage.
Key type selection. The Transit engine supports multiple key types:
aes256-gcm96—AES-256 with GCM (default, recommended for most use cases)chacha20-poly1305—ChaCha20-Poly1305 for high-performance scenariosrsa-2048/3072/4096—Asymmetric encryptionecdsa-p256/p384/p521—Digital signaturesed25519—Ed25519 signatures
Key rotation strategy. The Transit engine supports key rotation without re-encrypting all data immediately. The ciphertext includes a version prefix (vault:v1:...) that indicates which key version was used. During rotation:
- Create a new key version
- New encryptions use the new version
- Old ciphertext remains decryptable with the old version
- Rewrap old ciphertext to the new version when convenient
Performance considerations. The Transit engine is optimized for high throughput. For sub-millisecond latency, consider:
- Caching DEKs at the application layer (Ariso.ai achieved an 8:1 encrypt-to-decrypt ratio with effective DEK caching)
- Using HCP Vault Dedicated to eliminate operational burden
- Horizontal scaling—Transit operations are primarily reads and scale horizontally
Policy design. Vault policies must be tenant-scoped to prevent cross-tenant access:
# Tenant A can only use its own key
path "transit/encrypt/tenant-acme" {
capabilities = ["create", "update"]
}
path "transit/decrypt/tenant-acme" {
capabilities = ["create", "update"]
}
# Tenant A cannot access Tenant B's key
path "transit/encrypt/tenant-beta" {
capabilities = ["deny"]
}
Application integration. Applications call Vault's REST API rather than using the CLI:
# Encrypt
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"plaintext": "c2Vuc2l0aXZlLWRhdGE="}' \
$VAULT_ADDR/v1/transit/encrypt/my-app-key
# Decrypt
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"ciphertext": "vault:v1:8SDd3WHDOjf7mq69CyCqy..."}' \
$VAULT_ADDR/v1/transit/decrypt/my-app-key
All data must be base64-encoded before sending to Vault.
Evaluation checklist
- Does every tenant have its own encryption key or derived context?
- Are Vault policies scoped to prevent cross-tenant key access?
- Can keys be rotated without application downtime?
- Is every cryptographic operation audited and logged?
- Does the application never handle raw encryption keys?
- Are ciphertexts stored with version information for rotation?
- Can you rewrap old ciphertexts to new key versions?
- Is performance acceptable for your throughput requirements?
- Does the isolation level match your security and compliance needs?
Sources
- Transit secrets engine — HashiCorp Developer
- Encrypt data in transit with Vault — HashiCorp tutorials
- High-performance envelope encryption at Ariso.ai with Vault
- Transit and Transform secrets engines — Validated Designs
- How to Build Vault Transit Encryption — OneUptime
OpenTenant transforms the Transit engine from a shared encryption service into a tenant-scoped capability: each tenant gets its own encryption boundary, rotation schedule, and audit trail—all derived from the same tenant declaration that defines the rest of the infrastructure.