azure-cognitivesearch-query-index-via-key
A principal that can obtain an admin or query key (via ExposesCredential) can issue search, suggest, and autocomplete queries against all indexes in the service, reading the full content of matching indexed documents.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'service': None}
ExposesCredential {'apikey': None}
{'principal': None} HasPermission {'service': None}
where
node_class(?service) == Data and node_type(?service) ==
SearchService
?service.provider_type == 'Microsoft.Search/searchServices'
node_class(?apikey) == Secret and node_type(?apikey) == APIKey
(?apikey.properties.scope == 'admin' OR tag(?apikey, 'key-type') == 'admin') OR (?apikey.properties.scope == 'query' OR tag(?apikey, 'key-type') == 'query')
?principal has EFFECTIVE Microsoft.Search/searchServices/listAdminKeys/action OR Microsoft.Search/searchServices/listQueryKeys/action at ?service scope (Search Service Contributor 7ca78c08-252a-4471-8644-bb5ff32d4ba0, Contributor, Owner, or a custom role granting either action)
?service.properties.disableLocalAuth != true # keys are disabled when disableLocalAuth is true
?apikey was produced by azure-cognitivesearch-list-admin-keys or azure-cognitivesearch-list-query-keys
emit
| source type | Identity |
|---|---|
| target type | Data |
| source | ?principal |
| target | <all indexes (Data nodes) within ?service> |
| permissions | Microsoft.Search/searchServices/listAdminKeys/action Microsoft.Search/searchServices/listQueryKeys/action |
| conditions | iam_permission network_reachability |
| state logic | ACTIVE when ?principal can obtain a key (listAdminKeys or listQueryKeys) AND disableLocalAuth != true AND the search service data-plane endpoint is network-reachable (publicNetworkAccess not Disabled, OR principal has network access via private endpoint). CONDITIONAL(network_reachability) when publicNetworkAccess is Disabled — the ARM-plane key extraction remains possible but the extracted key cannot be used against the data-plane endpoint from outside the private network. BLOCKED if a deny assignment covers the listing action OR if disableLocalAuth == true. CONDITIONAL(service_state) if disableLocalAuth is unknown/unresolved. |
Narrative
{principal.name} can obtain an API key for search service {service.name} (listAdminKeys or listQueryKeys) and use it to query all indexes, reading the full content of matching indexed documents. Indexed documents may contain PII, sensitive business data, secrets, or other high-value information ingested from connected data sources (Azure Storage, Cosmos DB, SQL, SharePoint).
Raw rule rules/derived/azure/cognitivesearch.yaml
id: azure-cognitivesearch-query-index-via-key
emits: CanReadData
description: A principal that can obtain an admin or query key (via ExposesCredential) can issue search,
suggest, and autocomplete queries against all indexes in the service, reading the full content of matching
indexed documents.
match:
- - service: null
- ExposesCredential
- apikey: null
- - principal: null
- HasPermission
- service: null
where:
- node_class(?service) == Data and node_type(?service) == SearchService
- ?service.provider_type == 'Microsoft.Search/searchServices'
- node_class(?apikey) == Secret and node_type(?apikey) == APIKey
- (?apikey.properties.scope == 'admin' OR tag(?apikey, 'key-type') == 'admin') OR (?apikey.properties.scope
== 'query' OR tag(?apikey, 'key-type') == 'query')
- ?principal has EFFECTIVE Microsoft.Search/searchServices/listAdminKeys/action OR Microsoft.Search/searchServices/listQueryKeys/action
at ?service scope (Search Service Contributor 7ca78c08-252a-4471-8644-bb5ff32d4ba0, Contributor, Owner,
or a custom role granting either action)
- '?service.properties.disableLocalAuth != true # keys are disabled when disableLocalAuth is true'
- ?apikey was produced by azure-cognitivesearch-list-admin-keys or azure-cognitivesearch-list-query-keys
emit:
source_type: Identity
target_type: Data
source: ?principal
target: <all indexes (Data nodes) within ?service>
permissions:
- Microsoft.Search/searchServices/listAdminKeys/action
- Microsoft.Search/searchServices/listQueryKeys/action
conditions:
- iam_permission
- network_reachability
state_logic: "ACTIVE when ?principal can obtain a key (listAdminKeys or listQueryKeys) AND disableLocalAuth\
\ != true AND the search service data-plane endpoint is network-reachable (publicNetworkAccess not\
\ Disabled, OR principal has network access via private endpoint). CONDITIONAL(network_reachability)\
\ when publicNetworkAccess is Disabled \u2014 the ARM-plane key extraction remains possible but the\
\ extracted key cannot be used against the data-plane endpoint from outside the private network. BLOCKED\
\ if a deny assignment covers the listing action OR if disableLocalAuth == true. CONDITIONAL(service_state)\
\ if disableLocalAuth is unknown/unresolved."
confidence: 0.88
derived_from:
- 'ExposesCredential: ?service -> ?apikey (azure-cognitivesearch-list-admin-keys or azure-cognitivesearch-list-query-keys)'
- 'HasPermission: listAdminKeys/action or listQueryKeys/action at ?service scope'
- ?service.properties.publicNetworkAccess and ?service.properties.disableLocalAuth
false_positive_note: "Gate on BOTH disableLocalAuth and network reachability: (a) disableLocalAuth ==\
\ true: keys are disabled \u2014 CanReadData via key is not achievable regardless of network; emit\
\ BLOCKED or do not emit. (b) publicNetworkAccess == Disabled and no confirmed private-network foothold:\
\ the extracted key cannot reach the data-plane endpoint \u2014 emit CONDITIONAL(network_reachability).\
\ Do NOT conflate ARM-plane reachability (listAdminKeys) with data-plane endpoint reachability (https://*.search.windows.net).\
\ Query keys are read-only (search/suggest/autocomplete); admin keys additionally allow index management\
\ and document writes \u2014 but both yield CanReadData on the index content for attack-path purposes\
\ (read is the dominant sensitivity). A principal holding only Search Index Data Reader RBAC (Entra)\
\ does NOT need a key and reaches this edge via a separate RBAC-based path; that path emits CanReadData\
\ directly without ExposesCredential (see azure-cognitivesearch-rbac-data-read)."
narrative: '{principal.name} can obtain an API key for search service {service.name} (listAdminKeys
or listQueryKeys) and use it to query all indexes, reading the full content of matching indexed documents.
Indexed documents may contain PII, sensitive business data, secrets, or other high-value information
ingested from connected data sources (Azure Storage, Cosmos DB, SQL, SharePoint).'