Hardening SQL encryption: the basics
What does customer-managed key encryption actually change?
Every Azure SQL database is already encrypted at rest. Transparent data encryption, TDE, is on by default, and out of the box the key that protects the database, the TDE protector, is a service-managed key that Microsoft creates, stores and rotates for you. That is fine for a lot of workloads. The recommendations in this capability are about the next step up: replacing that platform key with a customer-managed key, a key you create in your own Azure Key Vault and control. This is the bring-your-own-key, or BYOK, model, and it gives you the power to revoke access to your own data by disabling the key, plus an audit trail of every time the key is used.
Microsoft Defender for Cloud raises this as two separate recommendations because Azure SQL comes in two deployment shapes that are configured differently. 'SQL servers should use customer-managed keys to encrypt data at rest' targets the logical server behind Azure SQL Database, where the protector is set on the server with 'az sql server tde-key'. 'SQL managed instances should use customer-managed keys to encrypt data at rest' targets Azure SQL Managed Instance, where the same job is done on the instance with 'az sql mi tde-key'. They read as two findings, but they are one capability: own the key that protects your data at rest.
The work is not to flip a switch on every database in the estate. Service-managed TDE is a perfectly acceptable default for most workloads, and moving to a customer-managed key adds operational responsibility: a Key Vault to keep available, a key to keep enabled, and permissions to keep granted. The job is to identify the databases and instances that a regulatory or contractual requirement says must use a customer-managed key, move those onto one cleanly, and then make sure new servers in those scopes adopt the key by default rather than slipping back to the platform key.
In this lesson you will learn the difference between service-managed and customer-managed TDE, why Azure SQL Database and SQL Managed Instance surface as two separate recommendations even though they are one capability, how to move a regulated workload onto a customer-managed key without losing access to its own data, and how to keep new servers in scope from drifting back to the platform key. The Controls this lesson covers section lists every Defender for Cloud recommendation in this capability, each linking to a deep page with the exact check and a copy-and-paste fix.
The key you can take back
The quiet superpower of a customer-managed key is not stronger encryption: the platform key and your key use the same algorithm and are equally hard to break. It is revocability. Because the TDE protector lives in your own Key Vault, disabling or removing access to that one key makes every database it protects unreadable within minutes, without touching the databases themselves. That is why Azure forces you to enable soft-delete and purge protection on the vault before it will let you use a key for TDE: the same property that lets you revoke access on purpose would, if the key were ever deleted by accident, lock you out of your own data permanently.
Finding which SQL resources hold their own key
Priya is the security lead at a fintech preparing for a SOC 2 Type II audit. Defender for Cloud flags several Azure SQL logical servers and one managed instance as not using customer-managed keys, and her data-protection obligations say the customer-record databases must hold their own key.
Rather than assume every server needs changing, she starts by listing which servers are still on the service-managed key, so she can separate the regulated databases that genuinely need a customer-managed key from the ones where the platform key is a perfectly acceptable and documented choice.
List each logical server's TDE protector type. 'ServiceManaged' means the platform holds the key; 'AzureKeyVault' means you do.
A server is only a finding worth acting on if a regulatory or contractual obligation says it must hold its own key. Separate those from the servers where 'ServiceManaged' is a fine, documented choice before changing anything.
How Defender for Cloud decides a SQL resource is not using a customer-managed keydeep dive
The check resolves to one property: the type of the TDE protector. For an Azure SQL logical server it is the server key type, which is either 'ServiceManaged' (the platform key) or 'AzureKeyVault' (a key in your vault). For a managed instance the same property lives on the instance. The recommendation is Healthy only when that type is 'AzureKeyVault' and the key it points at is a key you control. The two recommendations exist because Azure SQL Database and SQL Managed Instance are distinct resource types configured by different commands ('az sql server tde-key' versus 'az sql mi tde-key'), even though the underlying setting is the same idea.
Setting a customer-managed key has prerequisites that the protector type alone does not capture. The server or instance needs a managed identity, that identity needs 'get', 'wrapKey' and 'unwrapKey' permissions on the key, and the Key Vault must have soft-delete and purge protection enabled before Azure will accept the key for TDE. Miss any of these and the protector cannot be set. This is why the move is a short sequence rather than a single flag, and why it should be tested on a non-production server first.
The strongest position pairs the per-resource configuration with an Azure Policy backstop. The built-in policies 'SQL servers should use customer-managed keys to encrypt data at rest' and 'SQL managed instances should use customer-managed keys to encrypt data at rest' default to an Audit effect, which keeps the recommendation visible, and can be set to Deny on the subscriptions or resource groups that hold regulated workloads so a new server cannot be created there without a customer-managed key. Scoping the Deny to the regulated landing zones, rather than the whole tenant, is what keeps the control aligned to the obligation rather than blanketing every database.
What is the impact of staying on the platform key where a customer-managed key is required?
The first impact is a direct compliance gap. Where a contract, a regulatory framework or a data-residency rule requires that the customer holds the encryption key, a database on the service-managed key does not meet that obligation no matter how strong the encryption is. The data is encrypted, but the control the obligation actually asks for, that you can revoke access to your own data independently of the provider, is not present. At audit this surfaces as a finding against the specific regulated databases, and it cannot be argued away by pointing at the platform encryption.
The second impact is loss of a real security capability. With a customer-managed key you can disable the key to make every database it protects unreadable within minutes, which is a genuine response to a suspected compromise or a contractual termination. You also get an audit trail of every key operation. On the service-managed key neither is available to you: the platform handles the key, and you cannot revoke or independently audit it. For most workloads that is fine; for the regulated ones it is the gap.
It is worth being equally clear about the inverse impact: adopting customer-managed keys where there is no obligation is its own kind of mistake. It adds a Key Vault to keep available, a key to keep enabled, and a failure mode where an accidental loss of key access takes the database offline. A passing record here is not 'every database on a customer-managed key'. It is 'the regulated databases on customer-managed keys, the rest deliberately on the service-managed key, and both choices documented'.
How do you move a regulated workload onto a customer-managed key safely?
Work this as a scoped, ordered change rather than a sweep. The order matters: get the prerequisites right before you set the protector, because a half-configured customer-managed key can leave a database unable to come online.
1. Scope to the workloads that actually require it
List each server and instance still on the service-managed key, then map it to the obligation on its data. Only the databases a contract, framework or residency rule says must hold their own key are candidates. Everything else stays on the fully-encrypted platform key as a documented decision. Do not move a server just to clear a finding.
2. Prepare the key and the identity
Create or choose an Azure Key Vault with soft-delete and purge protection enabled, which Azure requires before it will accept a key for TDE. Create an RSA key (2048 or 3072 bit). Give the server or instance a managed identity, and grant that identity 'get', 'wrapKey' and 'unwrapKey' permissions on the key. Miss any of these and the protector cannot be set.
3. Set the protector on a test resource first
Add the key to the server with 'az sql server key create' (or 'az sql mi key create' for a managed instance), then set it as the TDE protector with 'az sql server tde-key set --server-key-type AzureKeyVault' (or the 'az sql mi tde-key set' equivalent). Verify the protector type reads 'AzureKeyVault' before doing it on production, and confirm the databases stay online.
4. Backstop the regulated scope with Azure Policy
Assign the built-in customer-managed-key policies to the subscriptions or resource groups that hold regulated workloads. Keep them on Audit to stay visible, or set Deny on the regulated landing zones so no new server can be created there on the platform key. Scope the Deny to the regulated zones, not the whole tenant, so the control matches the obligation.
# Move ONE regulated Azure SQL logical server onto a customer-managed key.
# Run against a test server first and confirm databases stay online.
RG=prod-rg
SERVER=custrecords-sql
VAULT=custrecords-kv
KEY=tde-protector
# 1. Vault needs soft-delete + purge protection before Azure accepts a TDE key.
az keyvault update --name "$VAULT" --resource-group "$RG" \
--enable-purge-protection true
# 2. Create the RSA key (2048 or 3072 bit).
az keyvault key create --name "$KEY" --vault-name "$VAULT" --size 2048
# 3. Give the server a managed identity and read its principal id.
az sql server update --name "$SERVER" --resource-group "$RG" --assign-identity
PRINCIPAL=$(az sql server show --name "$SERVER" --resource-group "$RG" \
--query identity.principalId -o tsv)
# 4. Grant the identity the exact key permissions TDE needs.
az keyvault set-policy --name "$VAULT" --object-id "$PRINCIPAL" \
--key-permissions get wrapKey unwrapKey
# 5. Add the key to the server and set it as the TDE protector.
KID=$(az keyvault key show --name "$KEY" --vault-name "$VAULT" \
--query key.kid -o tsv)
az sql server key create --server "$SERVER" --resource-group "$RG" --kid "$KID"
az sql server tde-key set --server "$SERVER" --resource-group "$RG" \
--server-key-type AzureKeyVault --kid "$KID"
# 6. Backstop the regulated scope: assign the built-in policy by display name
# (look up the definition id at runtime, never hardcode the GUID).
PID=$(az policy definition list \
--query "[?displayName=='SQL servers should use customer-managed keys to encrypt data at rest'].name" \
-o tsv)
az policy assignment create --name require-cmk-sql --policy "$PID" \
--scope "/subscriptions/<regulated-subscription-id>" Quick quiz
Question 1 of 5Defender for Cloud flags an Azure SQL server and a SQL managed instance for not using customer-managed keys. What is the most accurate way to think about these two findings?
You scored
0 / 5
Keep learning
Go deeper on how Azure SQL expresses customer-managed transparent data encryption across the logical server and managed instance.
- Customer-managed transparent data encryption (TDE) overview What a customer-managed TDE protector is, the BYOK model, and why revocability is the core benefit.
- Enable SQL TDE with Azure Key Vault The exact Azure CLI and PowerShell sequence to assign an identity, grant key permissions, and set the protector.
- Rotate the TDE protector How to rotate a customer-managed key safely once it is in use, without losing database access.
You can now treat Azure SQL encryption as one scoped capability rather than two findings to clear: every database is already encrypted, the question is who holds the key, and the answer should be a deliberate scope. Identify the workloads under an obligation to hold their own key, move exactly those onto a customer-managed key in a vault protected by soft-delete and purge protection, leave the rest on the documented platform key, and backstop the regulated scope with Azure Policy. The Controls this lesson covers section below links every recommendation in this group to its deep page and fix.
Back to the library