azure-cognitivesearch-list-admin-keys

The search service exposes its primary and secondary admin API keys (discoverable via listAdminKeys/action by principals holding Search Service Contributor, Contributor, or Owner roles). Admin keys grant full data-plane control of the search service (all indexes, indexers, data sources, and queries).

derived azure emits ExposesCredential

match

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

{'service': None} {None: None} {'adminkey': None}

where

node_class(?service) == Data and node_type(?service) == SearchService ?service.provider_type == 'Microsoft.Search/searchServices' node_class(?adminkey) == Secret and node_type(?adminkey) == APIKey ?adminkey.properties.scope == 'admin' OR tag(?adminkey, 'key-type') == 'admin' ?service.properties.disableLocalAuth != true # keys are disabled when disableLocalAuth is true; do not emit if flag is set

emit

source typeData
target typeSecret
source?service
target?adminkey
permissionsMicrosoft.Search/searchServices/listAdminKeys/action
conditionsiam_permission
state logicACTIVE when ?service exists, ?adminkey is materialized from listAdminKeys API response, and disableLocalAuth == false. BLOCKED if disableLocalAuth == true (keys are server-side disabled). CONDITIONAL(service_state) if service state is unknown or disableLocalAuth is unknown/unresolved. Treat disableLocalAuth absent or null as equivalent to false (Azure default: keys enabled). This edge models the service exposing its admin key credential — it does not depend on network reachability (ARM plane is reachable from any network that can reach management.azure.com).

Narrative

Search service {service.name} exposes admin API keys (primary and secondary) via the listAdminKeys action. Any principal holding Microsoft.Search/searchServices/listAdminKeys/action (granted by Search Service Contributor, Contributor, or Owner) can retrieve these keys. Admin keys grant full data-plane control: read all indexed documents, create/delete/update indexes, manage indexers and data sources, and generate query keys - all without Entra authentication. This is the highest-privilege data-plane credential for the service.

Raw rule rules/derived/azure/cognitivesearch.yaml

id: azure-cognitivesearch-list-admin-keys
emits: ExposesCredential
description: The search service exposes its primary and secondary admin API keys (discoverable via listAdminKeys/action
  by principals holding Search Service Contributor, Contributor, or Owner roles). Admin keys grant full
  data-plane control of the search service (all indexes, indexers, data sources, and queries).
match:
- - service: null
  - null: null
  - adminkey: null
where:
- node_class(?service) == Data and node_type(?service) == SearchService
- ?service.provider_type == 'Microsoft.Search/searchServices'
- node_class(?adminkey) == Secret and node_type(?adminkey) == APIKey
- ?adminkey.properties.scope == 'admin' OR tag(?adminkey, 'key-type') == 'admin'
- '?service.properties.disableLocalAuth != true  # keys are disabled when disableLocalAuth is true; do
  not emit if flag is set'
emit:
  source_type: Data
  target_type: Secret
  source: ?service
  target: ?adminkey
  permissions:
  - Microsoft.Search/searchServices/listAdminKeys/action
  conditions:
  - iam_permission
  state_logic: "ACTIVE when ?service exists, ?adminkey is materialized from listAdminKeys API response,\
    \ and disableLocalAuth == false. BLOCKED if disableLocalAuth == true (keys are server-side disabled).\
    \ CONDITIONAL(service_state) if service state is unknown or disableLocalAuth is unknown/unresolved.\
    \ Treat disableLocalAuth absent or null as equivalent to false (Azure default: keys enabled). This\
    \ edge models the service exposing its admin key credential \u2014 it does not depend on network reachability\
    \ (ARM plane is reachable from any network that can reach management.azure.com)."
  confidence: 0.93
  derived_from:
  - "Collector normalization: Microsoft.Search/searchServices/listAdminKeys/action \u2192 APIKey node"
  - ?service.properties.disableLocalAuth == false (or not set, per Azure default)
  false_positive_note: "CRITICAL gate: if ?service.properties.disableLocalAuth == true, admin keys are\
    \ inactive and cannot authenticate to the data plane \u2014 do NOT emit. Do not emit if ?adminkey.properties.scope\
    \ != 'admin' or the key is inferred rather than explicitly materialized."
  narrative: "Search service {service.name} exposes admin API keys (primary and secondary) via the listAdminKeys\
    \ action. Any principal holding Microsoft.Search/searchServices/listAdminKeys/action (granted by Search\
    \ Service Contributor, Contributor, or Owner) can retrieve these keys. Admin keys grant full data-plane\
    \ control: read all indexed documents, create/delete/update indexes, manage indexers and data sources,\
    \ and generate query keys \u2014 all without Entra authentication. This is the highest-privilege data-plane\
    \ credential for the service."
move · open · esc close