azure-rediscache-listkeys-principal-read-credential
A principal with listKeys/action permission can retrieve the Redis access key via ARM, gaining read access to the credential.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
HasPermission {'cache': None}
{'cache': None} ExposesCredential {'accessKey': None}
where
node_type(?cache) ==
Cache
?cache.provider_type == 'Microsoft.Cache/redis'
node_type(?accessKey) == AccessKey
?principal has EFFECTIVE Microsoft.Cache/redis/listKeys/action at ?cache scope (Owner, Contributor, Redis Cache Contributor, or custom role)
emit
| source type | Identity |
|---|---|
| target type | AccessKey |
| source | ?principal |
| target | ?accessKey |
| permissions | Microsoft.Cache/redis/listKeys/action |
| conditions | iam_permission |
| state logic | if a deny assignment or deny Azure Policy covers listKeys/action at the effective scope: BLOCKED; else ACTIVE: the principal can call the ARM listKeys REST API (POST .../redis/{name}/listKeys) from any network and retrieve both the primaryKey and secondaryKey. This is an ARM control-plane action not gated by the Redis IP firewall (firewallRules) or publicNetworkAccess setting. |
Narrative
{principal.name} holds Microsoft.Cache/redis/listKeys/action on {cache.name}, allowing retrieval of the primary and secondary access keys via ARM.
Raw rule rules/derived/azure/rediscache.yaml
id: azure-rediscache-listkeys-principal-read-credential
emits: CanReadCredential
description: A principal with listKeys/action permission can retrieve the Redis access key via ARM, gaining
read access to the credential.
match:
- - principal: null
- HasPermission
- cache: null
- - cache: null
- ExposesCredential
- accessKey: null
where:
- node_type(?cache) == Cache
- ?cache.provider_type == 'Microsoft.Cache/redis'
- node_type(?accessKey) == AccessKey
- ?principal has EFFECTIVE Microsoft.Cache/redis/listKeys/action at ?cache scope (Owner, Contributor,
Redis Cache Contributor, or custom role)
emit:
source_type: Identity
target_type: AccessKey
source: ?principal
target: ?accessKey
permissions:
- Microsoft.Cache/redis/listKeys/action
conditions:
- iam_permission
state_logic: 'if a deny assignment or deny Azure Policy covers listKeys/action at the effective scope:
BLOCKED; else ACTIVE: the principal can call the ARM listKeys REST API (POST .../redis/{name}/listKeys)
from any network and retrieve both the primaryKey and secondaryKey. This is an ARM control-plane action
not gated by the Redis IP firewall (firewallRules) or publicNetworkAccess setting.'
confidence: '0.97'
derived_from:
- <HasPermission edge_id (listKeys/action)>
- "<ExposesCredential edge_id (cache \u2192 accessKey)>"
false_positive_note: "Verify the EFFECTIVE permission at the ?cache scope \u2014 do not infer from the\
\ role name alone. Redis Cache Contributor includes listKeys/action. The \"Cosmos DB Operator\" and\
\ \"SQL Server Contributor\" roles do NOT cover Microsoft.Cache resources. The ARM listKeys call succeeds\
\ regardless of firewallRules or publicNetworkAccess; this CanReadCredential edge is always ACTIVE\
\ when the RBAC grant is confirmed. Using the retrieved key against the Redis data-plane is separately\
\ gated by network_reachability (see azure-rediscache-listkeys-can-read-data)."
narrative: '{principal.name} holds Microsoft.Cache/redis/listKeys/action on {cache.name}, allowing retrieval
of the primary and secondary access keys via ARM.'