aws-redshift-read-data-via-data-api
redshift-data:ExecuteStatement lets a principal run SELECT queries against the cluster via the Data API, reading tables accessible to the IAM-mapped DB user.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?cluster) ==
DataWarehouse
?cluster.provider_type in ['AWS::Redshift::Cluster', 'AWS::RedshiftServerless::Workgroup']
?principal has EFFECTIVE redshift-data:ExecuteStatement on ?cluster ARN
?principal has EFFECTIVE redshift-data:GetStatementResult on ?cluster ARN
emit
| source type | Identity |
|---|---|
| target type | Data |
| source | ?principal |
| target | ?cluster |
| permissions | redshift-data:ExecuteStatement redshift-data:GetStatementResult |
| conditions | iam_permission service_state |
| state logic | ACTIVE when both redshift-data:ExecuteStatement AND redshift-data:GetStatementResult are confirmed EFFECTIVE on the cluster ARN (identity-based policy + no SCP deny), AND the cluster is in the AVAILABLE state (or Serverless workgroup is active). CONDITIONAL(service_state) when the cluster is paused, restoring, or in a maintenance window. CONDITIONAL(iam_permission) when a resource policy or SCP may restrict ExecuteStatement but hasn't been resolved. BLOCKED by an explicit SCP or permission-boundary deny on redshift-data:ExecuteStatement. The depth of data access depends on the DB user privilege level: an IAM identity mapped to a DB superuser can read all tables; a non-privileged user can read only explicitly GRANTed tables. Score appropriately. |
Narrative
{principal.name} can submit SQL queries to Redshift cluster {cluster.name} via the Data API (redshift-data:ExecuteStatement + GetStatementResult), reading tables accessible to its IAM-mapped database user.
Raw rule rules/derived/aws/redshift.yaml
id: aws-redshift-read-data-via-data-api
emits: CanReadData
description: redshift-data:ExecuteStatement lets a principal run SELECT queries against the cluster via
the Data API, reading tables accessible to the IAM-mapped DB user.
match:
- - principal: null
- HasPermission
- cluster: null
where:
- node_type(?cluster) == DataWarehouse
- ?cluster.provider_type in ['AWS::Redshift::Cluster', 'AWS::RedshiftServerless::Workgroup']
- ?principal has EFFECTIVE redshift-data:ExecuteStatement on ?cluster ARN
- ?principal has EFFECTIVE redshift-data:GetStatementResult on ?cluster ARN
emit:
source_type: Identity
target_type: Data
source: ?principal
target: ?cluster
permissions:
- redshift-data:ExecuteStatement
- redshift-data:GetStatementResult
conditions:
- iam_permission
- service_state
state_logic: 'ACTIVE when both redshift-data:ExecuteStatement AND redshift-data:GetStatementResult are
confirmed EFFECTIVE on the cluster ARN (identity-based policy + no SCP deny), AND the cluster is in
the AVAILABLE state (or Serverless workgroup is active). CONDITIONAL(service_state) when the cluster
is paused, restoring, or in a maintenance window. CONDITIONAL(iam_permission) when a resource policy
or SCP may restrict ExecuteStatement but hasn''t been resolved. BLOCKED by an explicit SCP or permission-boundary
deny on redshift-data:ExecuteStatement. The depth of data access depends on the DB user privilege
level: an IAM identity mapped to a DB superuser can read all tables; a non-privileged user can read
only explicitly GRANTed tables. Score appropriately.'
confidence: min(contributing_confidences) * 0.90
derived_from:
- ?principal HasPermission ?cluster (redshift-data:ExecuteStatement + GetStatementResult effective permission)
false_positive_note: "TWO permissions needed: redshift-data:ExecuteStatement (submit) AND redshift-data:GetStatementResult\
\ (retrieve results); without GetStatementResult the query fires but results cannot be read. A third\
\ permission, redshift-data:DescribeStatement, may be needed to check statement status; omit it from\
\ the mandatory set but note it as a practical requirement. The cluster must also be AVAILABLE (not\
\ paused/restoring). The IAM-to-DB-user mapping determines actual table access: an identity with no\
\ DB privileges or mapped to a user with no GRANT cannot read data even with ExecuteStatement. Do\
\ NOT conflate \"can submit statements\" with \"can read all data\" \u2014 model the DB user privilege\
\ level via the cluster node's properties. For Serverless, the action applies to the workgroup ARN."
narrative: '{principal.name} can submit SQL queries to Redshift cluster {cluster.name} via the Data
API (redshift-data:ExecuteStatement + GetStatementResult), reading tables accessible to its IAM-mapped
database user.'