aws-kinesis-cross-account-read-trust

A Kinesis stream resource policy granting read actions (GetRecords/GetShardIterator/SubscribeToShard) to a foreign account enables that account to read the stream's records, supporting data exfiltration.

derived aws emits CrossAccountTrust

match

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

{'stream_policy': None} HasPolicy {'stream': None}

where

node_type(?stream) == GenericMessaging ?stream.provider_type == 'AWS::Kinesis::Stream' node_type(?stream_policy) == ResourcePolicy ?stream_policy grants kinesis:GetRecords or kinesis:GetShardIterator or kinesis:SubscribeToShard to a Principal whose account != account(?stream)

emit

source typeResourcePolicy
target typeAccount
source?stream_policy
target<the external AWS account named in the stream resource policy>
permissionskinesis:GetRecords kinesis:GetShardIterator kinesis:SubscribeToShard
conditionsresource_policy condition_expression
state logicACTIVE when the stream resource policy unconditionally grants kinesis:GetRecords, kinesis:GetShardIterator, or kinesis:SubscribeToShard to a named external principal with no conditions beyond aws:PrincipalArn identity scoping. CONDITIONAL(condition_expression) when scoped by aws:SourceAccount, aws:SourceVpc, aws:PrincipalOrgID, or other conditions. BLOCKED by an SCP or explicit deny in the stream-owner's account that prevents cross-account GetRecords. This edge asserts cross-boundary read TRUST; CanReadData cross- boundary is rolled up by data-plane rules and credential-chains (if records carry secrets).

Narrative

The resource policy on Kinesis stream {stream.name} grants kinesis:GetRecords, kinesis:GetShardIterator, or kinesis:SubscribeToShard to a principal in a foreign AWS account. That external principal can read records from this stream, enabling data exfiltration (especially if records carry sensitive data or credentials).

Raw rule rules/derived/aws/kinesis.yaml

id: aws-kinesis-cross-account-read-trust
emits: CrossAccountTrust
description: A Kinesis stream resource policy granting read actions (GetRecords/GetShardIterator/SubscribeToShard)
  to a foreign account enables that account to read the stream's records, supporting data exfiltration.
match:
- - stream_policy: null
  - HasPolicy
  - stream: null
where:
- node_type(?stream) == GenericMessaging
- ?stream.provider_type == 'AWS::Kinesis::Stream'
- node_type(?stream_policy) == ResourcePolicy
- ?stream_policy grants kinesis:GetRecords or kinesis:GetShardIterator or kinesis:SubscribeToShard to
  a Principal whose account != account(?stream)
emit:
  source_type: ResourcePolicy
  target_type: Account
  source: ?stream_policy
  target: <the external AWS account named in the stream resource policy>
  permissions:
  - kinesis:GetRecords
  - kinesis:GetShardIterator
  - kinesis:SubscribeToShard
  conditions:
  - resource_policy
  - condition_expression
  state_logic: ACTIVE when the stream resource policy unconditionally grants kinesis:GetRecords, kinesis:GetShardIterator,
    or kinesis:SubscribeToShard to a named external principal with no conditions beyond aws:PrincipalArn
    identity scoping. CONDITIONAL(condition_expression) when scoped by aws:SourceAccount, aws:SourceVpc,
    aws:PrincipalOrgID, or other conditions. BLOCKED by an SCP or explicit deny in the stream-owner's
    account that prevents cross-account GetRecords. This edge asserts cross-boundary read TRUST; CanReadData
    cross- boundary is rolled up by data-plane rules and credential-chains (if records carry secrets).
  confidence: min(contributing_confidences)
  derived_from:
  - ?stream_policy HasPolicy ?stream (kinesis:GetResourcePolicy evidence)
  - "data-plane:CanReadData-rollup (downstream CanReadData \u2014 cited not re-derived)"
  false_positive_note: 'This rule asserts ONLY the cross-boundary read TRUST from the resource policy.
    CanReadData cross-boundary is emitted by the data-plane rules and credential- chains, not here. Honor
    aws:PrincipalOrgID / aws:SourceAccount conditions as real controls: a policy scoped to a specific
    sibling account is not open read access (downgrade to CONDITIONAL). A read-only cross-account grant
    (GetRecords alone without GetShardIterator) has limitations but is still a capability (GetRecords
    requires a pre-obtained shard iterator from GetShardIterator, but an attacker holding both can read
    freely). Distinguish from rule 2 (publish-trust): this rule covers read-only access, while rule 2
    covers publish/trigger access.'
  narrative: The resource policy on Kinesis stream {stream.name} grants kinesis:GetRecords, kinesis:GetShardIterator,
    or kinesis:SubscribeToShard to a principal in a foreign AWS account. That external principal can read
    records from this stream, enabling data exfiltration (especially if records carry sensitive data or
    credentials).
move · open · esc close