Entra ID Automation #5 PIM and Auditing: Killing Standing Admins, Logs, and Access Reviews
The track’s final topic is the top of the privilege ladder and the records beneath it: how to keep admin rights minimal, and how to watch who did what, automatically. With this in place, the JML lifecycle drawn in part 1 becomes a closed loop that includes privilege and audit.
The problem: standing admin rights are incidents-in-waiting #
Picture an organization with five accounts holding standing Global Administrator rights. One successful phish against any of them and the tenant is gone. Privileges are held far longer than they are used, and every held hour is attack surface.
PIM (Privileged Identity Management) changes the time axis of privilege. It requires Entra ID P2 or a Governance license.
- Eligible assignment: the user is a candidate for the role, with no privileges day-to-day.
- Activation: when needed, the user requests activation — justification, MFA, approval if configured — and receives a time-boxed active assignment (up to 8 hours, reducible in role settings).
- Expiry: the privilege is revoked automatically when time runs out. “Forgot to revoke” ceases to exist as a concept.
The end state: standing Global Admins shrink to just the break-glass accounts from part 4, and every human’s day-to-day privilege becomes eligibility plus activation. Every activation is recorded with its justification, so “who was an admin last quarter, and why” becomes a single query.
PIM through the API: assignment and activation #
PIM is fully automatable through Graph, via the schedule-request resources under roleManagement/directory.
- Eligible assignment (admin): POST to
roleEligibilityScheduleRequestswith the principal, role, and duration. Onboarding automation can grant “Helpdesk Administrator eligibility for IT-team joiners” in code. - Self-activation (user): POST to
roleAssignmentScheduleRequestswith theSelfActivateaction. Justification is mandatory, and including a ticket number is standard practice. Your own activatable eligibilities are listed via thefilterByCurrentUserfunction. - Role settings: per-role policy controls maximum activation duration, approval requirements, and MFA.
The practical pattern combines this with part 3’s role-assignable groups: attach role eligibility to the group, and team onboarding reduces to group membership while privilege use stays controlled by individual activation. Management unit (the group) and usage control (activation) separate cleanly.
Audit and sign-in logs: consuming the record with code #
Entra ID writes two core logs, both queryable through Graph.
GET https://graph.microsoft.com/v1.0/auditLogs/directoryAudits
?$filter=activityDateTime ge 2026-09-01T00:00:00Z
GET https://graph.microsoft.com/v1.0/auditLogs/signIns
?$filter=status/errorCode ne 0- Directory audit logs (directoryAudits): who created and changed users, groups, policies, roles.
- Sign-in logs (signIns): every authentication attempt — failure codes, location, client app, and which Conditional Access policies applied. Part 4’s report-only impact analysis draws from this same source.
Automation uses them in two stages. First, scheduled reports: a script that queries daily for high-risk events — new admin role grants, break-glass sign-ins, new app registrations — and posts to a channel is half a day’s work with outsized payoff. Second, SIEM integration: with large volumes or long retention requirements, stream the logs via diagnostic settings into Log Analytics or a SIEM and manage alert rules there. Graph polling is for small scale and prototypes; streaming is for production-grade monitoring.
Access reviews: giving permissions an expiry date #
However good JML automation gets, access accumulates over time: project groups outlive projects, old app access outlives role changes. Access reviews clean this decay with scheduled re-certification (P2 and up; some scenarios require Governance).
- Define the target (group membership, app assignments, admin roles), the cadence (quarterly, say), and the reviewers (group owners, managers, or the users themselves).
- Set the default outcome for non-responding reviewers to “remove,” and neglect becomes cleanup. This one setting decides whether access reviews have teeth.
- Review creation and result collection are automatable through Graph’s
identityGovernance/accessReviewsAPIs — “every admin role gets a review auto-created each quarter” can be guaranteed in code.
Guest accounts and admin roles are the two top-priority review targets. Combined with part 3’s access package expiry, you reach the state where every granted access has either an expiry date or a recurring review.
Closing the track: adoption order #
The realistic order for applying these five parts to a real organization:
- Attribute standardization and the user lifecycle (part 2): clean source data underpins everything else, and leaver automation is the most urgent security win.
- Group redesign (part 3): dynamic groups plus group-based licensing take the Mover flow unattended.
- Conditional Access (part 4): validate a baseline set in report-only, then move it into policy-as-code.
- PIM and audit (this part): convert standing admins to eligibility, close the loop with high-risk alerts and access reviews.
The Graph API fundamentals (auth, throttling, pagination) assumed throughout come from the Microsoft Graph in Practice track — start there if the code feels unfamiliar.
Summary #
- Standing admin rights are attack surface. PIM converts them to eligibility + time-boxed activation (max 8 hours) + recorded justification, leaving only break-glass accounts standing.
- PIM is fully API-manageable via
roleEligibilityScheduleRequests(eligibility) androleAssignmentScheduleRequests(activation); combining with role-assignable groups is the working pattern. - Query audit and sign-in logs through Graph for high-risk event alerts; graduate to SIEM streaming as scale grows.
- Access reviews give permissions an expiry. Default non-response to removal, and start with guests and admin roles.
- Adoption order: user lifecycle → groups → Conditional Access → PIM and audit. Clean source data is always step one.