azure-cosmosdb-readonlykeys-exposes-credential
readonlykeys/action returns Cosmos DB read-only master keys - bypasses data-plane RBAC for read operations across all databases and containers.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_class(?account) == Data and node_type(?account) ==
NoSQLDatabase
node_type(?account) matched provider_type == 'Microsoft.DocumentDB/databaseAccounts'
?principal has EFFECTIVE Microsoft.DocumentDB/databaseAccounts/readonlykeys/action at ?account scope
NOT ?principal has EFFECTIVE Microsoft.DocumentDB/databaseAccounts/listKeys/action at ?account scope # avoid double-emit; listKeys subsumes readonlykeys
emit
| source type | NoSQLDatabase |
|---|---|
| target type | AccessKey |
| source | ?account |
| target | <read-only primary/secondary AccessKey node(s) of ?account> |
| permissions | Microsoft.DocumentDB/databaseAccounts/readonlykeys/action |
| conditions | iam_permission |
| state logic | if deny assignment covers readonlykeys/action: BLOCKED; elif ?account.properties.disableLocalAuth == true: CONDITIONAL(service_state); else ACTIVE. ARM-plane call — not gated by IP firewall. |
Narrative
{principal.name} can call readonlykeys on {account.name} (Microsoft.DocumentDB/databaseAccounts/readonlykeys/action), retrieving the read-only primary and secondary keys. These keys bypass all Azure RBAC data-plane role assignments for read operations across all databases and containers, enabling unauthorized data exfiltration.
Raw rule rules/derived/azure/cosmosdb.yaml
id: azure-cosmosdb-readonlykeys-exposes-credential
emits: ExposesCredential
description: "readonlykeys/action returns Cosmos DB read-only master keys \u2014 bypasses data-plane RBAC\
\ for read operations across all databases and containers."
match:
- - principal: null
- HasPermission
- account: null
where:
- node_class(?account) == Data and node_type(?account) == NoSQLDatabase
- node_type(?account) matched provider_type == 'Microsoft.DocumentDB/databaseAccounts'
- ?principal has EFFECTIVE Microsoft.DocumentDB/databaseAccounts/readonlykeys/action at ?account scope
- 'NOT ?principal has EFFECTIVE Microsoft.DocumentDB/databaseAccounts/listKeys/action at ?account scope #
avoid double-emit; listKeys subsumes readonlykeys'
emit:
source_type: NoSQLDatabase
target_type: AccessKey
source: ?account
target: <read-only primary/secondary AccessKey node(s) of ?account>
permissions:
- Microsoft.DocumentDB/databaseAccounts/readonlykeys/action
conditions:
- iam_permission
state_logic: "if deny assignment covers readonlykeys/action: BLOCKED; elif ?account.properties.disableLocalAuth\
\ == true: CONDITIONAL(service_state); else ACTIVE. ARM-plane call \u2014 not gated by IP firewall."
confidence: '0.90'
derived_from:
- <HasPermission edge_id (readonlykeys/action)>
false_positive_note: "Emit only when the principal has readonlykeys but NOT listKeys \u2014 listKeys\
\ is a superset and azure-cosmosdb-listkeys-exposes-credential already covers that case. Read-only\
\ keys bypass RBAC for read but cannot write or delete items; CanExfiltrate is still applicable (data\
\ can be exfiltrated via read-only key). ARM-plane call, not gated by IP firewall. Cosmos DB Operator\
\ explicitly excludes readonlyKeys/* \u2014 verify notActions. disableLocalAuth=true: same treatment\
\ as listKeys."
narrative: '{principal.name} can call readonlykeys on {account.name} (Microsoft.DocumentDB/databaseAccounts/readonlykeys/action),
retrieving the read-only primary and secondary keys. These keys bypass all Azure RBAC data-plane role
assignments for read operations across all databases and containers, enabling unauthorized data exfiltration.'