Conditional access combines identity, device, session, and environment signals so policies can adapt to current risk instead of relying on a fixed trust decision.
Conditional access is the practical policy layer where zero trust becomes operational. Instead of making the same decision for every login or every resource, the system considers context signals such as device posture, user risk, session anomalies, network type, geolocation, and application sensitivity. The point is not to collect signals for their own sake. The point is to make better access decisions when the situation is meaningfully different.
This is also where many zero-trust programs become either useful or brittle. Good conditional access uses a few meaningful signals that teams can explain, tune, and support operationally. Weak conditional access depends on noisy inputs, undocumented exceptions, or one “magic” signal that is treated as infallible.
Signals often used in conditional access include:
These signals are not equal. Some are strong identity-adjacent signals. Some are weaker heuristics. Stronger designs treat them accordingly.
flowchart LR
A["Identity verification"] --> G["Policy engine"]
B["Device posture"] --> G
C["User risk"] --> G
D["Session risk"] --> G
E["Network and location"] --> G
F["Application sensitivity"] --> G
G --> H["Allow, deny, step-up, or restrict"]
What to notice:
Organizations often improve conditional access by reducing signal sprawl, not by increasing it. The more signals a policy depends on, the more tuning and fallback logic it needs. A few questions matter:
For example, device management state may be a strong signal for corporate admin access. Geolocation alone may be too weak to deny all access without additional corroboration. Application sensitivity may be more important than raw network type when deciding whether to require step-up authentication.
1conditional_access:
2 resource: source-control-admin
3 base_requirements:
4 - verified_identity
5 - phishing_resistant_mfa
6 decision_rules:
7 - if: device_posture == "unmanaged"
8 then: deny
9 - if: session_risk == "high"
10 then: deny
11 - if: user_risk == "medium"
12 then: step_up
13 - if: network_type == "public" and app_sensitivity == "high"
14 then: step_up
This example works because it separates:
It also shows why “public network” is not automatically equal to “deny.” Context signals become useful when they modify decisions proportionally instead of acting as crude blanket rules.
Some signals are useful but imperfect. Impossible travel, for example, may indicate a compromised session or may reflect:
That does not make the signal useless. It means the right response may be step-up or extra scrutiny rather than automatic hard deny in every case. Stronger programs choose responses that match signal confidence.
One of the most important contextual signals is sometimes ignored: the sensitivity of the thing being accessed. A low-risk internal wiki and a privileged admin console should not necessarily use identical thresholds. Conditional access becomes much more useful when policies distinguish:
Otherwise the organization either overprotects low-risk activity or underprotects high-risk activity.
A company uses geolocation and device posture as its main conditional-access signals. It denies all access from unfamiliar countries, allows all access from managed devices, and uses the same policy for internal wiki access and privileged source-control administration. Is that a strong design?
No. The policy over-trusts device posture, overreacts to one geographic heuristic, and ignores application sensitivity. A stronger model would treat unfamiliar geography as one risk input among several, would not let “managed device” override every other concern, and would apply stricter conditions to privileged or sensitive resources than to ordinary collaboration tools.
Security+ • SC-900 • cloud security and zero-trust tracks • identity operations and risk-based access learning paths
The next lesson explains what happens after the initial decision, when the session risk changes and the system needs to re-evaluate trust instead of assuming the login result remains valid forever.