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).

derived aws emits CanReadData

match

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

{'principal': None} HasPermission {'backup': None}

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 typeIdentity
target typeNoSQLDatabase
source?principal
target<source table of the backup>
permissionsdynamodb:RestoreTableFromBackup
conditionsiam_permission scp_or_org_policy service_state
state logicCONDITIONAL(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.'
move · open · esc close