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.

derived azure emits CanPassIdentity

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