aws-dynamodb-dax-read-data
A principal with access to a DAX cluster (dax:GetItem / dax:Query / dax:Scan / dax:BatchGetItem) reads DynamoDB data through the cache, inheriting the DAX cluster's attached IAM role's DynamoDB permissions.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
HasPermission {'dax_cluster': None}
{'dax_cluster': None} ExecutesAs {'role': None}
{'role': None} HasPermission {'table': None}
where
node_type(?dax_cluster) ==
Cache
node_type(?table) == NoSQLDatabase
?dax_cluster.provider_type == 'AWS::DAX::Cluster'
?table.provider_type in ['AWS::DynamoDB::Table', 'AWS::DynamoDB::GlobalTable']
?principal has EFFECTIVE at least ONE of: dax:GetItem, dax:Query, dax:Scan, dax:BatchGetItem on ?dax_cluster
?role has EFFECTIVE at least ONE of: dynamodb:GetItem, dynamodb:Query, dynamodb:Scan on ?table ARN
emit
| source type | Identity |
|---|---|
| target type | NoSQLDatabase |
| source | ?principal |
| target | ?table |
| permissions | dax:GetItem dax:Query dax:Scan dax:BatchGetItem |
| conditions | iam_permission network_reachability service_state |
| state logic | ACTIVE when the principal has at least one DAX read action (including dax:BatchGetItem) effective on the DAX cluster AND the DAX cluster's attached role has the corresponding DynamoDB read action effective on a target table AND the principal can reach the DAX cluster endpoint (DAX is VPC-only — network_reachability condition). CONDITIONAL(network_reachability) when the principal does not have a proven network path to the DAX cluster endpoint (DAX clusters are VPC-internal; requires EC2 foothold or VPC peering in the same subnet/VPC as the cluster). CONDITIONAL(service_state) when the DAX cluster is in a non-AVAILABLE status. BLOCKED when an SCP or permission-boundary denies the DAX read action. Note: DAX clusters are not accessible from outside the VPC without explicit VPC connectivity — the network_reachability gate is almost always required for external-attacker scenarios. |
Narrative
{principal.name} can query DynamoDB through the DAX cluster {dax_cluster.name} (dax:GetItem / dax:Query / dax:Scan / dax:BatchGetItem), reading DynamoDB data via the DAX role {role.name}'s permissions - network reach to the DAX VPC endpoint is required.
Raw rule rules/derived/aws/dynamodb.yaml
id: aws-dynamodb-dax-read-data
emits: CanReadData
description: A principal with access to a DAX cluster (dax:GetItem / dax:Query / dax:Scan / dax:BatchGetItem)
reads DynamoDB data through the cache, inheriting the DAX cluster's attached IAM role's DynamoDB permissions.
match:
- - principal: null
- HasPermission
- dax_cluster: null
- - dax_cluster: null
- ExecutesAs
- role: null
- - role: null
- HasPermission
- table: null
where:
- node_type(?dax_cluster) == Cache
- node_type(?table) == NoSQLDatabase
- ?dax_cluster.provider_type == 'AWS::DAX::Cluster'
- ?table.provider_type in ['AWS::DynamoDB::Table', 'AWS::DynamoDB::GlobalTable']
- '?principal has EFFECTIVE at least ONE of: dax:GetItem, dax:Query, dax:Scan, dax:BatchGetItem on ?dax_cluster'
- '?role has EFFECTIVE at least ONE of: dynamodb:GetItem, dynamodb:Query, dynamodb:Scan on ?table ARN'
emit:
source_type: Identity
target_type: NoSQLDatabase
source: ?principal
target: ?table
permissions:
- dax:GetItem
- dax:Query
- dax:Scan
- dax:BatchGetItem
conditions:
- iam_permission
- network_reachability
- service_state
state_logic: "ACTIVE when the principal has at least one DAX read action (including dax:BatchGetItem)\
\ effective on the DAX cluster AND the DAX cluster's attached role has the corresponding DynamoDB\
\ read action effective on a target table AND the principal can reach the DAX cluster endpoint (DAX\
\ is VPC-only \u2014 network_reachability condition). CONDITIONAL(network_reachability) when the principal\
\ does not have a proven network path to the DAX cluster endpoint (DAX clusters are VPC-internal;\
\ requires EC2 foothold or VPC peering in the same subnet/VPC as the cluster). CONDITIONAL(service_state)\
\ when the DAX cluster is in a non-AVAILABLE status. BLOCKED when an SCP or permission-boundary denies\
\ the DAX read action. Note: DAX clusters are not accessible from outside the VPC without explicit\
\ VPC connectivity \u2014 the network_reachability gate is almost always required for external-attacker\
\ scenarios."
confidence: min(contributing_confidences) * 0.85
derived_from:
- ?principal HasPermission ?dax_cluster (dax:GetItem / dax:Query / dax:Scan / dax:BatchGetItem effective)
- ?dax_cluster ExecutesAs ?role
false_positive_note: "DAX is VPC-only. A principal without a VPC foothold (EC2 instance, Lambda in the\
\ same VPC, or VPN/Transit Gateway connectivity) cannot reach the DAX cluster endpoint \u2014 always\
\ CONDITIONAL(network_reachability) for principals that are not colocated. The DAX cluster role determines\
\ WHICH DynamoDB tables are accessible; a role with dynamodb:GetItem on arn:aws:dynamodb:*:*:table/SensitiveTable\
\ gives DAX-mediated access to that table. dax:BatchGetItem is a bulk-read action (analogous to dynamodb:BatchGetItem)\
\ that reads multiple items in a single call. The DAX cache may serve stale data (cache hits bypass\
\ DynamoDB); the principal reads whatever the cache has, which may be slightly behind the source of\
\ truth. DAX is not a data exfiltration vector on its own \u2014 it is a read cache; exfiltration\
\ still requires bulk operations (dax:Scan, dax:Query with filter expressions, or dax:BatchGetItem\
\ with large batches) and iterating all partition keys."
narrative: "{principal.name} can query DynamoDB through the DAX cluster {dax_cluster.name} (dax:GetItem\
\ / dax:Query / dax:Scan / dax:BatchGetItem), reading DynamoDB data via the DAX role {role.name}'s\
\ permissions \u2014 network reach to the DAX VPC endpoint is required."