aws-eb-bus-policy-cross-account-trust
An EventBridge custom bus resource policy granting events:PutEvents to a principal in another account establishes cross-account publish trust; the external principal can inject events that trigger compute consumers in this account.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?bus) ==
EventBus
node_type(?bus_policy) == ResourcePolicy
?bus_policy grants 'events:PutEvents' to a Principal in a different account than ?bus.account
Principal is NOT '*' (wildcard — ExposedToInternet, separate edge)
emit
| source type | ResourcePolicy |
|---|---|
| target type | Account |
| source | ?bus_policy |
| target | <external account named in the bus policy principal> |
| conditions | resource_policy condition_expression |
| state logic | ACTIVE when the bus policy unconditionally grants events:PutEvents to a named cross-account principal (arn:aws:iam::<other-account>:root or a specific role/user ARN). CONDITIONAL(condition_expression) when scoped by aws:SourceAccount, aws:SourceArn, aws:PrincipalOrgID, or other condition keys — the external principal must satisfy the condition. BLOCKED by an SCP or explicit deny that overrides the grant. On aws:PrincipalOrgID-scoped grants, the ACTIVE set is the entire org — emit CrossAccountTrust targeting the Organization node with CONDITIONAL. |
Narrative
The resource policy on {bus.name} grants events:PutEvents to a principal in {external_account}; that external principal can inject events into {bus.name}, potentially triggering compute consumers (rules/targets) inside this account.
Raw rule rules/derived/aws/eventbridge.yaml
id: aws-eb-bus-policy-cross-account-trust
emits: CrossAccountTrust
description: An EventBridge custom bus resource policy granting events:PutEvents to a principal in another
account establishes cross-account publish trust; the external principal can inject events that trigger
compute consumers in this account.
match:
- - bus_policy: null
- HasPolicy
- bus: null
where:
- node_type(?bus) == EventBus
- node_type(?bus_policy) == ResourcePolicy
- ?bus_policy grants 'events:PutEvents' to a Principal in a different account than ?bus.account
- "Principal is NOT '*' (wildcard \u2014 ExposedToInternet, separate edge)"
emit:
source_type: ResourcePolicy
target_type: Account
source: ?bus_policy
target: <external account named in the bus policy principal>
permissions: []
conditions:
- resource_policy
- condition_expression
state_logic: "ACTIVE when the bus policy unconditionally grants events:PutEvents to a named cross-account\
\ principal (arn:aws:iam::<other-account>:root or a specific role/user ARN). CONDITIONAL(condition_expression)\
\ when scoped by aws:SourceAccount, aws:SourceArn, aws:PrincipalOrgID, or other condition keys \u2014\
\ the external principal must satisfy the condition. BLOCKED by an SCP or explicit deny that overrides\
\ the grant. On aws:PrincipalOrgID-scoped grants, the ACTIVE set is the entire org \u2014 emit CrossAccountTrust\
\ targeting the Organization node with CONDITIONAL."
confidence: 0.95
derived_from:
- "events:DescribeEventBus \u2192 Policy (parsed principal)"
false_positive_note: "Do NOT emit CrossAccountTrust for Principal: '*' \u2014 that is internet exposure\
\ (ExposedToInternet), not a named cross-account trust. Do NOT emit for same-account principals (no\
\ cross-boundary value). Honor condition key scoping: aws:SourceAccount-scoped grants are CONDITIONAL\
\ on the source account satisfying the condition, not unconditional cross-account access. The CanEnterAccount\
\ consequence is produced by can-control (cited, not re-derived here) \u2014 this rule only asserts\
\ the trust FACT. A publish-only grant that reaches no bound consumer in this account does not enable\
\ account entry by itself."
narrative: The resource policy on {bus.name} grants events:PutEvents to a principal in {external_account};
that external principal can inject events into {bus.name}, potentially triggering compute consumers
(rules/targets) inside this account.