Ensure EventBridge Event Bus Is Not Publicly Exposed
Overview
This check verifies that your Amazon EventBridge event buses do not have overly permissive resource policies that allow public access. An event bus is considered "exposed" when its policy contains Principal: "*" without proper conditions, allowing any AWS account to send events to your bus.
Risk
If your EventBridge event bus is publicly exposed:
- Unauthorized event injection: Attackers can send malicious events that trigger your downstream targets (Lambda functions, Step Functions, etc.)
- Data exposure: Triggered targets may process or expose sensitive data
- Service disruption: High-volume event injection can overwhelm your systems
- Cost escalation: Attackers can drive up costs by flooding your bus with events
- Lateral movement: Compromised events can be used as a stepping stone to other resources
Severity: High
Remediation Steps
Prerequisites
You need permission to view and modify EventBridge event bus policies. Typically this requires the events:DescribeEventBus, events:PutPermission, and events:RemovePermission IAM permissions.
AWS Console Method
- Open the Amazon EventBridge console at https://console.aws.amazon.com/events/
- In the left navigation, click Event buses
- Select the event bus flagged by Prowler
- Click the Permissions tab
- Review the resource policy - look for statements where Principal is
"*"without restrictive conditions - Click Edit policy (or Manage permissions)
- Either:
- Remove statements that grant public access, or
- Replace
"*"with specific account ARNs (e.g.,arn:aws:iam::123456789012:root)
- Click Save
AWS CLI (optional)
View Current Policy
First, check the current event bus policy:
aws events describe-event-bus \
--name <your-event-bus-name> \
--region us-east-1
For the default event bus, omit the --name parameter:
aws events describe-event-bus --region us-east-1
The output includes a Policy field (JSON string) showing all permission statements.
Remove a Specific Permission
If you know the statement ID of the problematic permission:
aws events remove-permission \
--event-bus-name <your-event-bus-name> \
--statement-id <statement-id> \
--region us-east-1
Remove All Permissions
To remove all permissions from an event bus (use with caution):
aws events remove-permission \
--event-bus-name <your-event-bus-name> \
--remove-all-permissions \
--region us-east-1
Add Restricted Permission
To grant access to a specific AWS account:
aws events put-permission \
--event-bus-name <your-event-bus-name> \
--statement-id "AllowAccount123456789012" \
--action "events:PutEvents" \
--principal "123456789012" \
--region us-east-1
To grant access to all accounts in your AWS Organization:
aws events put-permission \
--event-bus-name <your-event-bus-name> \
--statement-id "AllowMyOrganization" \
--action "events:PutEvents" \
--principal "*" \
--condition "Type=StringEquals,Key=aws:PrincipalOrgID,Value=o-xxxxxxxxxx" \
--region us-east-1
CloudFormation (optional)
Use this template to create a secure event bus with a properly restricted policy:
AWSTemplateFormatVersion: '2010-09-09'
Description: Secure EventBridge event bus with restricted resource policy
Parameters:
EventBusName:
Type: String
Default: my-secure-event-bus
Description: Name of the EventBridge event bus
TrustedAccountId:
Type: String
Description: AWS Account ID allowed to send events to this bus
AllowedPattern: '^[0-9]{12}$'
Resources:
SecureEventBus:
Type: AWS::Events::EventBus
Properties:
Name: !Ref EventBusName
EventBusPolicy:
Type: AWS::Events::EventBusPolicy
Properties:
EventBusName: !Ref SecureEventBus
StatementId: AllowTrustedAccount
Action: events:PutEvents
Principal: !Ref TrustedAccountId
Outputs:
EventBusArn:
Description: ARN of the secure event bus
Value: !GetAtt SecureEventBus.Arn
EventBusName:
Description: Name of the secure event bus
Value: !Ref SecureEventBus
Deploy with:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name secure-eventbridge-bus \
--parameter-overrides \
EventBusName=my-secure-event-bus \
TrustedAccountId=123456789012 \
--region us-east-1
Terraform (optional)
# Secure EventBridge Event Bus with Restricted Policy
# This configuration creates an event bus that only allows
# specific AWS accounts to send events
variable "event_bus_name" {
description = "Name of the EventBridge event bus"
type = string
default = "my-secure-event-bus"
}
variable "trusted_account_ids" {
description = "List of AWS Account IDs allowed to send events"
type = list(string)
}
resource "aws_cloudwatch_event_bus" "secure_bus" {
name = var.event_bus_name
}
resource "aws_cloudwatch_event_bus_policy" "secure_policy" {
event_bus_name = aws_cloudwatch_event_bus.secure_bus.name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowTrustedAccounts"
Effect = "Allow"
Principal = {
AWS = [for account_id in var.trusted_account_ids : "arn:aws:iam::${account_id}:root"]
}
Action = "events:PutEvents"
Resource = aws_cloudwatch_event_bus.secure_bus.arn
}
]
})
}
output "event_bus_arn" {
description = "ARN of the secure event bus"
value = aws_cloudwatch_event_bus.secure_bus.arn
}
output "event_bus_name" {
description = "Name of the secure event bus"
value = aws_cloudwatch_event_bus.secure_bus.name
}
Create a terraform.tfvars file:
event_bus_name = "my-secure-event-bus"
trusted_account_ids = ["123456789012", "987654321098"]
Apply with:
terraform init
terraform plan
terraform apply
Verification
After remediation, verify that the event bus policy is properly restricted:
- Return to the EventBridge console > Event buses
- Select your event bus and click the Permissions tab
- Confirm that:
- No statements have
Principal: "*"without conditions - All principals are specific account ARNs or properly conditioned
- No statements have
CLI Verification
aws events describe-event-bus \
--name <your-event-bus-name> \
--region us-east-1 \
--query 'Policy' \
--output text | jq .
Look for any "Principal": "*" entries. If found, ensure they have proper Condition blocks (e.g., aws:PrincipalOrgID).
Re-run the Prowler check to confirm the issue is resolved:
prowler aws --check eventbridge_bus_exposed
Additional Resources
- Amazon EventBridge Resource-Based Policies
- Sending and Receiving Events Between AWS Accounts
- EventBridge Security Best Practices
- AWS::Events::EventBusPolicy (CloudFormation)
Notes
-
Default event bus: Every AWS account has a default event bus. If your default bus is exposed, the remediation steps are the same, but omit the
--event-bus-nameparameter in CLI commands or leave it empty in the console. -
Cross-account event delivery: If you legitimately need to receive events from other accounts, use specific account IDs or restrict access using AWS Organizations conditions (
aws:PrincipalOrgID) rather thanPrincipal: "*". -
Partner event sources: Some AWS partner integrations require specific permissions. Consult the partner's documentation before modifying policies that may affect these integrations.
-
Impact assessment: Before removing permissions, identify any external accounts or services that may be sending events to your bus. Removing their access will cause their event delivery to fail.