This check flags Cosmos DB accounts running without Microsoft Defender for Azure Cosmos DB, which means SQL injection attempts, credential abuse, and data exfiltration go undetected. Enable threat protection per account or subscription-wide with one CLI command or an Azure Policy assignment.
Azure Cosmos DB is a fast, globally distributed database, and that scale is exactly why it makes an attractive target. When Advanced Threat Protection is off, you lose the alerting layer that tells you when something abnormal is happening inside your data plane. This Lensix check, cosmosdb_nothreatprotection, fires when a Cosmos DB account has no threat protection enabled.
Below we walk through what the check looks at, the risk you carry while it stays open, and the concrete steps to close it and keep it closed.
What this check detects
The check inspects each Azure Cosmos DB account in scope and verifies whether Microsoft Defender for Azure Cosmos DB (historically called Advanced Threat Protection for Cosmos DB) is turned on. If the setting is disabled, the account is reported as non-compliant.
Defender for Cosmos DB analyzes telemetry from the Cosmos DB control and data planes to spot anomalous access patterns. It does not require agents and does not change your application code. When enabled, it raises security alerts in Microsoft Defender for Cloud for behavior such as:
- Potential SQL injection attempts against the Cosmos DB query API
- Access from unusual locations or by unfamiliar applications
- Suspicious extraction of large data volumes
- Access using a leaked or unusual connection string or key
Note: "Advanced Threat Protection" and "Microsoft Defender for Azure Cosmos DB" refer to the same capability. Microsoft renamed the Defender plans over time, so older docs, ARM templates, and CLI flags still use the advanced-threat-protection terminology.
Why it matters
A Cosmos DB account often sits behind a public-facing application, holding user records, session data, telemetry, or transactional information. Without threat detection, an attacker who gets a foothold can probe and exfiltrate data with no signal reaching your security team.
Consider a few realistic scenarios:
Leaked connection strings
Cosmos DB keys and connection strings turn up in committed source code, CI logs, and misconfigured app settings more often than anyone would like. With Defender enabled, the first use of that key from an unfamiliar IP or application generates an alert. Without it, the attacker quietly reads your collections at their own pace.
Injection through the application layer
If your app builds Cosmos DB queries from user input without proper parameterization, an attacker can manipulate query logic to read documents they should not see. Defender inspects query patterns and flags likely injection attempts, giving you a chance to respond before bulk data leaves.
Insider and supply-chain access
A compromised developer laptop or a malicious insider with read access can dump entire containers. Anomalous data extraction alerts catch the spike in read volume that normal application traffic would never produce.
Warning: Threat protection is a detection control, not a prevention control. It tells you something bad is happening, but it will not block the request. Treat it as one layer alongside private endpoints, key rotation, and least-privilege access, not a replacement for them.
The business impact is the usual chain: undetected breach, regulatory exposure under GDPR or HIPAA depending on the data, and the cleanup cost of an incident you found out about from a third party instead of your own tooling.
How to fix it
You can enable threat protection on a single account, or turn on the Defender plan across the whole subscription. Pick based on how broadly Cosmos DB is used in your environment.
Option 1: Azure Portal (single account)
- Open the Azure portal and navigate to your Cosmos DB account.
- In the left menu, under Settings, select Microsoft Defender for Cloud.
- Set Microsoft Defender for Azure Cosmos DB to On.
- Save the change.
Option 2: Azure CLI (single account)
Enable advanced threat protection on a specific account by its resource ID:
RESOURCE_ID=$(az cosmosdb show \
--name my-cosmos-account \
--resource-group my-rg \
--query id -o tsv)
az security atp cosmosdb update \
--resource-group my-rg \
--cosmosdb-account my-cosmos-account \
--is-enabled true
Confirm it is on:
az security atp cosmosdb show \
--resource-group my-rg \
--cosmosdb-account my-cosmos-account
Option 3: Subscription-wide Defender plan
If you run many Cosmos DB accounts, enabling the Defender plan at the subscription level covers existing and future accounts automatically.
az security pricing create \
--name CosmosDbs \
--tier Standard
Warning: The Standard Defender plan for Cosmos DB is billed per 100 request units per second (RU/s) provisioned. Costs scale with your throughput, so estimate before flipping it on subscription-wide across high-throughput accounts. Check the current Defender for Cloud pricing page for the rate in your region.
Option 4: Infrastructure as Code
For Terraform, manage the setting on the account resource so drift gets caught on the next plan:
resource "azurerm_cosmosdb_account" "this" {
name = "my-cosmos-account"
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
offer_type = "Standard"
kind = "GlobalDocumentDB"
consistency_policy {
consistency_level = "Session"
}
geo_location {
location = azurerm_resource_group.this.location
failover_priority = 0
}
}
resource "azurerm_advanced_threat_protection" "cosmos" {
target_resource_id = azurerm_cosmosdb_account.this.id
enabled = true
}
The equivalent in Bicep:
resource cosmosAtp 'Microsoft.DocumentDB/databaseAccounts/providers/advancedThreatProtectionSettings@2019-01-01' = {
name: '${cosmosAccount.name}/Microsoft.Security/current'
properties: {
isEnabled: true
}
}
Tip: Make sure the alert email contacts in Defender for Cloud are set, otherwise the alerts fire into a dashboard nobody watches. Set them under Defender for Cloud > Environment settings > Email notifications so alerts reach your on-call rotation or SIEM.
How to prevent it from happening again
Manual fixes drift. The reliable approach is to enforce the setting through policy and catch it in your pipeline before deployment.
Azure Policy
There is a built-in policy initiative that audits Defender plans. For a deny-and-deploy approach, assign a custom policy with a deployIfNotExists effect so newly created Cosmos DB accounts have threat protection enabled automatically. The policy targets Microsoft.DocumentDB/databaseAccounts and checks the advanced threat protection setting under Microsoft.Security/advancedThreatProtectionSettings.
Assign the relevant built-in policy at the management group level so it applies everywhere:
az policy assignment create \
--name "enable-cosmos-defender" \
--display-name "Enable Defender for Cosmos DB" \
--scope "/providers/Microsoft.Management/managementGroups/my-mg" \
--policy "/providers/Microsoft.Authorization/policyDefinitions/<defender-cosmos-policy-id>" \
--location eastus \
--mi-system-assigned
CI/CD gate with Lensix
Run the cosmosdb_nothreatprotection check in your deployment pipeline and fail the build if any new account would ship without threat protection. Combined with the Terraform or Bicep block above, the setting becomes part of the resource definition, and a reviewer sees it in the diff during code review.
Tip: Pair the policy-as-code gate with a scheduled Lensix scan. The pipeline gate stops new violations, and the scheduled scan catches accounts created out-of-band, for example through ClickOps in the portal or by a separate team.
Best practices
Threat protection is most useful as part of a layered posture for Cosmos DB. A few practices that compound well with it:
- Disable key-based auth where possible. Use Microsoft Entra ID authentication and role-based access control for the data plane instead of master keys, which removes the leaked-key risk entirely.
- Lock down network access. Use private endpoints or IP firewall rules so the account is not reachable from the public internet by default.
- Rotate keys on a schedule. If you still use keys, rotate them regularly and treat any key found in source control as compromised.
- Route alerts to your SIEM. Forward Defender for Cloud alerts to Microsoft Sentinel or your existing SIEM so Cosmos DB detections land in the same workflow as the rest of your security signals.
- Enable diagnostic logging. Send Cosmos DB data plane logs to a Log Analytics workspace so that when an alert fires, you have the query and access detail to investigate it.
A detection control you never read is the same as no control at all. Enabling Defender for Cosmos DB is step one; wiring its alerts into a place your team actually looks is what turns it into protection.
Turn it on, enforce it in policy, and make sure the alerts reach someone. That combination closes the gap this check is built to find.

