azure-rediscache-listkeys-can-read-data

Retrieving the cache access key via listKeys/action yields full data-plane read of all cached data, subject to network reachability of the Redis endpoint.

derived azure emits CanReadData

match

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

{'principal': None} CanReadCredential {'accessKey': None} {'accessKey': None} CredentialsFor {'cache': None}

where

node_type(?cache) == Cache ?cache.provider_type == 'Microsoft.Cache/redis' node_type(?accessKey) == AccessKey

emit

source typeIdentity
target typeCache
source?principal
target?cache
permissionsMicrosoft.Cache/redis/listKeys/action
conditionsiam_permission network_reachability
state logicif a deny assignment or deny Azure Policy covers listKeys/action: BLOCKED; elif ?cache.properties.publicNetworkAccess == 'Disabled' AND no private endpoint reachable from caller: CONDITIONAL(network_reachability) — key is obtainable via ARM but the data-plane is not reachable; the path is possible if the caller gains a foothold in the VNet (e.g., via a private endpoint or VNet peering); elif ?cache.properties.publicNetworkAccess == 'Enabled' AND firewallRules restrict the caller's network: CONDITIONAL(network_reachability); elif ?cache.properties.publicNetworkAccess == 'Enabled' AND (firewallRules is empty OR contains a rule allowing the caller's IP): ACTIVE — the caller can retrieve the key via ARM and immediately connect to the Redis data endpoint. Note: Premium VNet-injected instances have publicNetworkAccess forced Disabled; treat as CONDITIONAL(network_reachability) unless the caller has VNet access.

Narrative

{principal.name} can retrieve the access key for {cache.name} via listKeys/action (ARM, network-unrestricted), then authenticate to the Redis data endpoint and read all cached data. Full data-plane access includes KEYS, GET, SCAN, DUMP, and CONFIG commands. Network reachability to the Redis endpoint is required for the data-plane step; the ARM key retrieval is unconditional.

Raw rule rules/derived/azure/rediscache.yaml

id: azure-rediscache-listkeys-can-read-data
emits: CanReadData
description: Retrieving the cache access key via listKeys/action yields full data-plane read of all cached
  data, subject to network reachability of the Redis endpoint.
match:
- - principal: null
  - CanReadCredential
  - accessKey: null
- - accessKey: null
  - CredentialsFor
  - cache: null
where:
- node_type(?cache) == Cache
- ?cache.provider_type == 'Microsoft.Cache/redis'
- node_type(?accessKey) == AccessKey
emit:
  source_type: Identity
  target_type: Cache
  source: ?principal
  target: ?cache
  permissions:
  - Microsoft.Cache/redis/listKeys/action
  conditions:
  - iam_permission
  - network_reachability
  state_logic: "if a deny assignment or deny Azure Policy covers listKeys/action: BLOCKED; elif ?cache.properties.publicNetworkAccess\
    \ == 'Disabled' AND no private endpoint reachable from caller: CONDITIONAL(network_reachability) \u2014\
    \ key is obtainable via ARM but the data-plane is not reachable; the path is possible if the caller\
    \ gains a foothold in the VNet (e.g., via a private endpoint or VNet peering); elif ?cache.properties.publicNetworkAccess\
    \ == 'Enabled' AND firewallRules restrict the caller's network: CONDITIONAL(network_reachability);\
    \ elif ?cache.properties.publicNetworkAccess == 'Enabled' AND (firewallRules is empty OR contains\
    \ a rule allowing the caller's IP): ACTIVE \u2014 the caller can retrieve the key via ARM and immediately\
    \ connect to the Redis data endpoint. Note: Premium VNet-injected instances have publicNetworkAccess\
    \ forced Disabled; treat as CONDITIONAL(network_reachability) unless the caller has VNet access."
  confidence: '0.95'
  derived_from:
  - "<CanReadCredential edge_id (principal \u2192 accessKey)>"
  - "<CredentialsFor edge_id (accessKey \u2192 cache)>"
  false_positive_note: "The key retrieval (ARM listKeys via CanReadCredential) is always ACTIVE when the\
    \ RBAC grant is confirmed; this CanReadData edge additionally requires network reachability to the\
    \ Redis data-plane endpoint (port 6380/SSL or 6379/non-SSL). When publicNetworkAccess=Disabled, the\
    \ data-plane is only reachable via private endpoint or (for Premium) the injected VNet \u2014 downgrade\
    \ to CONDITIONAL(network_reachability). For Standard/Premium tier, the Redis endpoint only accepts\
    \ key-based authentication (no Entra ID data-plane token auth); this rule correctly models the key-based\
    \ path. Do NOT emit ACTIVE for VNet-injected Premium instances without confirming VNet reachability."
  narrative: '{principal.name} can retrieve the access key for {cache.name} via listKeys/action (ARM,
    network-unrestricted), then authenticate to the Redis data endpoint and read all cached data. Full
    data-plane access includes KEYS, GET, SCAN, DUMP, and CONFIG commands. Network reachability to the
    Redis endpoint is required for the data-plane step; the ARM key retrieval is unconditional.'
move · open · esc close