Skip to content

Prohibited CI Permissions

Part of the Security Model. This page lists the directory roles, Microsoft Graph permissions and Azure RBAC assignments that a CI identity must never hold if its pipeline applies changes. It applies the Access Tiering Model and the Role Tier Mapping. For why Tier 0 is never applied by CI, see Tier 0 Pipeline Design.

Related:


The test

A permission is prohibited for an applying CI identity if it lets the holder do any of these:

  1. Grant privilege: assign directory roles, Azure roles at the top of the hierarchy, or app role grants, including to itself.
  2. Take over another identity: add a credential to any app, reset a user's authentication methods, or add itself to a group that holds privilege.
  3. Change who gets in: edit Conditional Access, PIM settings, access packages or the pipeline-identity roster.
  4. Reach Tier 0 state: write to rg-terraform-state, where the state of every Tier 0 deployment lives.

Any one of these makes the holder Tier 0. A pipeline that applies on merge can't hold Tier 0 privilege, because a merge is then all it takes to make that privilege live. If a deployment needs one of these permissions, it is Tier 0: CI plans with a read-only identity and a human applies under PIM (Lane A). See Lane A and Lane B Delivery Methodology.

Read-only identities are fine

A Lane A plan identity (sp-*-ro) can read anything it needs to plan. The prohibition is on write rights held by an identity whose pipeline applies.


Entra ID directory roles

solution-manage-azure-service-principals accepts only a safelist of read-only roles: Global Reader, Directory Readers, Reports Reader, Security Reader and Message Center Reader. Anything else fails the plan. The roles below are the ones that matter most:

Role Why it's prohibited
Global Administrator Everything.
Privileged Role Administrator Can assign any directory role, including Global Administrator, and manage PIM for directory roles.
Privileged Authentication Administrator Can reset passwords and authentication methods of any user, including Global Administrators.
Authentication Administrator Can reset authentication methods of non-admin users, which takes over their accounts.
Application Administrator / Cloud Application Administrator Can add credentials to any app registration or service principal and sign in as it, inheriting its permissions.
User Administrator Can reset passwords and manage most users and groups.
Groups Administrator Can change membership of groups that grant access.
Conditional Access Administrator Can change or disable Conditional Access, including the policies that protect admins.
Security Administrator Can change security policy, Identity Protection and Conditional Access settings.
Identity Governance Administrator Can change access packages and access reviews, which decide who becomes eligible for persona groups.

Directory roles for applying identities belong in the azure-tenant-bootstrap roster, applied by a human under PIM.


Microsoft Graph application permissions

Application permissions are tenant-wide and have no user in the loop. These are prohibited for an applying identity:

Permission Why it's prohibited Use instead
RoleManagement.ReadWrite.Directory (and any other RoleManagement.* write) Can assign any directory role, including Global Administrator. Nothing. This is Tier 0 by definition.
Application.ReadWrite.All Can add a credential to any app and sign in as it. Application.ReadWrite.OwnedBy
AppRoleAssignment.ReadWrite.All Can grant any app any permission, including itself RoleManagement.ReadWrite.Directory. Nothing. Grant permissions in t0-azure-service-principals.
Group.ReadWrite.All / GroupMember.ReadWrite.All Can change membership of groups that grant access. Group.Create, plus ownership of the groups it creates
Directory.ReadWrite.All Broad write over users, groups and apps. A narrower .Read. permission, or the specific write permission scoped as above
UserAuthenticationMethod.ReadWrite.All Can add or reset authentication methods for any user, which takes over their account. Nothing for a pipeline.
Policy.ReadWrite.ConditionalAccess Can change or disable Conditional Access. Nothing for an applying pipeline. t0-azure-conditional-access is Lane A: CI plans with read-only Graph, and a human applies as Conditional Access Administrator.
PIM permissions: PrivilegedAccess.ReadWrite.AzureADGroup, PrivilegedAssignmentSchedule.ReadWrite.*, PrivilegedEligibilitySchedule.ReadWrite.*, RoleManagementPolicy.ReadWrite.* Can make someone eligible for, or active in, a privileged role or group, or remove the MFA and approval rules on activation. Nothing. PIM is Control plane.
EntitlementManagement.ReadWrite.All Can change the access packages that decide who becomes eligible for persona groups. Nothing (see EX-002 below).

OwnedBy and Group.Create are the safe forms

Application.ReadWrite.OwnedBy lets a pipeline manage only the apps it owns, so it can't take over anyone else's. Group.Create lets it create groups and own them, without write access to every other group. Use these whenever they do the job.


Azure RBAC

Assignment Why it's prohibited
Owner, User Access Administrator or Role Based Access Control Administrator at the Tenant Root Group or mg-intermediate-root, without an ABAC condition Can grant any role across the whole managed tenant, including to itself. See Role Tier Mapping.
Any role assignment at the Tenant Root Group Needs roleAssignments/write there, which is Tier 0 by mechanism.
Management Group Contributor (or anything that can move subscriptions or management groups) at mg-intermediate-root or above Can change the management group hierarchy, moving subscriptions out from under the policy and RBAC that govern them.
Any write role that reaches rg-terraform-state Tier 0 state lives here (see below).

Tier 0 state

Every Tier 0 deployment keeps its state in sa17452008tenantroot, in rg-terraform-state, in the management subscription under mg-management. Anyone who can write to that state can change what the next human apply does, or read secrets out of it. So any write role at a scope that contains it makes the holder Tier 0:

  • Owner, Contributor, Storage Account Contributor or Storage Blob Data Contributor / Owner on the storage account, rg-terraform-state, the management subscription, mg-management or mg-platform.
  • Access to the storage account keys (listKeys).

A Terraform pipeline gets Storage Blob Data Contributor on its own container only, plus Reader on rg-terraform-state, through state_rbac in t0-azure-service-principals. Workload pipelines keep their state outside it, in rg-terraform-state-workloads-prod.


How it's enforced

Control What it stops
Directory role safelist in solution-manage-azure-service-principals Any directory role other than the five read-only roles fails the plan.
operator_sp_roles ABAC condition (solution-privileged-access-allowlist) The operator applying t0-azure-service-principals can only assign the roles on the list. Anything else fails with a 403.
Reviewer checklist in Create a Service Principal Graph permissions and RBAC scopes from this page are caught in the MR.
Lane A (ci-only-guard.tf, no apply.yml, read-only plan identity) A Tier 0 deployment's CI can only plan.

Graph permissions aren't blocked in code, so the MR review is the control for them.


Exceptions and gaps

Where a pipeline does hold one of these permissions today, it's recorded in the Exceptions Register:

ID What it holds Status
EX-002 azure-privileged-access-packages: EntitlementManagement.ReadWrite.All, RoleManagementPolicy.ReadWrite.AzureADGroup, Group.ReadWrite.All Accepted (Lane B: no human can get these scopes)
EX-003 EPAC deploy identity: RBAC Administrator at mg-intermediate-root Accepted
GAP-011 subscription-vending-workload: its own state in the Tier 0 state account, and a group-wide GitLab token. Its RBAC is already down at mg-landingzones / mg-sandboxes Known gap

EX-001 (azure-entra-diagnostics, Security Administrator) and EX-006 (Conditional Access, Policy.ReadWrite.ConditionalAccess) are closed: both projects moved to Lane A.

A new exception needs an entry in the register before the MR merges.