Summary

The design principle of report-only first, personas over point-policies, and never a static allow but every grant is conditional, is a solid approach. Personas are the part worth dwelling on, because scoping by role rather than by application is what keeps a Microsoft 365 tenant from accumulating forty policies nobody can reason about. To properly understand the decision flow of conditional access, we will use "Field-Sales" as the persona, made up of 900 travelling account executives, and it is a useful test case because its members generate risk detections as a matter of routine. They sign in from airport networks, from countries they have never visited, and from hotel Wi-Fi that shares an egress address with a few thousand strangers. Wire risk into policy carelessly and "Field-Sales" is the group that finds out first. The argument of this article is that the flowchart is really a boolean expression, that each of its three outcomes has a precondition nobody draws, and that the risk conditions inside it are lagging indicators rather than live ones.

The Evaluation Order

Conditional Access reads a policy in a fixed order. Assignments decide whether the policy is in play at all. Conditions decide whether the circumstances match. Controls then apply, grant first and session second. Two of those steps can end the policy's involvement quietly, and quietly is the operative word: a policy that did not apply and a policy that applied and passed look identical from the outside.

Figure 1. The flowchart on the slide is accurate. The two dashed exits are the ones that surprise people.
Figure 1. The flowchart on the slide is accurate. The two dashed exits are the ones that surprise people.

The ANDing inside a single policy is not a footnote. Microsoft documents an explicit warning not to combine sign-in risk and user risk conditions in the same policy, and the reason is mechanical rather than stylistic: a policy carrying both fires only when both are true at once, which is close to never. Two conditions that describe independent problems belong in two policies.

Scoping deserves the same care. A persona-scoped policy covering "Field-Sales" with a regional sub-group excluded for a migration is a policy that does not apply to those users, and there is no failure event to build an alert on. The exclusion outlives the migration roughly every time.

Grant, Step-Up, Block

Three outcomes, and each one depends on something being true before the request ever arrives. In production they have very different failure modes, because step-up is the only one that needs the user to be able to do something.

OutcomeHow it is configuredWhat must already be true
GrantConditions satisfied, grantControls metNothing. This is the path that needs no preparation, which is why a static allow is a design smell.
Step-upRequire authentication strength, or Require risk remediation for user riskAn interactive client, and a registered method. Users who never registered for MFA are blocked and need an administrator.
RemediateSecure password change inside the risk remediation flowPassword writeback for hybrid users. A password change made anywhere else does not satisfy the requirement.
Blockblock in any matching policyNothing, and that is the problem. It is the cheapest control to write and the most expensive to own.

Table 1 - Describes step-up and remediate carry prerequisites. Grant and block do not, which is exactly why they get overused.

The current control for user risk is Require risk remediation, and selecting it changes two other things automatically. Require authentication strength is added as a grant control, and sign-in frequency of every time is applied as a mandatory session control. Passwordless users take a different path: rather than a password change, Microsoft Entra revokes their sessions so they have to reauthenticate. Both routes are self-service, which is the entire point, and both collapse into an administrator ticket if the user has no registered method.

That is the real risk for a group like "Field-Sales". A step-up requirement aimed at 900 people is only self-service for the ones already registered. For anyone else it is a block with extra steps, and it arrives at an airport at the end of a quarter. Registration campaigns are a prerequisite for risk-based policy, not a parallel workstream.

Risk as a Condition

A Conditional Access policy cannot condition on a detection. It conditions on a level, signInRiskLevels or userRiskLevels, set to some combination of low, medium and high. Everything Microsoft Entra ID Protection knows about why a user looks risky is compressed into one of three words before a policy sees it. Most of the confusion in risk-based design comes from designs written as though that compression did not happen.

The second thing to internalise is timing. Some detections are calculated during the authentication and some are calculated afterwards. Real-time detections surface in 5 to 10 minutes. Offline detections take up to 48 hours, because working out whether a sign-in was strange requires knowing what came after it.

Figure 2. Three of the four detections in the slide's own table are offline, so the response lands on the next authentication.
Figure 2. - Describes the three of the four detections that are offline, so the response lands on the next authentication.

The mappings are not wrong as policy, they are wrong about when the policy takes effect, and two of the four rows also name the wrong risk type.

Detection on 

Figure 2

riskEventTypeWhat it actually is…The response lands…
Leaked credentialsleakedCredentialsUser risk, offline, always high. On the next authentication. A cloud password reset does remediate it, with password hash sync for on-premises
Impossible travelmcasImpossibleTravelSign-in risk, offline, needs Defender for Cloud AppsAfter the fact. unlikelyTravel, atypical travel, is the P2 detection people usually mean
Anonymous IP or TORanonymizedIPAddressSign-in risk, real-timeOn this sign-in. The only row of the four that can gate in the moment
Token replay via AiTMattackerinTheMiddleUser risk, not sign-in risk, offlineAfter the session exists, so revocation matters more than blocking

Table 2 - Describes four rows, corrected against the detection reference. Only the third one gates in real time.

Reading a Detection

The two timestamps are the part to look at. Everything else is context.

Figure 3. Describes the source code for a detection.
Figure 3. Describes the source code for a detection.

The session that produced this detection was granted at 01:47 and the detection existed at 02:14. No policy conditioned on sign-in risk could have interrupted it, because there was nothing to condition on at the time. lastUpdatedDateTime moving later still is the other half of the problem: risk levels are revised as more evidence arrives, so a medium at breakfast can be a high by lunchtime.

How the Level Is Assembled

Sign-in risk is scoped to one authentication and is cleared by a successful strong authentication. User risk is cumulative, it aggregates detections over time, and an unremediated offline sign-in risk can roll up into it. Low risk ages out after six months. Medium and high sit there until somebody or something resolves them.

Figure 4. Describes the one-to-one mapping of detection to response is a useful teaching device and not a configurable thing.
Figure 4. Describes the one-to-one mapping of detection to response is a useful teaching device and not a configurable thing.

Volume helps here, which is counterintuitive. Atypical travel ignores VPN ranges and locations that other people in the organisation use regularly, and it holds new accounts in a learning period of 14 days or 10 sign-ins before it starts scoring them. A persona the size of "Field-Sales" therefore trains the model into a fairly tolerant baseline, and the sharp edge is the new hire in week one rather than the veteran in Frankfurt. Tenants without Entra ID P2 see none of this detail: riskEventType comes back as generic and riskLevel as hidden.

Closing the Loop

The Risk loop is composed of Detect, Score, Decide, Remediate. The Remediate step is where it either closes or quietly does not, because riskState has four exits and only one of them involves the attacker losing access.

Figure 5. Three of the four exits are administrative bookkeeping. Only remediation changes what the attacker can do.
Figure 5. Three of the four exits are administrative bookkeeping. Only remediation changes what the attacker can do.

Two of those transitions feed back into the model rather than just the record. Calling confirmCompromised sets the user to high risk and tells ID Protection its judgement was correct, which sharpens later scoring. confirmSafe does the opposite. Plain dismiss clears the state without teaching anything, and the platform does its own version of this: when it concludes a detection was a false positive or was already remediated, it dismisses the risk and sets the detail to AI confirmed sign-in safe. Bulk-dismissing a queue of atypical travel hits from a travelling sales team feels like triage and is closer to sanding the edges off your own detections.

A Deadline Worth Noting

The legacy risk policies configured inside ID Protection retire on 1 October 2026. Anything still running there needs an equivalent user risk and sign-in risk policy built in Conditional Access, validated in report-only mode, and then enabled before the old policies stop. Microsoft's own recommendation is user risk high requiring risk remediation, and sign-in risk medium and high requiring an authentication strength with sign-in frequency every time. Run both in enabledForReportingButNotEnforced against real traffic first. For a persona that lives on the road, a fortnight of report-only data is not enough to see what enabling it will cost.

Endpoints and Permissions

The risk APIs are where automation actually happens, and the least-privileged permission is narrower than most playbooks ask for. The riskyUsers API requires Entra ID P2, and Security Administrator is the least privileged directory role for the write actions.

OperationEndpointLeast-privileged permission
List risk detections

GET

/identityProtection/riskDetections

IdentityRiskEvent.Read.All
List risky users

GET

/identityProtection/riskyUsers

IdentityRiskyUser.Read.All
Confirm a user compromised

POST

/identityProtection/riskyUsers/

confirmCompromised

IdentityRiskyUser.

ReadWrite.All

Dismiss user risk

POST

/identityProtection/riskyUsers/dismiss

IdentityRiskyUser.

ReadWrite.All

Confirm a user safe

POST

/identityProtection/riskyUsers/confirmSafe

IdentityRiskyUser.

ReadWrite.All

Create or update a policy

POST

/identity/conditionalAccess/policies

Policy.ReadWrite.

ConditionalAccess

Test a request against policy

POST

/identity/conditionalAccess/evaluate

Policy.Read.

ConditionalAccess

Table 3 - Describes All five risk calls return quickly and change state immediately. confirmCompromised returns 204 No Content and sets the user to high risk.

Conclusion

If you've made it this far in the article, then your mind hasn't exploded by Conditional Access and its many boolean flows, and its risk conditions. Personas like "Field-Sales" are the right scope, but they will expose every skipped prerequisite, including MFA registration, password writeback, and a report-only window long enough to cover quarter-end activity. A great way to stay on top of these risks is to use detection-to-response mappings to teach the model, configure risk levels, and assume the answer will arrive late.