azure-kv-secret-to-escalation
Reading a secret that is a credential for a more-privileged identity is escalation.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanReadSecret {'secret': None}
{'secret': None} CredentialsFor {'identity': None}
where
node_class(?identity) == Identity #
CanEscalateTo target set is strictly [Identity] (User/Role/ServiceAccount/ServicePrincipal/ManagedIdentity/... are all Identity-class subtypes); a CredentialsFor target that resolves to a Data store is excluded here
?identity.privilege_level > ?principal.privilege_level
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | ?principal |
| target | ?identity |
| permissions | Microsoft.KeyVault/vaults/secrets/getSecret/action |
| state logic | inherit the weaker of CanReadSecret and CredentialsFor states (CONDITIONAL(network_reachability) or BLOCKED propagate) |
Narrative
{principal.name} can read secret {secret.name}, a credential for {identity.name}, and thereby escalate to {identity.name}.
Raw rule rules/derived/azure/keyvault.yaml
id: azure-kv-secret-to-escalation
emits: CanEscalateTo
description: Reading a secret that is a credential for a more-privileged identity is escalation.
match:
- - principal: null
- CanReadSecret
- secret: null
- - secret: null
- CredentialsFor
- identity: null
where:
- 'node_class(?identity) == Identity # CanEscalateTo target set is strictly [Identity] (User/Role/ServiceAccount/ServicePrincipal/ManagedIdentity/...
are all Identity-class subtypes); a CredentialsFor target that resolves to a Data store is excluded
here'
- ?identity.privilege_level > ?principal.privilege_level
emit:
source_type: Identity
target_type: Identity
source: ?principal
target: ?identity
permissions:
- Microsoft.KeyVault/vaults/secrets/getSecret/action
state_logic: inherit the weaker of CanReadSecret and CredentialsFor states (CONDITIONAL(network_reachability)
or BLOCKED propagate)
confidence: min(contributing_confidences) * 0.95
derived_from:
- <CanReadSecret edge_id>
- <CredentialsFor edge_id>
false_positive_note: Only emit when the credentialed identity is strictly more privileged than the reader;
a lateral/same-privilege SP is not escalation. Requires the secret to be classified as a credential
(CredentialsFor present).
narrative: '{principal.name} can read secret {secret.name}, a credential for {identity.name}, and thereby
escalate to {identity.name}.'