Encryption at Rest
Every piece of data stored by VeriProof is encrypted at rest. This page explains the encryption applied at each layer of the storage stack.
Encryption layers
VeriProof applies three independent layers of encryption to persistent data:
| Layer | Mechanism | What it covers |
|---|---|---|
| Infrastructure | Azure transparent data encryption (TDE) | All PostgreSQL and Blob storage volumes |
| Application | AES-256-GCM per-record | Captured content (opt-in), audit log entries |
| Column | SHA-256 (one-way) | API key material |
These layers are independent. A compromise of one layer does not expose plaintext data if the others hold.
PostgreSQL — Transparent Data Encryption
All VeriProof PostgreSQL instances run on Azure Database for PostgreSQL with TDE enabled. Azure manages the encryption keys for TDE using Azure Key Vault. The default configuration uses Azure-managed keys. Enterprise customers can configure customer-managed keys (CMK) for full control over the encryption key lifecycle:
Data written to disk ──▶ Azure PostgreSQL engine
│ TDE encryption
▼
AES-256-XTS
│ Key managed in
▼
Azure Key Vault
(Azure-managed or customer CMK)TDE operates transparently — your queries read and write plaintext, and encryption/decryption happens at the storage engine level with no performance-significant overhead.
Captured content — AES-256-GCM
When content capture is enabled, prompt text, completion text, and retrieved documents are encrypted before storage with AES-256-GCM authenticated encryption:
Plaintext content
│
▼ HKDF-SHA256 key derivation
│ (master key + tenant ID + session ID as context)
▼
Per-session sub-key
│
▼ AES-256-GCM encrypt
│ (random 96-bit IV per encryption)
▼
Ciphertext + auth tag stored in PostgreSQLKey derivation uses HKDF to produce a per-session sub-key from the master key. Different sessions use different sub-keys, so a compromise of one session’s key does not expose any other session.
The master key is stored in Azure Key Vault, not in the application’s environment variables or configuration files.
API keys — one-way hashing
VeriProof never stores the plaintext form of a customer API key after it is issued. When you generate a key in the Customer Portal, it is shown to you once and then discarded. What is stored:
Raw API key: vp_cust_acme.abc123.xyz789
│
▼ SHA-256
│
Stored: hash of secondary + metadata (scope, expiry, label)Authentication validates an incoming key by hashing it and comparing to the stored hash. The hash is one-way — there is no way to recover the original key from the stored value. If a key is lost, it must be revoked and reissued.
Audit log — application-layer encryption
Every write to the audit log (API key operations, staff access, configuration changes) encrypts the entry at the application layer before it reaches the database:
- Encryption: AES-256-GCM
- Key: per-tenant key derived from the Key Vault master key using HMAC-SHA256
- Scope: audit log entries only; session records use the TDE layer
This means that even with direct database read access, audit log content is indecipherable without the corresponding Key Vault key.
Enterprise Tier — Azure Blob WORM encryption
In Enterprise Federated deployments, encrypted audit logs written to Azure Blob Storage use:
- Server-side encryption: AES-256 (Azure-managed or customer CMK)
- Application-layer encryption: AES-256-GCM before persistence to customer-managed storage
- Immutability: WORM policy prevents deletion during the retention period
Content is encrypted before it is written to persistent storage. Azure only stores the ciphertext.
Key rotation
| Key type | Rotation frequency | Rotation procedure |
|---|---|---|
| TDE database keys | Annual (Azure-managed) | Automated by Azure; no downtime |
| Content encryption master key | On demand / after incident | New key generated; old data re-encrypted in background |
| API key signing key | On demand | Revoke old key, issue new key |
| Deployment context signing key | Annual or on demand | New key via Key Vault; static config regenerated |
GDPR and cryptographic erasure
When a customer requests deletion of their data, VeriProof performs cryptographic erasure of content encryption keys, making captured content permanently unrecoverable:
- The per-tenant content encryption key is deleted from Azure Key Vault
- All AES-256-GCM encrypted content for that tenant becomes permanently undecryptable
- The ciphertext itself is then deleted on the standard retention schedule
Because blockchain-anchored Merkle roots are public (by design), they cannot be deleted. However, they contain no personal data — only a 32-byte hash. Personal data exists only in the encrypted content layer, which is covered by cryptographic erasure. See GDPR Cryptographic Erasure for the full procedure.
Next steps
- Encryption in Transit — TLS configuration and certificate management
- Azure Key Vault & HMAC Signing — key management architecture
- GDPR Cryptographic Erasure — erasure procedure for data subject requests