Encryption: TDE, Always Encrypted, and VBS Enclaves
Implement Transparent Data Encryption, object-level encryption, Always Encrypted, and Always Encrypted with VBS enclaves to protect data at rest in Azure SQL.
Encrypting data at rest
Think of encryption like protecting valuables in a house.
TDE is like locking your front door — it protects the entire house (database files on disk). If someone steals the hard drive, they can’t read anything. But once you’re inside the house (connected to the database), you see everything normally.
Always Encrypted is like a safe inside the house — even if you’re inside (connected to the database), you can’t see what’s in the safe unless you have the combination (the encryption key). Even the database engine can’t peek inside.
Object-level encryption is like individual lockboxes — you choose exactly which items to encrypt, one column or value at a time.
Transparent Data Encryption (TDE)
TDE encrypts the entire database at rest — data files, log files, and backups are all encrypted on disk.
How it works:
- A Database Encryption Key (DEK) encrypts the database
- The DEK is protected by a TDE protector (certificate or asymmetric key)
- Encryption/decryption happens at the I/O level — transparent to applications
- No application code changes required
TDE on Azure SQL Database and MI:
- Enabled by default on all new databases
- Uses service-managed keys by default (Microsoft manages the key)
- Can switch to customer-managed keys (CMK) in Azure Key Vault for full control
TDE on SQL Server (VMs):
- Not enabled by default — must be configured manually
- Requires a certificate backup (critical for disaster recovery)
-- Enable TDE (SQL Server on VMs)
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TDECert;
ALTER DATABASE NorthStarERP SET ENCRYPTION ON;
-- Check TDE status
SELECT db.name, db.is_encrypted, dek.encryption_state
FROM sys.databases db
LEFT JOIN sys.dm_database_encryption_keys dek ON db.database_id = dek.database_id;
Customer-managed keys (CMK) for TDE
With CMK, you store the TDE protector in Azure Key Vault:
- You control the key lifecycle — create, rotate, revoke
- Revoke access = database becomes inaccessible (the “kill switch”)
- Requires Azure Key Vault with soft-delete and purge protection enabled
- The SQL server’s managed identity needs Get, Wrap Key, and Unwrap Key permissions on the key
The exam may ask: “How can Amara ensure Harbour Health retains full control over encryption keys?” → Customer-managed TDE keys in Azure Key Vault.
Object-level encryption
For encrypting specific values within the database (not the whole database):
-- Create a symmetric key
CREATE SYMMETRIC KEY PatientDataKey
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE DataCert;
-- Encrypt a value
OPEN SYMMETRIC KEY PatientDataKey DECRYPTION BY CERTIFICATE DataCert;
UPDATE Patients SET SSN_Encrypted = ENCRYPTBYKEY(KEY_GUID('PatientDataKey'), SSN);
CLOSE SYMMETRIC KEY PatientDataKey;
-- Decrypt
OPEN SYMMETRIC KEY PatientDataKey DECRYPTION BY CERTIFICATE DataCert;
SELECT PatientID, CONVERT(VARCHAR, DECRYPTBYKEY(SSN_Encrypted)) AS SSN
FROM Patients;
CLOSE SYMMETRIC KEY PatientDataKey;
Limitations:
- Application must manage key opening/closing
- Encrypted columns are
VARBINARY— no indexing, no range queries - More code changes than TDE or Always Encrypted
Always Encrypted
Always Encrypted is client-side encryption — data is encrypted by the application (or driver) before it reaches the database engine.
Key concept: The database engine never sees plaintext. Even a DBA with full access sees only ciphertext.
Architecture
| Component | Where It Lives | Purpose |
|---|---|---|
| Column Master Key (CMK) | Azure Key Vault, Windows Certificate Store, or HSM | Protects the column encryption key |
| Column Encryption Key (CEK) | Database (encrypted form only) | Encrypts the actual data |
| Client driver | Application side | Encrypts/decrypts data using the CEK |
Encryption types
| Type | What It Does | Supports | Use When |
|---|---|---|---|
| Deterministic | Same plaintext always produces same ciphertext | Equality comparisons, joins, GROUP BY, indexing | You need to search or join on encrypted columns |
| Randomized | Same plaintext produces different ciphertext each time | Nothing (no server-side operations) | Maximum security, no need to query on the column |
Setting up Always Encrypted
Amara protects patient SSN and medical record numbers:
Using SSMS wizard:
- Right-click the table → Encrypt Columns
- Select columns to encrypt and encryption type (deterministic or randomized)
- Choose where to store the CMK (Azure Key Vault recommended)
- SSMS generates the CEK, encrypts existing data, and configures the columns
Using T-SQL:
-- Create CMK definition (metadata pointing to Key Vault)
CREATE COLUMN MASTER KEY CMK_AKV
WITH (KEY_STORE_PROVIDER_NAME = 'AZURE_KEY_VAULT',
KEY_PATH = 'https://harbourhealthvault.vault.azure.net/keys/AlwaysEncryptedCMK/...');
-- Create CEK (encrypted by the CMK)
CREATE COLUMN ENCRYPTION KEY CEK_SSN
WITH VALUES (COLUMN_MASTER_KEY = CMK_AKV,
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x01AA...);
-- Create table with encrypted columns
CREATE TABLE Patients (
PatientID INT PRIMARY KEY,
Name NVARCHAR(100),
SSN NVARCHAR(11) ENCRYPTED WITH (
COLUMN_ENCRYPTION_KEY = CEK_SSN,
ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256')
);
Always Encrypted with VBS enclaves
Standard Always Encrypted has a limitation: the database engine can’t perform operations on encrypted data (no sorting, pattern matching, or range queries on randomized columns).
VBS enclaves solve this by creating a secure, isolated memory region (enclave) within the database engine:
- The enclave can access encryption keys inside its protected boundary
- Operations on encrypted data (comparisons, LIKE, sorting, range queries) happen inside the enclave
- Data remains encrypted outside the enclave — the rest of the database engine can’t see plaintext
| Feature | Standard Always Encrypted | With VBS Enclaves |
|---|---|---|
| Equality queries (deterministic) | Yes | Yes |
| Range queries | No | Yes (inside enclave) |
| LIKE pattern matching | No | Yes (inside enclave) |
| Sorting | No | Yes (inside enclave) |
| In-place encryption | No (requires data export) | Yes (enclave encrypts in-place) |
| Key rotation | Complex (re-encrypt all data) | Simpler (enclave handles re-encryption) |
Exam tip: when to recommend each encryption method
- TDE — “Protect the entire database at rest with no application changes” → TDE
- Always Encrypted — “Even DBAs should not see sensitive column data” → Always Encrypted
- Always Encrypted + VBS enclaves — “DBAs can’t see data, but we need range queries on encrypted columns” → VBS enclaves
- Object-level — “Encrypt specific values with custom key management” → ENCRYPTBYKEY functions
- TDE + Always Encrypted — “Defence in depth: encrypt at rest AND encrypt sensitive columns” → Both together
Amara needs to encrypt patient SSN numbers so that even database administrators cannot see the plaintext values. The application needs to search for patients by exact SSN. Which approach should she use?
Kenji's team uses Always Encrypted to protect financial data. They now need to run range queries (WHERE amount BETWEEN 1000 AND 5000) on an encrypted column. What should they implement?
🎬 Video coming soon
Next up: Network Security: Firewalls, Private Links, and Endpoints — control who can reach your databases at the network level.