azure-msgraph-app-ownership

A service principal holding Application.ReadWrite.All can add itself as the owner of any app registration, granting it permanent owner-level control (credential addition, configuration change) independent of the original permission grant.

derived azure emits CanTakeOwnership

match

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

{'sp': None} HasRole {'approle': None}

where

node_type(?sp) in [MachineIdentity, ApplicationIdentity] ?approle is Application.ReadWrite.All (id: 1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9) on microsoft.graph SP

emit

source typeIdentity
target type*
source?sp
target<any ApplicationIdentity in the tenant>
permissionsApplication.ReadWrite.All
conditionsiam_permission service_state
state logicACTIVE when the appRoleAssignment for Application.ReadWrite.All is granted and the SP credential is valid. CONDITIONAL(service_state) if SP credential is expired. Inherits weakest from the HasRole input. Not blocked by ARM RBAC deny assignments (Graph authorization is Entra-only). Elevated-privilege apps (Global Admin app registrations) may require additional authorization in future Entra hardening — flag CONDITIONAL in tenants with Entra Privileged Access hardening applied.

Narrative

{sp.name} holds Application.ReadWrite.All and can add itself as owner of any app registration via POST /applications/{id}/owners/$ref, gaining permanent owner-level control over that app's credentials and configuration regardless of subsequent permission changes.

Raw rule rules/derived/azure/msgraph.yaml

id: azure-msgraph-app-ownership
emits: CanTakeOwnership
description: A service principal holding Application.ReadWrite.All can add itself as the owner of any
  app registration, granting it permanent owner-level control (credential addition, configuration change)
  independent of the original permission grant.
match:
- - sp: null
  - HasRole
  - approle: null
where:
- node_type(?sp) in [MachineIdentity, ApplicationIdentity]
- '?approle is Application.ReadWrite.All (id: 1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9) on microsoft.graph
  SP'
emit:
  source_type: Identity
  target_type: '*'
  source: ?sp
  target: <any ApplicationIdentity in the tenant>
  permissions:
  - Application.ReadWrite.All
  conditions:
  - iam_permission
  - service_state
  state_logic: "ACTIVE when the appRoleAssignment for Application.ReadWrite.All is granted and the SP\
    \ credential is valid. CONDITIONAL(service_state) if SP credential is expired. Inherits weakest from\
    \ the HasRole input. Not blocked by ARM RBAC deny assignments (Graph authorization is Entra-only).\
    \ Elevated-privilege apps (Global Admin app registrations) may require additional authorization in\
    \ future Entra hardening \u2014 flag CONDITIONAL in tenants with Entra Privileged Access hardening\
    \ applied."
  confidence: '0.9'
  derived_from:
  - <HasRole edge_id (appRoleAssignment Application.ReadWrite.All on ?sp)>
  - "azure/identity-escalation.yaml#azure-app-sp-ownership (object ownership path \u2014 parallel; this\
    \ covers the app-permission path)"
  false_positive_note: "CanTakeOwnership of every app is a significant blast-radius claim \u2014 the SP\
    \ can add itself as owner of ANY app, including high-privilege first-party Microsoft apps (exchange,\
    \ SharePoint). Practically, the first escalation step will target the highest-privilege SP in the\
    \ tenant. This edge feeds the ownership -> CanCreateCredentialFor chain in identity-escalation.yaml\
    \ (azure-app-sp-ownership). Do NOT emit if Application.ReadWrite.All is not present in appRoleAssignments.\
    \ Dedupe with rule 2 (azure-msgraph-app-readwrite-cred) on (CanCreateCredentialFor, ?sp, ?target)\
    \ \u2014 the two rules emit different edges (CanTakeOwnership here vs CanCreateCredentialFor in rule\
    \ 2) so no dedup needed between rules, but both should reference the same appRoleAssignment."
  narrative: '{sp.name} holds Application.ReadWrite.All and can add itself as owner of any app registration
    via POST /applications/{id}/owners/$ref, gaining permanent owner-level control over that app''s credentials
    and configuration regardless of subsequent permission changes.'
move · open · esc close