azure-eh-sas-key-exposes-cred
A namespace or entity authorization rule with usable SAS keys (disableLocalAuth=false) embeds connection-string credential material; any holder of the keys can authenticate to the Event Hubs data plane.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_class(?namespace) == Messaging
node_type(?sasRule) ==
APIKey
?namespace.properties.disableLocalAuth != true
?sasRule.rights include Send OR Manage (i.e. the key grants data-plane write access)
emit
| source type | GenericMessaging |
|---|---|
| target type | Credential |
| source | ?namespace |
| target | <SAS connection string (Credential / ConnectionString) embedded in ?sasRule> |
| state logic | ACTIVE when the namespace has authorization rules with Send or Manage rights AND disableLocalAuth=false (SAS is enabled). BLOCKED when disableLocalAuth=true. This is a STATIC INVENTORY FACT (not action-gated): the connection-string credential exists in the ARM resource and is accessible to anyone who can invoke listkeys/action (gated separately by azure-eh-listkeys-namespace/entity). Expresses the fact that the authorization rule IS a credential, regardless of whether the attacker has currently read it — feeds credential-chains as the CredentialsFor link when the SAS connection string is CredentialsFor the event hub's data-plane access. |
Narrative
Event Hubs namespace {namespace.name} authorization rule {sasRule.name} stores SAS signing keys (primary + secondary) that authenticate to the Event Hubs data plane; any holder of these keys (obtainable via listkeys/action) can generate SAS tokens granting {sasRule.rights} access to the namespace's event hubs.
Raw rule rules/derived/azure/eventhubs.yaml
id: azure-eh-sas-key-exposes-cred
emits: ExposesCredential
description: A namespace or entity authorization rule with usable SAS keys (disableLocalAuth=false) embeds
connection-string credential material; any holder of the keys can authenticate to the Event Hubs data
plane.
match:
- - namespace: null
- ContainsSecret
- sasRule: null
where:
- node_class(?namespace) == Messaging
- node_type(?sasRule) == APIKey
- ?namespace.properties.disableLocalAuth != true
- ?sasRule.rights include Send OR Manage (i.e. the key grants data-plane write access)
emit:
source_type: GenericMessaging
target_type: Credential
source: ?namespace
target: <SAS connection string (Credential / ConnectionString) embedded in ?sasRule>
permissions: []
conditions: []
state_logic: "ACTIVE when the namespace has authorization rules with Send or Manage rights AND disableLocalAuth=false\
\ (SAS is enabled). BLOCKED when disableLocalAuth=true. This is a STATIC INVENTORY FACT (not action-gated):\
\ the connection-string credential exists in the ARM resource and is accessible to anyone who can\
\ invoke listkeys/action (gated separately by azure-eh-listkeys-namespace/entity). Expresses the fact\
\ that the authorization rule IS a credential, regardless of whether the attacker has currently read\
\ it \u2014 feeds credential-chains as the CredentialsFor link when the SAS connection string is CredentialsFor\
\ the event hub's data-plane access."
confidence: 0.95
derived_from:
- 'ContainsSecret: namespace has at least one authorization rule with SAS keys'
- 'credential-chains.yaml: ExposesCredential + CredentialsFor => CanImpersonate (if SAS key authenticates
a specific identity)'
- 'messaging-chains.yaml: messaging-publish-triggers-consumer (SAS Send key => CanWriteData => CanTrigger
consumer)'
false_positive_note: "This edge asserts that usable credential material EXISTS in the authorization\
\ rule \u2014 it does not assert the attacker has READ it. Reading the keys requires listkeys/action\
\ (azure-eh-listkeys-namespace / azure-eh-listkeys-entity). When disableLocalAuth=true, the keys are\
\ in ARM but cannot authenticate to the Event Hubs data plane \u2014 emit as BLOCKED. Only emit for\
\ rules with Send or Manage rights (Listen-only rules yield CanReadData, not CanWriteData; still credential\
\ material but lower impact). A SAS key is not a scoped Entra identity \u2014 it does not map to a\
\ specific service principal or managed identity, so CredentialsFor targets the EVENT HUB DATA PLANE\
\ (the Queue node), not an Identity node."
narrative: Event Hubs namespace {namespace.name} authorization rule {sasRule.name} stores SAS signing
keys (primary + secondary) that authenticate to the Event Hubs data plane; any holder of these keys
(obtainable via listkeys/action) can generate SAS tokens granting {sasRule.rights} access to the namespace's
event hubs.