Back to Checks
Cosmos DB account uses private endpoint connections
cosmosdb_account_use_private_endpoints
Service: cosmosdbSeverity: high
OfficialBuilt-inVerified
Categories:internet-exposedtrust-boundaries
Resource Type:microsoft.documentdb/databaseaccounts
Azure Cosmos DB accounts are assessed for private endpoint connections that keep data-plane traffic on private IPs within authorized virtual networks.
Risk
Without private endpoints, access may use public endpoints or broad IP rules, enabling:
- interception and credential replay
- unauthorized queries and data exfiltration
- lateral movement via exposed paths
This degrades confidentiality and can impact availability under abusive traffic.
Run this check with Prowler
Run in Prowler CloudRun
prowler azure --checks cosmosdb_account_use_private_endpointsRecommendation
Adopt Azure Private Link for Cosmos DB:
- Create private endpoints for required subresources
- Link a private DNS zone so clients resolve to private IPs
- Set
PublicNetworkAccess=Disabled; keep tight firewall rules - Allow only needed VNets/subnets; apply NSGs
- Enforce least privilege and monitor access patterns
Remediation
CLI
az network private-endpoint create --name <example_resource_name> --resource-group <example_resource_name> --vnet-name <example_resource_name> --subnet <example_resource_name> --private-connection-resource-id /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<example_resource_name>/providers/Microsoft.DocumentDB/databaseAccounts/<example_resource_name> --group-ids Sql --connection-name <example_resource_name>Terraform
# Create a Private Endpoint to a Cosmos DB account (adds a private endpoint connection)
resource "azurerm_private_endpoint" "<example_resource_name>" {
name = "<example_resource_name>"
location = "<location>"
resource_group_name = "<example_resource_name>"
subnet_id = "<example_subnet_id>"
private_service_connection {
name = "<example_resource_name>"
private_connection_resource_id = "<example_cosmosdb_account_id>" # CRITICAL: Cosmos DB account ID
subresource_names = ["Sql"] # CRITICAL: targets Cosmos DB subresource to create the connection
}
}NativeIaC
// Create a Private Endpoint to a Cosmos DB account (adds a private endpoint connection)
resource pe 'Microsoft.Network/privateEndpoints@2025-05-01' = {
name: '<example_resource_name>'
location: resourceGroup().location
properties: {
subnet: { id: '<example_subnet_id>' }
privateLinkServiceConnections: [
{
name: 'conn'
properties: {
privateLinkServiceId: '<example_cosmosdb_account_id>' // CRITICAL: attaches PE to the Cosmos DB account
groupIds: ['Sql'] // CRITICAL: targets Cosmos DB NoSQL subresource so the connection is created
}
}
]
}
}Other
1In Azure Portal, open your Cosmos DB account
2Go to Networking > Private access
3Click + Private endpoint
4Resource type: Microsoft.AzureCosmosDB/databaseAccounts; Resource: select your account; Target subresource: Sql
5Select your Virtual network and Subnet
6Click Review + create, then Create
7Verify the private endpoint connection appears under Networking > Private access
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.cosmosdb.cosmosdb_client import cosmosdb_client
class cosmosdb_account_use_private_endpoints(Check):
def execute(self) -> Check_Report_Azure:
findings = []
for subscription, accounts in cosmosdb_client.accounts.items():
subscription_name = cosmosdb_client.subscriptions.get(
subscription, subscription
)
for account in accounts:
report = Check_Report_Azure(metadata=self.metadata(), resource=account)
report.subscription = subscription
report.status = "FAIL"
report.status_extended = f"CosmosDB account {account.name} from subscription {subscription_name} ({subscription}) is not using private endpoints connections"
if account.private_endpoint_connections:
report.status = "PASS"
report.status_extended = f"CosmosDB account {account.name} from subscription {subscription_name} ({subscription}) is using private endpoints connections"
findings.append(report)
return findings