aws-msk-cluster-policy-cross-account
An MSK cluster resource-based policy granting kafka-cluster:WriteData or ReadData to a principal in another account is cross-account publish/consume trust; feeds messaging-chains rule 4 and can-control's CanEnterAccount derivation.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?clusterpolicy) ==
ResourcePolicy
node_type(?cluster) == GenericMessaging
?cluster is an AWS::MSK::Cluster
?clusterpolicy grants kafka-cluster:WriteData OR kafka-cluster:ReadData OR kafka-cluster:Connect to a Principal whose account != owner_account(?cluster)
the external Principal is not the AWS service principal kafka.amazonaws.com or kafkaconnect.amazonaws.com (exclude internal service grants)
emit
| source type | ResourcePolicy |
|---|---|
| target type | Account |
| source | ?clusterpolicy |
| target | <external account named in the cluster resource policy> |
| conditions | resource_policy condition_expression |
| state logic | ACTIVE when the cluster resource policy unconditionally grants a cross-account kafka-cluster:WriteData or ReadData to a named external principal. CONDITIONAL(condition_expression) when scoped by a condition the external principal must satisfy (aws:PrincipalOrgID, aws:SourceAccount, or a principal ARN condition narrowing the grant to a specific external role). BLOCKED by an SCP or org-policy that neutralizes the cross-account grant. On GCP this same pattern emits CrossProjectTrust — but this rule is AWS-only. |
Narrative
The resource policy on MSK cluster {cluster.name} grants kafka-cluster:WriteData (or ReadData) to a principal in account {target.name}; this cross-account trust lets external principals drive message production (and, via bound Lambda consumers, execution inside {cluster.name}'s account - messaging-chains + can-control roll that up to CanEnterAccount).
Raw rule rules/derived/aws/msk.yaml
id: aws-msk-cluster-policy-cross-account
emits: CrossAccountTrust
description: An MSK cluster resource-based policy granting kafka-cluster:WriteData or ReadData to a principal
in another account is cross-account publish/consume trust; feeds messaging-chains rule 4 and can-control's
CanEnterAccount derivation.
match:
- - clusterpolicy: null
- HasPolicy
- cluster: null
where:
- node_type(?clusterpolicy) == ResourcePolicy
- node_type(?cluster) == GenericMessaging
- ?cluster is an AWS::MSK::Cluster
- ?clusterpolicy grants kafka-cluster:WriteData OR kafka-cluster:ReadData OR kafka-cluster:Connect to
a Principal whose account != owner_account(?cluster)
- the external Principal is not the AWS service principal kafka.amazonaws.com or kafkaconnect.amazonaws.com
(exclude internal service grants)
emit:
source_type: ResourcePolicy
target_type: Account
source: ?clusterpolicy
target: <external account named in the cluster resource policy>
permissions: []
conditions:
- resource_policy
- condition_expression
state_logic: "ACTIVE when the cluster resource policy unconditionally grants a cross-account kafka-cluster:WriteData\
\ or ReadData to a named external principal. CONDITIONAL(condition_expression) when scoped by a condition\
\ the external principal must satisfy (aws:PrincipalOrgID, aws:SourceAccount, or a principal ARN condition\
\ narrowing the grant to a specific external role). BLOCKED by an SCP or org-policy that neutralizes\
\ the cross-account grant. On GCP this same pattern emits CrossProjectTrust \u2014 but this rule is\
\ AWS-only."
confidence: min(contributing_confidences)
derived_from:
- ?clusterpolicy HasPolicy ?cluster (kafka:GetClusterPolicy evidence)
- cross-account Principal in policy statement
false_positive_note: "CITE, DO NOT DUPLICATE messaging-chains.messaging-resource-policy-cross-boundary-trust:\
\ this rule is the MSK-specific adapter that emits the CrossAccountTrust fact; the CanEnterAccount\
\ roll-up (cross-account produce \u2192 trigger Lambda consumer in this account \u2192 CanEnterAccount)\
\ is messaging-chains rule 4 + can-control's responsibility \u2014 never re-derived here. Honor the\
\ two-policy evaluation for cross-account IAM: the external principal also needs kafka-cluster:WriteData\
\ in their own identity-based policy (resource-based policy alone is necessary but not sufficient\
\ for cross-account IAM access). Wildcard Principal ('*') in the cluster policy is internet/tenant\
\ exposure (ExposedToInternet or ExposedToTenant), not this cross-account trust edge."
narrative: "The resource policy on MSK cluster {cluster.name} grants kafka-cluster:WriteData (or ReadData)\
\ to a principal in account {target.name}; this cross-account trust lets external principals drive\
\ message production (and, via bound Lambda consumers, execution inside {cluster.name}'s account \u2014\
\ messaging-chains + can-control roll that up to CanEnterAccount)."