Just-in-time activation for cloud-only accounts: disabled by default, enabled on request, expired automatically.
VERSION 1.0 | 07/10/2026Temporary and test accounts are among the least governed identities in most Microsoft Entra ID tenants. They are created quickly, rarely owned by a named person, and often left enabled long after the work has finished. Attackers look for exactly these accounts, because nobody notices when one of them signs in.
This strategy treats every temporary or test account as a dormant asset. Each account stays disabled until a named owner requests it for a fixed period, with a business reason and, where needed, an approval. When the period ends, the account is disabled again without anyone having to remember. The model mirrors Privileged Identity Management (PIM), which most organisations already use for administrator roles.
Microsoft does not offer this as a single product feature. It is assembled from standard Entra ID components plus a small amount of automation, and it can be delivered in four phases over roughly twelve weeks. Three licensing routes are set out, so the design can be adopted whether the organisation holds Entra ID P1, P2 or Entra ID Governance licences.
A test account exists to prove that something works. Once the test is complete, the account has no purpose, yet it normally remains enabled with a password that someone wrote down. A temporary account for a contractor or a migration behaves the same way. Over several years a tenant accumulates dozens or hundreds of these identities.
The risk has four parts, and each compounds the others:
An enabled account that nobody is using is pure exposure with no offsetting benefit. Reducing the time each account is enabled is therefore the single most effective control available.
| Principle | What it means in practice |
|---|---|
| Disabled by default | Every temporary or test account is disabled unless an activation is in force. |
| Always owned | Every account has one named, current employee as owner. An account without an owner is disabled and then deleted. |
| Time-boxed | Activation lasts for a fixed period chosen at request time, up to an agreed maximum. |
| No standing credentials | The owner receives a short-lived sign-in code at activation. No password is stored or shared. |
| No standing privilege | Test accounts never hold permanent administrator roles. Privilege needs a second, separate activation. |
| Born with an end date | Each account is created with an expiry date, and is deleted when that date passes unless renewed. |
| Tamper resistant | Only the automation and a small administrator group can change these accounts. |
| Fully evidenced | Every request, approval, enablement and expiry is logged and reportable. |
The recommended design uses Entitlement Management, part of Entra ID Governance, as the request and approval front end. An access package represents “permission to have a test account active”. A custom extension links the access package to an Azure Logic App, which carries out the enablement and disablement through the Microsoft Graph Application Programming Interface (API). Microsoft documents custom extension triggers for when an assignment is granted and when it is removed, which map directly onto activation and expiry [1].
| Component | Role in the design |
|---|---|
| Account tagging | An extension attribute (for example extensionAttribute10 = TESTACCT or TEMPACCT) identifies in-scope accounts. The manager attribute records the owner. A second extension attribute holds the account end date. |
| Restricted management administrative unit | Holds all in-scope accounts. Only administrators with a role assigned at the scope of the unit can change the accounts inside it [3]. |
| Access package | One package per account class (test, temporary), held in a dedicated catalogue. It grants membership of a marker group and carries the request questions, approval and expiry policy. |
| Custom extension and Logic App | Fires on “assignment granted” and “assignment removed” [1]. Runs under a system-assigned managed identity. |
| Temporary Access Pass (TAP) | A time-limited passcode issued to the owner at activation. Removes the need for a stored password. |
| Conditional Access policy | Targets a dynamic group of tagged accounts. Restricts device, location and session length. |
| Reconciliation sweep | A scheduled job that disables any tagged account that is enabled without a current assignment. |
| Monitoring | Alert rules over the Entra ID audit and sign-in logs, in Microsoft Sentinel or Log Analytics. |
A disabled account cannot sign in to request its own activation, so the request has to come from a person. In the recommended model the owner requests the access package for themselves and names the target account in a request question. The Logic App then confirms that the requester is the recorded owner of that account before it acts.
This model has two practical advantages. Only the human owners need governance licences, not the test accounts. It also avoids making a disabled account the subject of an access request, a scenario that should not be assumed to work without testing.
The trade-off is that an owner holds one assignment per access package at a time. An owner who needs several accounts live together should be able to list more than one account in a single request, and the Logic App should handle a list.
accountEnabled to true, creates a single-use TAP, and sends it to the owner over an authenticated channel. It writes a record of the activation.accountEnabled to false, revokes sign-in sessions and deletes any remaining TAP.| Tier | Duration | Approval | Typical use |
|---|---|---|---|
| Short | Up to 8 hours | Automatic, justification required | Functional testing, reproducing a fault |
| Standard | Up to 5 days | Line manager or service owner | Test cycle, user acceptance testing |
| Extended | Up to 30 days | Security team | Temporary worker, migration project |
Each tier is implemented as a separate assignment policy on the access package. Durations are starting points to be tuned to the organisation.
Place every in-scope account in a restricted management administrative unit. Tenant-wide administrators, including User Administrators, then lose the ability to enable the accounts or reset their credentials by hand. Assign the Logic App identity and a small break-fix group the roles they need at the scope of the unit only. The restricted setting must be chosen when the unit is created; it cannot be applied afterwards.
Temporary and test accounts hold no permanent directory roles or Azure role assignments. Where a test needs privilege, make the account eligible through PIM for Groups, so that privilege requires its own activation with its own time limit. Two independent time limits then apply: one for the account and one for the privilege.
| Alert | Why it matters |
|---|---|
| Tagged account enabled by anything other than the automation identity | Someone has bypassed the process. |
| Sign-in by a tagged account with no active assignment | The account should have been disabled; the control has failed or been evaded. |
| Role or privileged group assignment to a tagged account | Standing privilege is being introduced. |
| Tag, manager or administrative unit membership changed | An account may be leaving the control boundary. |
| New account matching the naming pattern but untagged | An account was created outside the approved route. |
| Logic App run failures | An expiry may not have been enforced. |
Accounts are created through one route only: a request form or service desk item that captures the owner, purpose and end date. The automation creates the account in a disabled state, applies the naming convention (for example tst- and tmp- prefixes), sets the tag, and adds the account to the administrative unit. No password is issued.
Owners confirm each quarter that their accounts are still needed. An access review is the natural mechanism where licensing allows; otherwise a scheduled report to each owner works. Accounts that are not confirmed are scheduled for deletion.
When an owner leaves or changes role, ownership passes to their manager for fourteen days. If nobody claims the account in that period, it is deleted.
| Trigger | Action |
|---|---|
| End date reached | Owner notified 14 days before; account deleted on the date unless renewed. |
| No activation for 90 days | Owner notified; account deleted after a further 14 days. |
| No valid owner | Account deleted after 14 days. |
Deleted users remain recoverable in Entra ID for 30 days, which gives a safety margin for mistakes.
The design can be reached by three routes. They differ in how polished the request experience is and how much custom automation the organisation has to own. Microsoft lists custom extensions for Entitlement Management among its Entra ID Governance features [4], so the recommended route needs that licence for the people who make requests.
| Route A: Governance | Route B: P2 | Route C: P1 | |
|---|---|---|---|
| Request front end | Access package in My Access | PIM for Groups activation | Form or service desk request |
| Approval and expiry | Native, policy-driven | Native to PIM | Built into the Logic App |
| Enable and disable | Event-driven via custom extension | Scheduled job polling group membership | Logic App with a timed delay, plus sweep |
| Latency | Near real time | Up to the polling interval, typically 5 minutes | Near real time to enable |
| Audit trail | Strong, native | Strong, native | Adequate, custom |
| Custom code to maintain | Low | Medium | Highest |
| Who needs the higher licence | Account owners | Account owners | Nobody beyond P1 |
Route B in brief. Each owner is made eligible for a group that represents their test accounts. Activating the group membership in PIM is the request. A scheduled job reads group membership and enables or disables the matching accounts. The experience is familiar to anyone who already uses PIM, at the cost of a short polling delay.
Route C in brief. The guardrails in section 6 do most of the risk reduction and need only P1. The request and timing logic is entirely custom, so the organisation carries more build and support effort.
| Phase | Weeks | Activities | Exit criteria |
|---|---|---|---|
| 0. Discover | 1–2 | Inventory candidate accounts by name pattern, sign-in history and licence. Identify owners. Disable accounts with no sign-in for 90 days. | Every candidate account is classified, owned or disabled. |
| 1. Contain | 3–4 | Apply tags. Create the restricted administrative unit, dynamic group and Conditional Access policy in report-only mode, then enforce. Remove standing roles. Stand up the monitoring alerts. | All in-scope accounts are inside the control boundary with no standing privilege. |
| 2. Automate | 5–8 | Build the catalogue, access package, custom extension and Logic App. Pilot with one team. Disable all pilot accounts by default. Build the reconciliation sweep. | Pilot team activates and expires accounts with no manual intervention. |
| 3. Govern | 9–12 | Extend to all teams. Close the old creation routes. Start quarterly reviews and automated deletion. Publish the standard and report metrics. | No tagged account is enabled without an active assignment. |
Phases 0 and 1 deliver most of the risk reduction and do not depend on the licensing decision. They can begin immediately.
| Item | Type | Treatment |
|---|---|---|
| The automation identity can enable accounts and issue sign-in codes, so it becomes a high-value target. | Risk | Use a managed identity with no credentials to steal. Scope its roles to the administrative unit. Restrict who can edit the Logic App and alert on changes. |
| An expiry event is missed because the Logic App fails. | Risk | Hourly reconciliation sweep and a failure alert. |
| Teams create untagged accounts to avoid the process. | Risk | Restrict user creation rights, detect by naming pattern, and make the approved route quick. |
| The sign-in code is intercepted on its way to the owner. | Risk | Single-use code with a short lifetime, sent only over an authenticated internal channel. |
| Automated tests need accounts available without a human request. | Risk | Move these to workload identities, or allow the pipeline identity to hold the request role under the same time limits. |
| Request-question answers are passed to the Logic App in the custom extension payload. | Assumption | Confirm in the pilot. If not, the Logic App reads the request through Microsoft Graph. |
| Graph application permissions alone are not sufficient to modify accounts inside a restricted administrative unit; a scoped role is needed. | Assumption | Confirm in the pilot and record the final permission set. |
| Maximum activation period and deletion thresholds. | Decision | Risk committee, with input from test and delivery leads. |
| Licensing route. | Decision | Risk committee, following confirmation of current entitlements. |
The material below is a starting point for the build team. It has not been run against a live tenant and should be validated during the pilot.
TRIGGER Entitlement Management custom extension (HTTP request)
READ stage, requester object ID, assignment end time, answers (target accounts)
FOR EACH target account
GET user: accountEnabled, extensionAttribute10, manager
CHECK tag is TESTACCT or TEMPACCT else reject and alert
CHECK manager ID equals requester ID else reject and alert
IF stage = assignment granted
PATCH user: accountEnabled = true
POST temporaryAccessPassMethods: single use, short lifetime
SEND pass to requester over authenticated channel
LOG account, requester, justification, end time
IF stage = assignment removed
PATCH user: accountEnabled = false
POST revokeSignInSessions
DELETE any remaining temporaryAccessPassMethods
LOG account, requester, actual end time
| Purpose | Candidate permission or role |
|---|---|
| Read users and managers | User.Read.All |
| Enable and disable accounts | User.EnableDisableAccount.All, or User Administrator scoped to the administrative unit |
| Issue and delete a TAP | UserAuthenticationMethod.ReadWrite.All, or Authentication Administrator scoped to the administrative unit |
| Revoke sessions | User.RevokeSessions.All |
Prefer roles scoped to the administrative unit over tenant-wide application permissions wherever the pilot shows they are sufficient.
(user.extensionAttribute10 -eq "TESTACCT") or (user.extensionAttribute10 -eq "TEMPACCT")
active = target accounts named in current access package assignments
tagged = users where extensionAttribute10 in (TESTACCT, TEMPACCT)
FOR EACH user in tagged
IF user.accountEnabled AND user NOT IN active
disable user, revoke sessions, raise alert "enabled outside process"
IF user.manager is empty OR manager is disabled
flag "no valid owner"
IF end date has passed
queue for deletion
Enablement by anything other than the automation identity:
AuditLogs
| where OperationName in ("Enable account", "Update user")
| mv-expand prop = TargetResources[0].modifiedProperties
| where prop.displayName == "AccountEnabled" and prop.newValue has "true"
| extend target = tostring(TargetResources[0].userPrincipalName)
| where target startswith "tst-" or target startswith "tmp-"
| extend actor = coalesce(tostring(InitiatedBy.app.displayName),
tostring(InitiatedBy.user.userPrincipalName))
| where actor != "<automation identity name>"
Sign-ins by tagged accounts, for comparison against the activation log:
SigninLogs
| where UserPrincipalName startswith "tst-" or UserPrincipalName startswith "tmp-"
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress,
ResultType, ConditionalAccessStatus
| Term | Plain-language meaning |
|---|---|
| Access package | A bundle of access that a person can request for a set period through a self-service portal. |
| Administrative unit | A container in Entra ID that limits which administrators can manage the accounts inside it. |
| Application Programming Interface (API) | A way for one piece of software to instruct another. |
| Cloud-only account | An account that exists only in Entra ID and is not copied from an on-premises directory. |
| Conditional Access | Rules that decide whether a sign-in is allowed, based on who, where, and on what device. |
| Custom extension | A hook that lets Entitlement Management call an organisation’s own automation at set points. |
| Entitlement Management | The Entra ID feature that handles access requests, approvals and expiry. |
| Logic App | A Microsoft Azure service for building automated workflows without managing servers. |
| Managed identity | An identity for automation that Microsoft manages, with no password or key for anyone to steal. |
| Microsoft Graph | The interface through which software reads and changes data in Microsoft 365 and Entra ID. |
| Multi-Factor Authentication (MFA) | Signing in with two or more proofs of identity, such as a password and a phone prompt. |
| Privileged Identity Management (PIM) | The Entra ID feature that grants administrator rights only for a limited, requested period. |
| Temporary Access Pass (TAP) | A passcode that works for a short time or a single use, issued in place of a password. |
| Workload identity | An identity used by software or a script instead of a person. |