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.

derived azure emits CanAttachIdentity

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'pipeline': None}

where

node_type(?pipeline) == BuildWorker ?principal holds 'Manage service endpoints' in DevOps service-endpoint security namespace

emit

source typeIdentity
target typeBuildWorker
source?principal
target?pipeline
permissionsManage service endpoints (DevOps service endpoint namespace)
conditionsrole_compatibility
state logicACTIVE 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.'
move · open · esc close