azure-kv-secret-cross-subscription
A secret credential for a principal in another subscription yields entry there.
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
?identity home subscription != ?principal home subscription
emit
| source type | Identity |
|---|---|
| target type | Subscription |
| source | ?principal |
| target | <subscription of ?identity> |
| permissions | Microsoft.KeyVault/vaults/secrets/getSecret/action |
| state logic | inherit the weaker of CanReadSecret and CredentialsFor states |
Narrative
{principal.name} reads secret {secret.name} (a credential for {identity.name}) and gains access in subscription {subscription.name}.
Raw rule rules/derived/azure/keyvault.yaml
id: azure-kv-secret-cross-subscription
emits: CanEnterSubscription
description: A secret credential for a principal in another subscription yields entry there.
match:
- - principal: null
- CanReadSecret
- secret: null
- - secret: null
- CredentialsFor
- identity: null
where:
- ?identity home subscription != ?principal home subscription
emit:
source_type: Identity
target_type: Subscription
source: ?principal
target: <subscription of ?identity>
permissions:
- Microsoft.KeyVault/vaults/secrets/getSecret/action
state_logic: inherit the weaker of CanReadSecret and CredentialsFor states
confidence: min(contributing_confidences) * 0.9
derived_from:
- <CanReadSecret edge_id>
- <CredentialsFor edge_id>
false_positive_note: Only when the credentialed identity actually holds access in the other subscription.
A secret naming an SP with no cross-sub roles does not yield subscription entry.
narrative: '{principal.name} reads secret {secret.name} (a credential for {identity.name}) and gains
access in subscription {subscription.name}.'