Microsoft Defender for Cloud · Azure Cosmos DB
Azure Cosmos DB should disable public network access
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Azure Cosmos DB should disable public network access" check?
Flags any Azure Cosmos DB account where the 'publicNetworkAccess' property is set to Enabled, meaning the account's data-plane endpoint resolves to a public IP that any host on the internet can reach. It checks the account-wide network toggle only, across every API surface the account exposes, whether that is NoSQL, MongoDB, Cassandra, Gremlin or Table. It does not assess whether you have configured IP firewall rules, virtual network service endpoints or private endpoints, and it does not look at the data inside containers or at the authorisation model. An account can have a tight IP allow list and still flag here, because the control is about whether the public endpoint exists at all rather than how narrowly you have scoped it.
Why does "Azure Cosmos DB should disable public network access" matter?
With public access enabled, the Cosmos DB account is exposed to the whole internet and the only thing standing between an attacker and your data is the account key or token. Keys leak constantly through committed source, CI logs, browser bundles and stolen laptops, and a leaked key against a public endpoint is an immediate full read or write of every database in the account. Disabling public network access means the endpoint simply isn't routable from the internet, so a leaked credential is useless without a foothold inside your virtual network. For regulated data this is often the difference between a contained key-rotation incident and a reportable breach.
How do I fix "Azure Cosmos DB should disable public network access"?
- Provision an Azure Private Endpoint for the account in the subnet your application uses, then set public access off by running: az cosmosdb update --name <account> --resource-group <rg> --public-network-access Disabled. Confirm clients connect over the private DNS zone before cutting over production traffic.
- Bake the safe default into infrastructure as code: in Bicep set publicNetworkAccess: 'Disabled' on the Microsoft.DocumentDB/databaseAccounts resource so new accounts are never born public.
- Enforce it at scale by assigning the built-in policy 'Azure Cosmos DB should disable public network access'. Look the definition up by name rather than hardcoding its id: pid=$(az policy definition list --query "[?displayName=='Azure Cosmos DB should disable public network access'].name" -o tsv); az policy assignment create --name cosmos-no-public-net --policy "$pid" --scope <scope>.
Remediation script · bash
# 1. Give the account a private path IN before shutting the public one.
# --group-ids is the API sub-resource: Sql, MongoDB, Cassandra, Gremlin or Table.
RG=data-prod
ACCT=custprofiles-prod
VNET=spoke-data-vnet
SUBNET=db-subnet
SUB=$(az account show --query id -o tsv)
az network private-endpoint create \
--name "${ACCT}-pe" \
--resource-group "$RG" \
--vnet-name "$VNET" \
--subnet "$SUBNET" \
--private-connection-resource-id \
"/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.DocumentDB/databaseAccounts/$ACCT" \
--group-ids Sql \
--connection-name "${ACCT}-conn"
# 2. Once the endpoint is approved and private DNS resolves, shut the public route.
# --public-network-access Disabled takes precedence over any IP/VNet firewall rule.
az cosmosdb update \
--name "$ACCT" \
--resource-group "$RG" \
--public-network-access Disabled
# 3. Backstop: audit any future account that lacks private link or stays public.
# Look the built-in policies up by display name; never hardcode a definition GUID.
for disp in \
"CosmosDB accounts should use private link" \
"Azure Cosmos DB should disable public network access"; do
pid=$(az policy definition list \
--query "[?displayName=='$disp'].name | [0]" -o tsv)
az policy assignment create \
--name "audit-$(echo "$disp" | tr ' A-Z' '-a-z' | cut -c1-40)" \
--policy "$pid" \
--scope "/subscriptions/$SUB"
done Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure Cosmos DB.
Is "Azure Cosmos DB should disable public network access" a false positive?
An account fronting a public-facing read API with no private connectivity option may legitimately keep public access on while relying on an IP firewall allow list and per-request tokens. That is a deliberate, documented exception rather than a fix, so record the compensating controls and the data sensitivity, and prefer SecuredByPerimeter with a Network Security Perimeter where it is available before settling on a public endpoint.