azure-cosmosdb-readonlykeys-exfiltrate

Read-only keys (from readonlykeys/action) enable read-only data exfiltration across all databases and containers.

derived azure emits CanExfiltrate

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'account': None}

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 CanExfiltrate subsumes this ?account.properties.disableLocalAuth != true

emit

source typeIdentity
target typeNoSQLDatabase
source?principal
target?account
permissionsMicrosoft.DocumentDB/databaseAccounts/readonlykeys/action
conditionsiam_permission
state logicif deny assignment covers readonlykeys/action: BLOCKED; elif ?account.properties.disableLocalAuth == true: BLOCKED (key-based auth rejected at data endpoint); else ACTIVE. ARM-plane call — not gated by IP firewall.

Narrative

{principal.name} can retrieve read-only master keys from {account.name}, enabling read-only access to all data across all databases and containers. While this principal cannot write or delete data, complete data exfiltration via queries and point reads is possible.

Raw rule rules/derived/azure/cosmosdb.yaml

id: azure-cosmosdb-readonlykeys-exfiltrate
emits: CanExfiltrate
description: Read-only keys (from readonlykeys/action) enable read-only data exfiltration 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 CanExfiltrate subsumes this'
- ?account.properties.disableLocalAuth != true
emit:
  source_type: Identity
  target_type: NoSQLDatabase
  source: ?principal
  target: ?account
  permissions:
  - Microsoft.DocumentDB/databaseAccounts/readonlykeys/action
  conditions:
  - iam_permission
  state_logic: "if deny assignment covers readonlykeys/action: BLOCKED; elif ?account.properties.disableLocalAuth\
    \ == true: BLOCKED (key-based auth rejected at data endpoint); else ACTIVE. ARM-plane call \u2014\
    \ not gated by IP firewall."
  confidence: '0.85'
  derived_from:
  - <HasPermission edge_id (readonlykeys/action)>
  false_positive_note: "Read-only keys cannot write or delete \u2014 impact is limited to read exfiltration.\
    \ Emit only when readonlykeys is present but listKeys is not (listKeys subsumes this via azure-cosmosdb-listkeys-full-exfiltrate).\
    \ Lower confidence (0.85) than master-key path (0.95) due to read-only limitation. Cosmos DB Operator\
    \ explicitly excludes readonlykeys/* \u2014 verify notActions. disableLocalAuth=true blocks this path."
  narrative: '{principal.name} can retrieve read-only master keys from {account.name}, enabling read-only
    access to all data across all databases and containers. While this principal cannot write or delete
    data, complete data exfiltration via queries and point reads is possible.'
move · open · esc close