Encrypting events on a Custom Event Bus
A bus encrypts everything it stores: event payloads, event metadata, subscriber filters, and
subscriber target configuration. By default it uses a key that Amazon owns, and you configure
nothing. To encrypt a bus with your own Amazon KMS key instead, set
EncryptionConfiguration.KmsKeyIdentifier when you create or update the bus, for
example aws eventsv2 create-event-bus --name orders --encryption-configuration
KmsKeyIdentifier=arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab,
and add the three statements in Writing the key policy to the
key policy.
Choosing the key that encrypts a bus
Omit EncryptionConfiguration and EventBridge encrypts the bus with 256-bit AES under an
Amazon owned key. You cannot view or manage that key, its use does not appear in your CloudTrail logs,
it costs nothing, it does not count against your Amazon KMS quotas, and Amazon rotates it
monthly. DescribeEventBus returns no EncryptionConfiguration for such
a bus. For more information, see
Amazon owned keys
Set EncryptionConfiguration.KmsKeyIdentifier and EventBridge encrypts the bus with your
customer managed key. You then control the key policy, rotation, disabling, and deletion, and you
see every use of the key in CloudTrail. The key incurs the Amazon KMS monthly key fee and request charges.
Because EventBridge encrypts and decrypts events locally under a cached branch key (see
How the bus uses your key), it makes a few Amazon KMS requests per bus per
cache window plus rotation; the request count does not grow with your event volume. For more
information, see Amazon KMS pricing
KmsKeyIdentifier accepts a key ID, a key ARN, an alias name such as
alias/orders, or an alias ARN. EventBridge qualifies a bare key ID or alias name in your
account and Region, so a key in another account must be named by its full key ARN. An alias is
resolved to its key when you create or update the bus, and the create and describe responses
return that key ARN. Re-pointing the alias later does not change the key a bus uses. The key
must be a symmetric encryption key (SYMMETRIC_DEFAULT, key usage
ENCRYPT_DECRYPT); EventBridge rejects asymmetric and HMAC keys. A multi-Region key works
as an ordinary key: name the replica in the bus's Region, because EventBridge replicates neither your
data nor your key material across Regions. Keys with imported key material and keys in an
external key store are supported.
aws eventsv2 create-event-bus \ --name orders \ --encryption-configuration KmsKeyIdentifier=arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
Your key encrypts the event payloads and metadata that the bus retains, the copies held for each subscriber during delivery, and the subscriber filters and target configuration. Four things are not encrypted with your key, because EventBridge needs them to route and look up events: the bus name, ARN, and account ID; the event group ID that orders FIFO delivery, so do not put sensitive data in it; the deduplication ID, which EventBridge stores as a one-way hash; and internal match results and sequence numbers. The storage services encrypt those at rest with their own keys.
How the bus uses your key
When you configure a customer managed key, EventBridge creates a branch key for
the bus: an intermediate key, stored in a service-managed table and wrapped by your Amazon KMS key,
following the Amazon Encryption SDK
Hierarchical Keyring
When you publish an event, EventBridge encrypts it under the bus's branch key before writing it to storage.
When EventBridge delivers an event, it decrypts the event to evaluate filters and to deliver it. The target receives the decrypted event; encryption at the target is the target service's responsibility.
EventBridge caches the branch key in memory for up to 15 minutes. When the cache expires, it calls
kms:Decrypton your key to unwrap the branch key again.EventBridge creates a new branch key version about every 30 days and keeps the older versions, so events written earlier stay readable for the bus's retention period.
EventBridge reaches your key on two paths, and the key policy must allow both. For the checks it runs
while your API call is in progress, it uses your credentials, forwarded from the call. For the
work it does after the call returns, such as delivering events and managing the branch key, it
acts as the events.amazonaws.com service principal, because your credentials are no
longer available.
Writing the key policy
Add three statements to the key policy: one that lets your principals validate the key, one
that lets them pass the access checks EventBridge runs with their credentials, and one for the
events.amazonaws.com service principal. Every Amazon KMS request EventBridge makes for a bus
carries the encryption context key aws:events:event-busv2:arn with the bus ARN,
on both access paths, so the second and third statements are scoped to one bus. A bus ARN ends
in a suffix that EventBridge generates at creation, so match it with StringLike and a
trailing /*. Keep your own key administration statements in the policy as well.
Replace the account, Region, role, and bus name in the following example.
{ "Version": "2012-10-17", "Id": "eventbridge-custom-event-bus-key-policy", "Statement": [ { "Sid": "AllowKeyValidationThroughEventBridge", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/ExampleRole" }, "Action": "kms:DescribeKey", "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "events.us-east-1.amazonaws.com" } } }, { "Sid": "AllowKeyUseThroughEventBridge", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/ExampleRole" }, "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKeyWithoutPlaintext", "kms:ReEncryptFrom", "kms:ReEncryptTo" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "events.us-east-1.amazonaws.com" }, "StringLike": { "kms:EncryptionContext:aws:events:event-busv2:arn": "arn:aws:events:us-east-1:111122223333:event-busv2/orders/*" } } }, { "Sid": "AllowEventBridgeServicePrincipal", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKeyWithoutPlaintext", "kms:ReEncryptFrom", "kms:ReEncryptTo" ], "Resource": "*", "Condition": { "StringLike": { "kms:EncryptionContext:aws:events:event-busv2:arn": "arn:aws:events:us-east-1:111122223333:event-busv2/orders/*" } } } ] }
AllowKeyValidationThroughEventBridge lets your principals validate the key when they
create or update a bus. EventBridge calls kms:DescribeKey with your credentials to confirm
that the key exists, is symmetric, and is enabled. DescribeKey takes no encryption
context, so this statement has none; kms:ViaService limits it to requests that come
through EventBridge.
AllowKeyUseThroughEventBridge authorizes the access checks that EventBridge runs with your
credentials before it accepts a key configuration and before it writes or reads encrypted data
for you, so that you cannot configure a key that the service's later, asynchronous work cannot
use. The checks are Amazon KMS dry runs: they authorize but encrypt and decrypt nothing. They are
billed as standard Amazon KMS requests and count against your Amazon KMS request quotas; see
Testing your permissions
CreateEventBuswith a customer managed key checkskms:GenerateDataKeyWithoutPlaintext,kms:ReEncryptFrom,kms:ReEncryptTo, andkms:Decrypt, the actions that branch key creation and later reads perform.UpdateEventBusthat changes the key checkskms:Decrypton the current key, andkms:Encryptandkms:Decrypton the new key.PutEventsandPutRawEventson a bus with a customer managed key checkkms:Decrypt. A producer that cannot read the bus's events back cannot write them either. Without it, the publish call fails withAccessDeniedExceptionnamingKMS_ACCESS_DENIED.CreateSubscriberandUpdateSubscribercheckkms:Decrypt, because subscriber configuration is encrypted under the bus key.
So the Principal of this statement must cover every role that creates or updates the
bus, publishes to it, or creates subscribers on it. List the role ARNs, or name the account root
principal to delegate the decision to the IAM policies in your account.
AllowEventBridgeServicePrincipal authorizes the work EventBridge performs as the service
after your call completes. kms:GenerateDataKeyWithoutPlaintext,
kms:ReEncryptFrom, and kms:ReEncryptTo create the bus's branch key and
its new versions on rotation. kms:Decrypt unwraps the branch key to deliver events, to
load subscriber configuration, and to return decrypted configuration on describe calls.
kms:Decrypt with kms:Encrypt re-wraps the branch key when you change the
bus's key.
The key can live in another account, for example a central security account. Put all three statements in that key's policy, with the bus account's roles as the principals of the first two and the bus account's bus ARN in the encryption context values. The bus account's roles also need IAM identity policies that allow the same Amazon KMS actions on the key ARN, because cross-account Amazon KMS access requires permission on both sides. Name the key by its full key ARN.
Scoping the key policy to one bus
To limit a statement to one bus, condition it on
kms:EncryptionContext:aws:events:event-busv2:arn. Before the bus exists, use
StringLike with a trailing /*, as in the preceding policy. For an
existing bus, you can match the exact ARN that DescribeEventBus returns with
StringEquals. Every request made with your credentials also populates
kms:ViaService with events.,
so you can restrict your principals to using the key through EventBridge only.region.amazonaws.com
Requests that EventBridge makes as the service principal carry aws:SourceArn with the bus
ARN and aws:SourceAccount with the bus account. Add them to
AllowEventBridgeServicePrincipal so that EventBridge can use your key only for your own
buses.
"Condition": { "StringEquals": { "aws:SourceAccount": "111122223333" }, "ArnLike": { "aws:SourceArn": "arn:aws:events:us-east-1:111122223333:event-busv2/orders/*" } }
Individual publish and delivery operations use the cached branch key and do not re-check the key policy per event. A key policy change, including one that removes EventBridge's access, takes effect on a bus's data handling when the cached branch key expires, within 15 minutes.
Changing or removing the key on a bus
Call UpdateEventBus to move a bus from the Amazon owned key to a customer managed
key, from one customer managed key to another, or back to the Amazon owned key. To return to the
Amazon owned key, send EncryptionConfiguration present and empty, as
--encryption-configuration '{}'. Omit EncryptionConfiguration entirely
and the bus keeps its current key.
The bus enters UPDATING while EventBridge re-wraps the branch key under the new key, then
returns to ACTIVE. The branch key itself does not change, so EventBridge re-encrypts no
stored events, the change completes quickly whatever the bus holds, and previously written
events stay readable whatever the state of the old key. Once DescribeEventBus
shows the bus ACTIVE with the new key, you can disable the old key.
If EventBridge cannot use the new key, the bus settles in UPDATE_FAILED and keeps working
with its previous key: it still accepts and delivers events, and DescribeEventBus
keeps reporting the old key. The failed key never becomes the bus key. Call
UpdateEventBus again with a usable key, or the same key after you fix its policy, and
the bus returns to ACTIVE. A bus whose creation fails on the key settles in
CREATE_FAILED with a StateReason naming the Amazon KMS denial; that state
accepts only DeleteEventBus, and UpdateEventBus is rejected with a
message naming the states it does accept, [ACTIVE, UPDATE_FAILED]. Fix the key
policy, delete the bus, and create it again. For the states, see
Bus states and what each allows.
If you enable
automatic key rotation
When the key becomes unusable
If you disable the key, schedule it for deletion, or remove EventBridge's access to it, the bus keeps working until its cached branch key expires, within 15 minutes. Then publishing to the bus fails with a Amazon KMS access error, and delivery pauses. EventBridge does not drop the events it has already accepted and does not send them to dead-letter queues; it holds and retries them, because a key access failure is a condition you can fix. When you restore access, publishing and delivery resume on their own. No event is lost unless the outage outlasts the bus's retention period.
Deleting the key is permanent. After Amazon KMS deletes the key configured on a bus, EventBridge can no
longer unwrap the bus's branch key, and every event still stored on the bus is unreadable for
the rest of its retention period. Disable the key first, confirm the effect, and only then
schedule deletion; see
Deleting Amazon KMS keysDeleteEventBus does not need the
key: it succeeds when the key is disabled or deleted.
Monitoring key use in CloudTrail
Every request EventBridge makes to your customer managed key is recorded in CloudTrail; see
Logging Amazon KMS API calls with CloudTrail
eventName |
When | Calling identity |
|---|---|---|
DescribeKey |
Key validation on bus create and update | Your principal, through EventBridge |
Decrypt, Encrypt, GenerateDataKeyWithoutPlaintext, ReEncrypt (dry run) |
Access checks on bus create and update, publish, and subscriber create and update | Your principal, through EventBridge |
GenerateDataKeyWithoutPlaintext, ReEncrypt |
Branch key creation at bus create, and branch key rotation about every 30 days | events.amazonaws.com |
Decrypt |
Branch key unwrap when the cache expires: event delivery, subscriber configuration load, describe calls | events.amazonaws.com |
Decrypt and Encrypt |
Branch key re-wrap when UpdateEventBus changes the key |
events.amazonaws.com |
CloudTrail records a ReEncrypt call as one event; the kms:ReEncryptFrom and
kms:ReEncryptTo permissions both authorize it. A dry-run entry that shows
DryRunOperationException is a passing access check, not a fault in your
configuration; one that shows AccessDeniedException means the caller lacks the
permission being checked. The requestParameters.encryptionContext of every entry
includes aws:events:event-busv2:arn with your bus ARN. Branch key entries also carry
the Hierarchical Keyring's fields: branch-key-id (the bus ARN), type,
create-time, tablename, hierarchy-version, and
kms-arn. Per-event encryption and decryption use data keys derived locally from the
cached branch key, so individual events do not appear in CloudTrail.
Encryption in transit
All Custom Event Bus API calls go to an HTTPS endpoint,
eventsv2., and every request
must be signed with your credentials. A FIPS endpoint,
region.amazonaws.comeventsv2-fips., is available
where you need it. For EventBridge data protection in general, see
Amazon EventBridge security.region.amazonaws.com