aws-dynamodb-streams-read

dynamodb:GetShardIterator + dynamodb:GetRecords on a DynamoDB Stream yields real-time access to all item-level changes, including full item images depending on StreamViewType.

derived aws emits CanReadData

match

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

{'principal': None} HasPermission {'stream': None} {'stream': None} LocatedIn {'table': None}

where

node_type(?stream) == Messaging node_type(?table) == NoSQLDatabase ?stream.provider_type == 'AWS::DynamoDB::Stream' or arn_matches(?stream, ':table/*/stream/*') ?principal has EFFECTIVE dynamodb:GetShardIterator on ?stream ARN ?principal has EFFECTIVE dynamodb:GetRecords on ?stream ARN

emit

source typeIdentity
target typeNoSQLDatabase
source?principal
target?table
permissionsdynamodb:GetShardIterator dynamodb:GetRecords
conditionsiam_permission resource_policy service_state
state logicACTIVE when BOTH dynamodb:GetShardIterator AND dynamodb:GetRecords are confirmed EFFECTIVE on the stream ARN and the parent table has DynamoDB Streams enabled (StreamSpecification.StreamEnabled == true). CONDITIONAL(service_state) when Streams is not enabled on the parent table — GetShardIterator and GetRecords succeed only for the 24-hour shard retention window; after 24 hours with no new writes the stream is effectively empty. CONDITIONAL(resource_policy) when a stream resource policy exists but its evaluation is unresolved. BLOCKED by an explicit SCP or deny on either GetShardIterator or GetRecords. The stream only captures CHANGES since stream enablement — it does NOT provide historical data for items written before Streams was enabled.

Narrative

{principal.name} can read the DynamoDB stream of {table.name} (dynamodb:GetShardIterator + GetRecords), accessing a real-time feed of all item mutations{if streamViewType != KEYS_ONLY: " including full item images"}.

Raw rule rules/derived/aws/dynamodb.yaml

id: aws-dynamodb-streams-read
emits: CanReadData
description: dynamodb:GetShardIterator + dynamodb:GetRecords on a DynamoDB Stream yields real-time access
  to all item-level changes, including full item images depending on StreamViewType.
match:
- - principal: null
  - HasPermission
  - stream: null
- - stream: null
  - LocatedIn
  - table: null
where:
- node_type(?stream) == Messaging
- node_type(?table) == NoSQLDatabase
- ?stream.provider_type == 'AWS::DynamoDB::Stream' or arn_matches(?stream, ':table/*/stream/*')
- ?principal has EFFECTIVE dynamodb:GetShardIterator on ?stream ARN
- ?principal has EFFECTIVE dynamodb:GetRecords on ?stream ARN
emit:
  source_type: Identity
  target_type: NoSQLDatabase
  source: ?principal
  target: ?table
  permissions:
  - dynamodb:GetShardIterator
  - dynamodb:GetRecords
  conditions:
  - iam_permission
  - resource_policy
  - service_state
  state_logic: "ACTIVE when BOTH dynamodb:GetShardIterator AND dynamodb:GetRecords are confirmed EFFECTIVE\
    \ on the stream ARN and the parent table has DynamoDB Streams enabled (StreamSpecification.StreamEnabled\
    \ == true). CONDITIONAL(service_state) when Streams is not enabled on the parent table \u2014 GetShardIterator\
    \ and GetRecords succeed only for the 24-hour shard retention window; after 24 hours with no new writes\
    \ the stream is effectively empty. CONDITIONAL(resource_policy) when a stream resource policy exists\
    \ but its evaluation is unresolved. BLOCKED by an explicit SCP or deny on either GetShardIterator\
    \ or GetRecords. The stream only captures CHANGES since stream enablement \u2014 it does NOT provide\
    \ historical data for items written before Streams was enabled."
  confidence: min(contributing_confidences) * 0.90
  derived_from:
  - ?principal HasPermission ?stream (dynamodb:GetShardIterator + GetRecords effective)
  false_positive_note: "BOTH GetShardIterator AND GetRecords are required; GetShardIterator alone cannot\
    \ retrieve item data. The StreamViewType determines data richness: KEYS_ONLY reveals only partition/sort\
    \ keys (lower sensitivity); NEW_IMAGE, OLD_IMAGE, and NEW_AND_OLD_IMAGES reveal full item attribute\
    \ values (higher sensitivity). Emit with the parent table as target (CanReadData on the NoSQLDatabase);\
    \ the stream is the access mechanism, not the data target. Streams have a 24-hour shard retention;\
    \ old shards expire. SSE-KMS on the parent table does NOT additionally encrypt the stream \u2014 stream\
    \ records are always decryptable by a principal with GetRecords, regardless of the table CMK. Do NOT\
    \ emit CONDITIONAL(key_permission) for stream access based on the parent table's SSE setting."
  narrative: '{principal.name} can read the DynamoDB stream of {table.name} (dynamodb:GetShardIterator
    + GetRecords), accessing a real-time feed of all item mutations{if streamViewType != KEYS_ONLY: "
    including full item images"}.'
move · open · esc close