aws-dynamodb-write-data
dynamodb:PutItem / UpdateItem / DeleteItem / BatchWriteItem / TransactWriteItems grant item-level write access, enabling data poisoning (stream injection), TTL manipulation, and denial-of-service.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?table) ==
NoSQLDatabase
?table.provider_type in ['AWS::DynamoDB::Table', 'AWS::DynamoDB::GlobalTable']
?principal has EFFECTIVE at least ONE of: dynamodb:PutItem, dynamodb:UpdateItem, dynamodb:DeleteItem, dynamodb:BatchWriteItem, dynamodb:TransactWriteItems on ?table ARN
emit
| source type | Identity |
|---|---|
| target type | NoSQLDatabase |
| source | ?principal |
| target | ?table |
| permissions | dynamodb:PutItem dynamodb:UpdateItem dynamodb:DeleteItem dynamodb:BatchWriteItem dynamodb:TransactWriteItems |
| conditions | iam_permission resource_policy key_permission |
| state logic | ACTIVE when at least one of the write actions is confirmed EFFECTIVE on the table ARN (identity-based policy + resource policy evaluated + no SCP deny) AND the table's SSE uses the AWS-managed default key (alias/aws/dynamodb) or no SSE. Writing to a table does not require kms:Decrypt on an SSE CMK, but the DynamoDB service may need to decrypt existing data during an update operation — CONDITIONAL(key_permission) if table SSE uses a customer-managed CMK and the write path involves reading (UpdateItem with conditions, or Transact writes with conditions). For pure PutItem/DeleteItem without read-modify-write, SSE does not gate the write. CONDITIONAL(resource_policy) when a table resource policy exists but evaluation is unresolved. BLOCKED by an explicit SCP or permission-boundary deny on all write actions simultaneously. IAM condition keys dynamodb:LeadingKeys narrow access to specific partition keys — CONDITIONAL(condition_expression) when such conditions are present and the writable item scope is unclear. |
Narrative
{principal.name} can write items to DynamoDB table {table.name} via PutItem, UpdateItem, DeleteItem, BatchWriteItem, or TransactWriteItems (dynamodb:PutItem / UpdateItem / DeleteItem / BatchWriteItem / TransactWriteItems), enabling data poisoning, TTL manipulation, and denial-of-service attacks.
Raw rule rules/derived/aws/dynamodb.yaml
id: aws-dynamodb-write-data
emits: CanWriteData
description: dynamodb:PutItem / UpdateItem / DeleteItem / BatchWriteItem / TransactWriteItems grant item-level
write access, enabling data poisoning (stream injection), TTL manipulation, and denial-of-service.
match:
- - principal: null
- HasPermission
- table: null
where:
- node_type(?table) == NoSQLDatabase
- ?table.provider_type in ['AWS::DynamoDB::Table', 'AWS::DynamoDB::GlobalTable']
- '?principal has EFFECTIVE at least ONE of: dynamodb:PutItem, dynamodb:UpdateItem, dynamodb:DeleteItem,
dynamodb:BatchWriteItem, dynamodb:TransactWriteItems on ?table ARN'
emit:
source_type: Identity
target_type: NoSQLDatabase
source: ?principal
target: ?table
permissions:
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:BatchWriteItem
- dynamodb:TransactWriteItems
conditions:
- iam_permission
- resource_policy
- key_permission
state_logic: "ACTIVE when at least one of the write actions is confirmed EFFECTIVE on the table ARN\
\ (identity-based policy + resource policy evaluated + no SCP deny) AND the table's SSE uses the AWS-managed\
\ default key (alias/aws/dynamodb) or no SSE. Writing to a table does not require kms:Decrypt on an\
\ SSE CMK, but the DynamoDB service may need to decrypt existing data during an update operation \u2014\
\ CONDITIONAL(key_permission) if table SSE uses a customer-managed CMK and the write path involves\
\ reading (UpdateItem with conditions, or Transact writes with conditions). For pure PutItem/DeleteItem\
\ without read-modify-write, SSE does not gate the write. CONDITIONAL(resource_policy) when a table\
\ resource policy exists but evaluation is unresolved. BLOCKED by an explicit SCP or permission-boundary\
\ deny on all write actions simultaneously. IAM condition keys dynamodb:LeadingKeys narrow access\
\ to specific partition keys \u2014 CONDITIONAL(condition_expression) when such conditions are present\
\ and the writable item scope is unclear."
confidence: min(contributing_confidences) * 0.90
derived_from:
- ?principal HasPermission ?table (dynamodb:PutItem / UpdateItem / DeleteItem / BatchWriteItem / TransactWriteItems
effective permission)
- "messaging-chains:stream-injection-path (if table has stream \u2192 Lambda; data writes trigger Lambda\
\ execution)"
false_positive_note: "At least ONE of the five write actions must be effective; all being denied yields\
\ no write capability. IAM condition key dynamodb:LeadingKeys (partition-key scoping) restricts write\
\ access to items with specific partition keys \u2014 honor CONDITIONAL(condition_expression) when\
\ such conditions are present with non-trivial values. PutItem, UpdateItem, and TransactWriteItems\
\ have conditional-expression support (return values, etc.); these are application-layer controls,\
\ not IAM gates. A principal with UpdateItem can modify TTL, read-modify-write, or poison item data;\
\ all are write-capability realizations. If the table's stream feeds a Lambda (CanTrigger relationship\
\ exists), data writes trigger the Lambda; combine CanWriteData with the existing CanTrigger structural\
\ edge for the full stream-injection path (cite messaging-chains linchpin). SSE-KMS on a table does\
\ NOT gate pure writes (PutItem is write-only); it gates read-modify-write patterns (UpdateItem, TransactWriteItems\
\ with conditions). Do NOT emit CONDITIONAL(key_permission) for table SSE on a pure PutItem or DeleteItem."
narrative: '{principal.name} can write items to DynamoDB table {table.name} via PutItem, UpdateItem,
DeleteItem, BatchWriteItem, or TransactWriteItems (dynamodb:PutItem / UpdateItem / DeleteItem / BatchWriteItem
/ TransactWriteItems), enabling data poisoning, TTL manipulation, and denial-of-service attacks.'