azure-devops-sc-pass-identity
DevOps 'Manage service endpoints' permission lets a principal create a new service connection embedding a chosen Entra SP's credentials, enabling identity-swap escalation paths.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
HasPermission {'service_endpoint_namespace': None}
{'principal': None} CanCreateCredentialFor {'target_sp': None}
where
?principal holds 'Manage service endpoints' in DevOps service-endpoint security namespace
node_type(?target_sp) in [
ApplicationIdentity, ServiceAccount]
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | ?principal |
| target | ?target_sp |
| permissions | Manage service endpoints (DevOps service endpoint namespace) CanCreateCredentialFor (?target_sp) |
| conditions | iam_permission role_compatibility |
| state logic | ACTIVE when the principal holds Manage service endpoints AND can create/add credentials for the target SP (MS Graph Application.ReadWrite or Owner on the SP). The principal can then create an ARM service connection wrapping ?target_sp's credentials and bind it to a pipeline, enabling CanExecuteAs the target SP via execute-as-via-config-identity-swap. |
Narrative
{principal.name} can create a new ARM service connection embedding credentials for {target_sp.name} (Manage service endpoints + CanCreateCredentialFor), enabling identity-swap escalation when combined with Edit pipeline definition.
Raw rule rules/derived/azure/devops.yaml
id: azure-devops-sc-pass-identity
emits: CanPassIdentity
description: DevOps 'Manage service endpoints' permission lets a principal create a new service connection
embedding a chosen Entra SP's credentials, enabling identity-swap escalation paths.
applies_to:
- azure
match:
- - principal: null
- HasPermission
- service_endpoint_namespace: null
- - principal: null
- CanCreateCredentialFor
- target_sp: null
where:
- ?principal holds 'Manage service endpoints' in DevOps service-endpoint security namespace
- node_type(?target_sp) in [ApplicationIdentity, ServiceAccount]
emit:
source_type: Identity
target_type: Identity
source: ?principal
target: ?target_sp
permissions:
- Manage service endpoints (DevOps service endpoint namespace)
- CanCreateCredentialFor (?target_sp)
conditions:
- iam_permission
- role_compatibility
state_logic: ACTIVE when the principal holds Manage service endpoints AND can create/add credentials
for the target SP (MS Graph Application.ReadWrite or Owner on the SP). The principal can then create
an ARM service connection wrapping ?target_sp's credentials and bind it to a pipeline, enabling CanExecuteAs
the target SP via execute-as-via-config-identity-swap.
confidence: 0.85
derived_from: []
false_positive_note: "The CanCreateCredentialFor precondition is critical \u2014 Manage service endpoints\
\ alone does NOT yield CanPassIdentity unless the principal also holds MS Graph permissions to add\
\ credentials to the target SP. This is a conjunction, not an unconditional path."
narrative: '{principal.name} can create a new ARM service connection embedding credentials for {target_sp.name}
(Manage service endpoints + CanCreateCredentialFor), enabling identity-swap escalation when combined
with Edit pipeline definition.'