Skip to main content
Back to the Azure Footguns Database
SecurityMediumCommonAZF-0064

Cosmos DB master keys are on by default — full account access outside Entra ID and RBAC

Every Cosmos DB account ships with two master keys enabled. A key in a connection string is full access to all the data — no Entra ID, no RBAC, no conditional access, no per-user audit trail.

Footgun ID
AZF-0064 (Azure Footgun No. 64)
Azure service
Azure Cosmos DB
Resource type
Microsoft.DocumentDB/databaseAccounts
Updated
July 9, 2026

What it is

An Azure Cosmos DB account with key-based (local) authentication still enabled — the default on every account. The primary and secondary master keys are long-lived static secrets that grant complete data-plane access to every database and container in the account. They can't be scoped down, can't be gated by conditional access, and don't identify who is using them. Unless disableLocalAuth is set to true, everything you built on Entra ID sits next to a back door that ignores all of it.

Impact (security)
Anyone holding either account key has full data-plane read/write on every database in the account, with no identity attached
Basis: Azure behavior (authored assessment). Figures are estimates, not measurements.

Why it happens

Cosmos DB predates its own Entra ID data-plane RBAC, so key auth is the founding access model and the default the portal, SDK quickstarts, and a decade of sample code all reach for. disableLocalAuth defaults to false, and nothing in the create flow suggests changing it.

Keys spread the way connection strings always do: pasted into app settings, CI variables, local .env files, Slack threads, and old wiki pages. Rotating a key breaks every consumer at once, so rotation gets deferred indefinitely — which means the same secret that was shared two reorgs ago still works today. And because a key is not an identity, diagnostic logs can tell you that the account was read, but not by whom.

The fix has two halves: move callers to Entra ID auth (DefaultAzureCredential plus a Cosmos DB data-plane role assignment), then set disableLocalAuth: true so the keys stop being a parallel path. Skipping the second half leaves the back door open no matter how good the front door is.

What it costs / blast radius

One leaked key — from a committed .env file, an over-shared connection string, or a compromised CI system — is full read/write on every document in the account: customer records, session data, whatever the account holds. The attacker needs no phishing, no token, no MFA bypass; the key is the whole credential. Containment is equally blunt: you can't revoke access for one holder, only rotate the key for everyone at once. (Authored assessment of Azure behavior, not a measured statistic.)

See it

Footgun: the default — master keys accepted alongside Entra ID
resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2024-08-15' = {
  name: 'cosmos-prod'
  location: location
  properties: {
    databaseAccountOfferType: 'Standard'
    locations: [
      { locationName: location, failoverPriority: 0 }
    ]
    // disableLocalAuth omitted — both master keys grant full access
  }
}
Fix: disable key auth; callers use Entra ID with a data-plane role
resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2024-08-15' = {
  name: 'cosmos-prod'
  location: location
  properties: {
    databaseAccountOfferType: 'Standard'
    locations: [
      { locationName: location, failoverPriority: 0 }
    ]
    disableLocalAuth: true  // keys no longer authenticate
  }
}

// Data-plane access via Cosmos DB's built-in RBAC instead.
// App code switches to DefaultAzureCredential — no secret to leak.
resource dataAccess 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2024-08-15' = {
  parent: cosmos
  name: guid(cosmos.id, appPrincipalId, 'data-contributor')
  properties: {
    // Built-in Data Contributor role
    roleDefinitionId: '${cosmos.id}/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002'
    principalId: appPrincipalId
    scope: cosmos.id
  }
}

How StratoLens helps

StratoLens flags every Cosmos DB account that still accepts key auth, automatically and continuously, across all your subscriptions — inside your own tenant. Instead of hoping every team remembered disableLocalAuth, you get a standing list of the accounts where a leaked connection string is still a full-account credential.

Start Your 28-Day Free Trial

Every feature unlocked. Deploys to your Azure tenant. No data leaves your tenant.

Available now on the Azure Marketplace.

Not ready to install anything? Browse the Azure Footguns Database: 55+ documented ways Azure quietly costs money or creates risk.

Request a demo

StratoLens catches the cost waste, access risk, and config drift across your whole Azure estate, from inside your own tenant, so your data never leaves it.