azure-evg-publish-entra

A principal with the EventGrid Data Sender role (events/send/action) on a custom topic can publish events via Entra token, triggering all bound consumers.

derived azure emits CanWriteData

match (effective permission)

{ "action": "Microsoft.EventGrid/events/send/action", "scope_type": "resource|resourceGroup|subscription" }

where

?topic is a custom topic or domain topic (NOT a system topic) ?topic.properties.publicNetworkAccess == Enabled OR principal has network path to private endpoint

emit

source typeIdentity
target typeGenericData
source<principal>
target<Event Grid custom topic or domain topic (EventBus)>
permissionsMicrosoft.EventGrid/events/send/action
conditionstrigger_exists network_reachability
state logicACTIVE when the effective permission is confirmed AND the topic is network-reachable. CONDITIONAL(network_reachability) when publicNetworkAccess=Disabled and no private endpoint reach confirmed. CONDITIONAL(trigger_exists) when no confirmed live subscription binding routes the topic to a consumer (but publishing still succeeds). BLOCKED if a deny assignment covers events/send/action at the effective scope.

Narrative

{principal.name} holds Microsoft.EventGrid/events/send/action on Event Grid topic {target.name} (EventGrid Data Sender role or equivalent); it can publish arbitrary events via Entra token, triggering all bound event subscription consumers with an attacker-controlled payload.

Raw rule rules/derived/azure/eventgrid.yaml

id: azure-evg-publish-entra
emits: CanWriteData
description: A principal with the EventGrid Data Sender role (events/send/action) on a custom topic can
  publish events via Entra token, triggering all bound consumers.
match_effective_permission:
  action: Microsoft.EventGrid/events/send/action
  scope_type: resource|resourceGroup|subscription
where:
- ?topic is a custom topic or domain topic (NOT a system topic)
- ?topic.properties.publicNetworkAccess == Enabled OR principal has network path to private endpoint
emit:
  source_type: Identity
  target_type: GenericData
  source: <principal>
  target: <Event Grid custom topic or domain topic (EventBus)>
  permissions:
  - Microsoft.EventGrid/events/send/action
  conditions:
  - trigger_exists
  - network_reachability
  state_logic: ACTIVE when the effective permission is confirmed AND the topic is network-reachable. CONDITIONAL(network_reachability)
    when publicNetworkAccess=Disabled and no private endpoint reach confirmed. CONDITIONAL(trigger_exists)
    when no confirmed live subscription binding routes the topic to a consumer (but publishing still succeeds).
    BLOCKED if a deny assignment covers events/send/action at the effective scope.
  confidence: 0.96
  derived_from:
  - 'effective permission: Microsoft.EventGrid/events/send/action'
  - 'messaging-chains.yaml: messaging-publish-triggers-consumer: CanWriteData + CanTrigger(topic->consumer)
    => CanTrigger(principal->consumer)'
  false_positive_note: "events/send/action is the Entra data-plane RBAC permission for publishing, included\
    \ in EventGrid Data Sender and EventGrid Contributor. It does NOT grant control-plane access (cannot\
    \ modify subscriptions or retrieve keys). It applies to CUSTOM topics and domain topics only \u2014\
    \ system topics are published to exclusively by the originating Azure resource; events/send/action\
    \ on a system topic returns 403. Confirm the topic type before emitting. Standard Reader and Contributor\
    \ roles at resource-group scope DO include wildcard data-plane actions including events/send/action;\
    \ a resource-scoped Contributor does NOT inherit it without explicit assignment."
  narrative: '{principal.name} holds Microsoft.EventGrid/events/send/action on Event Grid topic {target.name}
    (EventGrid Data Sender role or equivalent); it can publish arbitrary events via Entra token, triggering
    all bound event subscription consumers with an attacker-controlled payload.'
move · open · esc close