azure-devops-sc-attach-to-pipeline
DevOps 'Manage service endpoints' permission lets a principal bind a different - potentially more privileged - service connection to a pipeline, changing its execution identity.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?pipeline) ==
BuildWorker
?principal holds 'Manage service endpoints' in DevOps service-endpoint security namespace
emit
| source type | Identity |
|---|---|
| target type | BuildWorker |
| source | ?principal |
| target | ?pipeline |
| permissions | Manage service endpoints (DevOps service endpoint namespace) |
| conditions | role_compatibility |
| state logic | ACTIVE when the permission is held and the principal can reference a target service connection (has 'Use' or 'Administrator' on it). CONDITIONAL(role_compatibility) when the target SC requires additional authorization. |
Narrative
{principal.name} can bind a different service connection to pipeline {pipeline.name} (DevOps 'Manage service endpoints'), changing which Azure identity the pipeline executes as. If the new service connection is more privileged, this is a privilege escalation.
Raw rule rules/derived/azure/devops.yaml
id: azure-devops-sc-attach-to-pipeline
emits: CanAttachIdentity
description: "DevOps 'Manage service endpoints' permission lets a principal bind a different \u2014 potentially\
\ more privileged \u2014 service connection to a pipeline, changing its execution identity."
applies_to:
- azure
match:
- - principal: null
- HasPermission
- pipeline: null
where:
- node_type(?pipeline) == BuildWorker
- ?principal holds 'Manage service endpoints' in DevOps service-endpoint security namespace
emit:
source_type: Identity
target_type: BuildWorker
source: ?principal
target: ?pipeline
permissions:
- Manage service endpoints (DevOps service endpoint namespace)
conditions:
- role_compatibility
state_logic: ACTIVE when the permission is held and the principal can reference a target service connection
(has 'Use' or 'Administrator' on it). CONDITIONAL(role_compatibility) when the target SC requires
additional authorization.
confidence: 0.85
derived_from: []
false_positive_note: "This edge models the ability to CHANGE the identity binding. Escalation only occurs\
\ if the new SC is MORE privileged than the old. The edge target is the Pipeline (Compute), not the\
\ identity \u2014 CanAttachIdentity(principal -> pipeline). The downstream escalation (CanExecuteAs\
\ the more-privileged SC identity) is derived by can-execute-as execute-as-via-config-identity-swap\
\ off the resulting CanModifyConfiguration + CanPassIdentity combination. Also see azure-devops-sc-pass-identity\
\ for the CanPassIdentity fact."
narrative: '{principal.name} can bind a different service connection to pipeline {pipeline.name} (DevOps
''Manage service endpoints''), changing which Azure identity the pipeline executes as. If the new
service connection is more privileged, this is a privilege escalation.'