AWS EventBridge event bus does not allow cross-account access
EventBridge event bus has a resource policy that grants cross-account event delivery to principals outside the account, including broad or public access.
Focus is on buses whose policies permit external accounts to send events.
Risk
Cross-account event injection can erode integrity and availability. Spoofed events may trigger rules and invoke downstream targets, causing unintended actions, data exposure via targets, lateral movement through over-privileged roles, and cost or service disruption from event floods.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks eventbridge_bus_cross_account_accessRecommendation
Apply least privilege on the event bus resource policy: allow only specific account IDs or org scope (e.g., aws:PrincipalOrgID) and avoid wildcard Principal or *.
Constrain rules to trusted senders using the account field and vetted sources, and add monitoring/throttling for defense in depth.
Remediation
CLI
aws events remove-permission --event-bus-name <event_bus_name> --statement-id <statement_id>Terraform
# Terraform: restrict EventBridge event bus to same account only
resource "aws_cloudwatch_event_permission" "<example_resource_name>" {
statement_id = "<example_resource_id>"
action = "events:PutEvents"
principal = "<example_resource_id>" # Critical: set to your own AWS account ID to block cross-account access
event_bus_name = "<example_resource_name>"
}NativeIaC
# CloudFormation: restrict EventBridge event bus to same account only
Resources:
<example_resource_name>:
Type: AWS::Events::EventBusPolicy
Properties:
StatementId: <example_resource_id>
Action: events:PutEvents
Principal: !Ref AWS::AccountId # Critical: allows only this AWS account, blocking cross-account access
EventBusName: <example_resource_name>Other
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.eventbridge.eventbridge_client import (
eventbridge_client,
)
from prowler.providers.aws.services.iam.lib.policy import is_policy_public
class eventbridge_bus_cross_account_access(Check):
def execute(self):
findings = []
trusted_account_ids = eventbridge_client.audit_config.get(
"trusted_account_ids", []
)
for bus in eventbridge_client.buses.values():
if bus.policy is None:
continue
report = Check_Report_AWS(metadata=self.metadata(), resource=bus)
report.status = "PASS"
report.status_extended = (
f"EventBridge event bus {bus.name} does not allow cross-account access."
)
if is_policy_public(
bus.policy,
eventbridge_client.audited_account,
is_cross_account_allowed=False,
trusted_account_ids=trusted_account_ids,
):
report.status = "FAIL"
report.status_extended = (
f"EventBridge event bus {bus.name} allows cross-account access."
)
findings.append(report)
return findingsReferences
- https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/aws/CloudWatchEvents/event-bus-cross-account-access.html
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CWE_GettingStarted.html
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEvents-CrossAccountEventDelivery.html