aws-qldb-sendcommand-read-data

qldb:SendCommand on an ALLOW_ALL-mode ledger allows the caller to run arbitrary PartiQL SELECT statements against all tables, yielding full data-plane read of all committed document revisions.

derived aws emits CanReadData

match

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

{'principal': None} HasPermission {'ledger': None}

where

node_type(?ledger) == NoSQLDatabase ?ledger.provider_type == 'AWS::QLDB::Ledger' effective_action(?principal, ?ledger) includes 'qldb:SendCommand' (?ledger.properties.permissionsMode == 'ALLOW_ALL') OR (?ledger.properties.permissionsMode == 'STANDARD' AND effective_action(?principal, ?ledger) includes 'qldb:UpdateLedgerPermissionsMode')

emit

source typeIdentity
target typeNoSQLDatabase
source?principal
target?ledger
permissionsqldb:SendCommand
conditionsiam_permission key_permission
state logicif ?ledger.properties.permissionsMode == 'ALLOW_ALL' AND effective_action(?principal, ?ledger) includes 'qldb:SendCommand': if ?ledger.encryptionDescription.kmsKeyArn is a customer-managed key (not 'AWS_OWNED_KMS_KEY'): CONDITIONAL(key_permission) — the QLDB service (qldb.amazonaws.com, not the IAM caller) must have kms:Decrypt on the CMK via a KMS grant in the key policy. This is a service-level permission fact collected from the KMS key policy, not an IAM caller permission. Emit ACTIVE when the KMS grant for qldb.amazonaws.com is confirmed; emit CONDITIONAL(key_permission) when unknown. else: ACTIVE. if ?ledger.properties.permissionsMode == 'STANDARD' AND effective_action(?principal, ?ledger) includes 'qldb:SendCommand' AND effective_action(?principal, ?ledger) includes 'qldb:UpdateLedgerPermissionsMode': CONDITIONAL(service_state) — principal can downgrade to ALLOW_ALL then read all data; downgrade must happen first. else: do not emit.

Narrative

{principal.name} can initiate a QLDB session (qldb:SendCommand) on {ledger.name}, which is in ALLOW_ALL permissions mode, and run arbitrary PartiQL SELECT statements against all tables without any table-level IAM grants. This yields full data-plane read of all committed document revisions in the ledger journal.

Raw rule rules/derived/aws/qldb.yaml

id: aws-qldb-sendcommand-read-data
emits: CanReadData
description: qldb:SendCommand on an ALLOW_ALL-mode ledger allows the caller to run arbitrary PartiQL SELECT
  statements against all tables, yielding full data-plane read of all committed document revisions.
match:
- - principal: null
  - HasPermission
  - ledger: null
where:
- node_type(?ledger) == NoSQLDatabase
- ?ledger.provider_type == 'AWS::QLDB::Ledger'
- effective_action(?principal, ?ledger) includes 'qldb:SendCommand'
- (?ledger.properties.permissionsMode == 'ALLOW_ALL') OR (?ledger.properties.permissionsMode == 'STANDARD'
  AND effective_action(?principal, ?ledger) includes 'qldb:UpdateLedgerPermissionsMode')
emit:
  source_type: Identity
  target_type: NoSQLDatabase
  source: ?principal
  target: ?ledger
  permissions:
  - qldb:SendCommand
  conditions:
  - iam_permission
  - key_permission
  state_logic: "if ?ledger.properties.permissionsMode == 'ALLOW_ALL'\n  AND effective_action(?principal,\
    \ ?ledger) includes 'qldb:SendCommand':\n  if ?ledger.encryptionDescription.kmsKeyArn is a customer-managed\
    \ key\n  (not 'AWS_OWNED_KMS_KEY'): CONDITIONAL(key_permission) \u2014 the QLDB service\n  (qldb.amazonaws.com,\
    \ not the IAM caller) must have kms:Decrypt on the CMK\n  via a KMS grant in the key policy. This\
    \ is a service-level permission fact\n  collected from the KMS key policy, not an IAM caller permission.\
    \ Emit ACTIVE\n  when the KMS grant for qldb.amazonaws.com is confirmed; emit CONDITIONAL(key_permission)\n\
    \  when unknown.\n  else: ACTIVE.\nif ?ledger.properties.permissionsMode == 'STANDARD'\n  AND effective_action(?principal,\
    \ ?ledger) includes 'qldb:SendCommand'\n  AND effective_action(?principal, ?ledger) includes 'qldb:UpdateLedgerPermissionsMode':\n\
    \  CONDITIONAL(service_state) \u2014 principal can downgrade to ALLOW_ALL\n  then read all data; downgrade\
    \ must happen first.\nelse: do not emit."
  confidence: contributing_confidence * 0.95
  derived_from:
  - <HasPermission edge for qldb:SendCommand on ?ledger>
  false_positive_note: "Do NOT emit ACTIVE when permissionsMode is STANDARD and the principal lacks qldb:UpdateLedgerPermissionsMode\
    \ \u2014 SendCommand alone on a STANDARD ledger only opens a session; subsequent SELECT calls are\
    \ IAM-denied at the table level. Always verify permissionsMode from DescribeLedger output. Do NOT\
    \ emit when qldb:SendCommand is scoped by a resource ARN that does not cover this ledger. When the\
    \ ledger uses a customer-managed KMS key (encryptionDescription.kmsKeyArn != 'AWS_OWNED_KMS_KEY'),\
    \ emit CONDITIONAL(key_permission). The KMS grant that gates data-plane access is held by the QLDB\
    \ service principal (qldb.amazonaws.com) in the key policy, not the IAM caller. Emit ACTIVE only when\
    \ the KMS key policy is confirmed to grant kms:Decrypt to qldb.amazonaws.com; this is a service-level\
    \ fact collected from the KMS key policy, not an IAM caller permission."
  narrative: '{principal.name} can initiate a QLDB session (qldb:SendCommand) on {ledger.name}, which
    is in ALLOW_ALL permissions mode, and run arbitrary PartiQL SELECT statements against all tables without
    any table-level IAM grants. This yields full data-plane read of all committed document revisions in
    the ledger journal.'
move · open · esc close