Advanced Zero Trust: Eligible Privilege and the Mover Problem
In this article
Summary
"Payments-Onboard" is an access package. It bundles a security group, an app role in the payments application, and a Privilege Identity Management (PIM) eligibility for a scoped administrator role, and it is assigned to anyone who joins the payments team. It works exactly as designed on the day someone joins. The interesting day is eleven months later, when that person moves to treasury, gets everything the new role needs, and keeps most of what the old one gave them. Nobody approved that outcome. Nobody noticed it either, because the systems that could have noticed were each looking at a different slice of the problem. Least privilege is a lifecycle rather than a one-time grant, and this article takes the mechanics of that seriously: which control removes what, what Privileged Identity Management (PIM) permits when you accept its defaults, and why the tiered model on the second slide is a set of commitments rather than a feature you enable.
The Mover Problem
Joiner and leaver of employees are events. A mover is a subtraction problem wearing the costume of an event, and subtraction is the part that does not happen.
Entitlement management is precise about its own scope. When an access package assignment ends, the resource roles that assignment granted are removed. That is the contract, and it is honoured. What it does not cover is anything granted by a route other than the package: a group somebody added by hand during an incident, an app role set inside the application's own admin console, a PIM eligibility created directly by a Privileged Role Administrator.
Lifecycle workflows do give you a place to hang the removal. The leaver side ships as three templates rather than one, covering the run-up to a last day, the day itself, and the period after, with built-in tasks addressed by identifiers. There is no equivalent built-in that computes what a mover should lose. You express that as a workflow you design, or it does not exist.
| Event | What the platform will do unprompted | What you have to build |
|---|---|---|
| Joiner | Provision the account, apply the access package, run the joiner workflow | Almost nothing. This is the well-served case, which is why it gets demonstrated. |
| Mover | Add what the new role's package grants | The entire removal side. Ending the old assignment is a deliberate step, and it only reaches package-granted access. |
| Leaver | Run pre-offboarding, offboarding and post-offboarding workflows if you configured all three | Sequencing, and the decision about what happens to access granted outside any package. |
Table 1 - Describes the asymmetry is structure. Two of the three events add; only one of them is designed to subtract.
What the Four Controls Cover
Put the four governance controls from the slide against the ways access actually arrives in a tenant, and the coverage is patchier than the diagram implies.
Reviews That Change Nothing
Since reviews are carrying most of the weight, their settings deserve more attention than they usually get. Two of them decide whether a review is a control or a report. defaultDecisionEnabled governs what happens to a user nobody reviewed, and it is false unless you change it, so silence means the access stays. autoApplyDecisionsEnabled governs whether recorded decisions are actually carried out. Leave that off and you get a completed review, a full set of Deny decisions, and every one of those users still holding their access.
Turn both on and the failure mode inverts: reviewers who ignore the campaign now revoke access by inaction. That is the safer direction for a package like "Payments-Onboard", and it needs to be a decision somebody makes knowingly rather than a checkbox found later. The inactivity recommendation helps here. With it enabled, the last sign-in date is evaluated when the review starts and anyone who has not signed in for 30 days gets a recommended Deny, which gives reviewers a defensible default instead of a wall of names.
Separation of Duties Is One-Way
The incompatibility relationship between two access packages is unidirectional. Marking the treasury package as incompatible with "Payments-Onboard" stops someone holding "Payments-Onboard" from requesting treasury access. It does nothing in the other direction until you go to the treasury package and add the reverse entry. Half-configured separation of duties is the normal state of a tenant, and it looks identical to the working version in the portal.
The check also runs at request time. It blocks new requests and it blocks an access package manager from creating a conflicting assignment, and it leaves every conflict that predates the configuration exactly where it is. Those are findable, either through the additionalAccess function on assignments or by exporting both assignment lists and comparing them, but nothing surfaces them on its own. For access granted outside entitlement management entirely, the Application role assignment activity workbook is the honest place to look, because it can show app role assignments that no access package created.
Eligible Is Not Unprivileged
An eligible assignment is a standing capability with a gate in front of it. Whether that gate is a control or a formality is decided entirely by the rules on the role management policy, and those rules have defaults. Reading them is a five-minute exercise that most PIM deployments never do.
Read together, the default posture is a self-service eight-hour activation, protected by multifactor authentication and a free-text justification, with no approver, no ticket reference, no device requirement, sitting on an eligibility that is not obliged to expire. The MFA and justification defaults are genuinely good. The rest is an audit trail rather than a barrier, and an audit trail is worth having as long as nobody mistakes it for prevention.
| Rule | Ships as | What it costs you |
|---|---|---|
| Approval_EndUser_Assignment | isApprovalRequired: false | Activation asks nobody. A compromised eligible account activates itself. |
AuthenticationContext_ EndUser_Assignment | isEnabled: false | You cannot demand phishing-resistant MFA or a compliant device at activation until this is on. |
| Expiration_Admin_Eligibility | isExpirationRequired: false, P365D | An eligibility created for a three-week project is still there next year. |
| Enablement_Admin_Eligibility | enabledRules: [] | An administrator can create an eligibility without recording a reason. |
| Expiration_EndUser_Assignment | PT8H, required | Nothing. Keep it, and shorten it for control-plane roles. |
Table 2 - Describes four defaults to change and one to leave alone. Read your own tenant's rules before designing around assumptions.
Activation itself is a single call, POST /roleManagement/directory/roleAssignmentScheduleRequests with action: "selfActivate", a justification, and a scheduleInfo carrying something like PT5H. Two details are worth knowing. The caller must already be in a session that was challenged for MFA, so activation cannot be the thing that first proves who they are. And the response comes back Granted when no approval is required against Provisioned for an administrative assignment, which is a useful signal to alert on if you expected an approver to be involved.
Planes, Not Tiers
Tier 0, Tier 1 and Tier 2 come from the Active Directory tier model. The current framing is the enterprise access model, where Tier 0 expands into a control plane that has to be isolated from the management and data planes so that control of a higher plane cannot be obtained from a lower one. The renaming matters less than the expansion. Anything that can manage or broker access to privileged roles is control plane, which pulls in jump hosts, session hosts, automation runbooks, and any service principal holding a privileged role. That last category is where most tenants are quietly inconsistent: the Logic App that can disable accounts is treated as automation, and it belongs in the same bucket as a domain controller.
There is no tier or plane attribute in Microsoft Entra. The boundary is assembled from separate control-plane accounts, privileged access workstations, restricted management administrative units so that lower-tier administrators cannot manage higher-tier objects, and Conditional Access policies with device filters targeting the admin roles. Each is a real mechanism. None of them is the model, and nothing in the portal will tell you the model is intact.
What I Would Do First
If a tenant only has appetite for one change, it is not a PIM rollout. Read the role management policy rules for the control-plane roles, turn on approval and authentication context for those roles specifically, and set eligibility expiry so that an eligibility has to be renewed rather than inherited. That is a morning's work and it converts the audit trail into an actual gate. The second change is enabling defaultDecisionEnabled and autoApplyDecisionsEnabled on the reviews covering anything that grants a role, with the inactivity recommendation on, and then living through one cycle of the complaints. Both changes are cheap. Both are usually skipped in favour of extending PIM to more roles, which grows the eligible population without tightening the gate.
Endpoints and Permissions
| Operation | Endpoint | Least-privileged permission |
|---|---|---|
| Activate an eligible role | POST /roleManagement/directory/ roleAssignmentScheduleRequests | RoleAssignmentSchedule. ReadWrite.Directory |
| Read the PIM rules for a role | GET /policies/ roleManagementPolicies?$expand=rules | RoleManagementPolicy. Read.Directory |
| Mark two packages incompatible | POST /identityGovernance/ entitlementManagement/accessPackages/ {id}/incompatibleAccessPackages/$ref | EntitlementManagement. ReadWrite.All |
| Find existing conflicts | GET /identityGovernance/ entitlementManagement/assignments/ additionalAccess | EntitlementManagement. Read.All |
| Create an access review | POST /identityGovernance/ accessReviews/definitions | AccessReview.ReadWrite.All |
| Run a lifecycle workflow now | POST /identityGovernance/ lifecycleWorkflows/workflows/{id}/activate | LifecycleWorkflows. ReadWrite.All |
Table 3 - Describes writing to the role management policies needs Privileged Role Administrator, which is itself a control-plane role. Plan the sequence.
Conclusion
Governance removes what it granted and nothing else, and PIM gates what you tell it to gate. "Payments-Onboard" will keep working perfectly for every joiner and keep leaving residue behind every mover until somebody writes the subtraction down. Read your role management policy rules, decide what silence means in an access review, and treat the runbook that can disable accounts as control plane. None of that is a feature you switch on.