aws-dynamodb-restore-backup-read
dynamodb:RestoreTableFromBackup restores a table from an on-demand backup; reading it requires separate GetItem/Scan/Query permission on the restored table ARN (CONDITIONAL path).
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?backup) ==
Backup
?backup.provider_type == 'AWS::DynamoDB::Backup'
?principal has EFFECTIVE dynamodb:RestoreTableFromBackup on ?backup ARN
?backup.properties.BackupStatus == 'AVAILABLE'
emit
| source type | Identity |
|---|---|
| target type | NoSQLDatabase |
| source | ?principal |
| target | <source table of the backup> |
| permissions | dynamodb:RestoreTableFromBackup |
| conditions | iam_permission scp_or_org_policy service_state |
| state logic | CONDITIONAL(iam_permission) when dynamodb:RestoreTableFromBackup is confirmed EFFECTIVE on the backup ARN AND the backup status is AVAILABLE. RestoreTableFromBackup creates a NEW table but does NOT automatically grant the restoring principal read access to the NEW table's ARN. The principal must have a SEPARATE, confirmed EFFECTIVE permission (dynamodb:GetItem, dynamodb:Query, or dynamodb:Scan) on the newly-restored table's ARN. This typically requires a wildcard permission (e.g., dynamodb:GetItem on arn:aws:dynamodb:*:*:table/*) or explicit grant. Emit as CONDITIONAL(iam_permission); upgrade to ACTIVE only when an aws-dynamodb-read-data edge is confirmed on the restored table ARN. CONDITIONAL(service_state) when backup status is not AVAILABLE (e.g., DELETED, CREATING). BLOCKED by an SCP or permission-boundary deny on RestoreTableFromBackup. |
Narrative
{principal.name} can restore a copy of {table.name} from an on-demand backup (dynamodb:RestoreTableFromBackup), creating a new table with historical item data. Reading the new table requires a separate GetItem/Scan/Query permission on the restored table ARN.
Raw rule rules/derived/aws/dynamodb.yaml
id: aws-dynamodb-restore-backup-read
emits: CanReadData
description: dynamodb:RestoreTableFromBackup restores a table from an on-demand backup; reading it requires
separate GetItem/Scan/Query permission on the restored table ARN (CONDITIONAL path).
match:
- - principal: null
- HasPermission
- backup: null
where:
- node_type(?backup) == Backup
- ?backup.provider_type == 'AWS::DynamoDB::Backup'
- ?principal has EFFECTIVE dynamodb:RestoreTableFromBackup on ?backup ARN
- ?backup.properties.BackupStatus == 'AVAILABLE'
emit:
source_type: Identity
target_type: NoSQLDatabase
source: ?principal
target: <source table of the backup>
permissions:
- dynamodb:RestoreTableFromBackup
conditions:
- iam_permission
- scp_or_org_policy
- service_state
state_logic: CONDITIONAL(iam_permission) when dynamodb:RestoreTableFromBackup is confirmed EFFECTIVE
on the backup ARN AND the backup status is AVAILABLE. RestoreTableFromBackup creates a NEW table but
does NOT automatically grant the restoring principal read access to the NEW table's ARN. The principal
must have a SEPARATE, confirmed EFFECTIVE permission (dynamodb:GetItem, dynamodb:Query, or dynamodb:Scan)
on the newly-restored table's ARN. This typically requires a wildcard permission (e.g., dynamodb:GetItem
on arn:aws:dynamodb:*:*:table/*) or explicit grant. Emit as CONDITIONAL(iam_permission); upgrade to
ACTIVE only when an aws-dynamodb-read-data edge is confirmed on the restored table ARN. CONDITIONAL(service_state)
when backup status is not AVAILABLE (e.g., DELETED, CREATING). BLOCKED by an SCP or permission-boundary
deny on RestoreTableFromBackup.
confidence: min(contributing_confidences) * 0.85
derived_from:
- ?principal HasPermission ?backup (dynamodb:RestoreTableFromBackup effective permission)
- ?backup.properties.BackupStatus == AVAILABLE
- aws-dynamodb-read-data (separate edge required on restored table ARN)
false_positive_note: "The backup must be in AVAILABLE status \u2014 RestoreTableFromBackup fails on\
\ DELETED or CREATING backups. Unlike RestoreTableToPointInTime, this rule does NOT require PITR to\
\ be enabled; on-demand backups are independent of PITR status. The restored table is created in the\
\ SAME ACCOUNT as the calling principal. CRITICAL: the principal MUST HAVE a confirmed EFFECTIVE GetItem/Scan/Query\
\ permission on the NEW restored table's ARN to read it; restore access alone does not grant read\
\ capability. This is a peer-level escalation to aws-dynamodb-restore-pitr-read but uses on-demand\
\ backups instead of PITR. The SSE key of the source table is inherited by the restored table \u2014\
\ additional CONDITIONAL(key_permission) applies if the source table uses a CMK the principal cannot\
\ decrypt."
narrative: '{principal.name} can restore a copy of {table.name} from an on-demand backup (dynamodb:RestoreTableFromBackup),
creating a new table with historical item data. Reading the new table requires a separate GetItem/Scan/Query
permission on the restored table ARN.'