The strongest Conditional Access control most tenants under-use is “require a compliant or hybrid-joined device.” Multi-factor authentication proves who is signing in; the compliant-device grant proves what they sign in from — a corporate, managed, patched, encrypted endpoint rather than an unmanaged laptop in an internet café. It is the single highest-signal control in a Zero Trust posture because it moves the trust boundary from “a password plus a phone” to “a machine your organisation continuously evaluates.” It is also the control that generates the most self-inflicted outages, because three independent systems — Intune, Entra ID, and Conditional Access — must agree on a device’s state, asynchronously, before anyone is let in, and each one has a default that quietly makes the grant either toothless or a lockout.
This guide builds the full endpoint-gating stack end to end and then teaches you to debug it. You will author an Intune compliance policy (every setting class, the actions-for-noncompliance schedule that is your grace period, and the Defender for Endpoint risk connector), understand exactly how isCompliant flows from Intune onto the Entra device object and how Conditional Access reads it at token time, build the require-compliant and compliant-OR-hybrid grants correctly for a mixed estate, scope them with filters for devices (rules, attributes, the include/exclude trap), split managed desktops from personal phones with a parallel app-protection policy, and stage the whole thing through report-only so a bad grant never reaches production blind. The centrepiece is the troubleshooting playbook for the ticket every endpoint admin gets: “my device is Compliant in Intune but Conditional Access says it isn’t.”
By the end you will treat the compliant-device grant not as a scary switch but as an engineering system with a known state machine, a known set of failure modes, and a known diagnostic for each. You will know why a device that shows green in the Intune portal can still be blocked, why the “no policy assigned = Compliant” tenant default silently disarms your entire estate, why Require compliant on a hybrid-joined-but-not-enrolled fleet blocks all of it, and exactly which Graph query, sign-in log field or registry key confirms each. Knowing which within minutes is the difference between a five-minute fix and a tenant-wide checkout outage during a flash sale.
What problem this solves
Identity-only Conditional Access — MFA plus maybe a risk check — leaves a gaping hole: a valid user with valid credentials on a compromised or unmanaged device sails straight into Microsoft 365. Token theft, adversary-in-the-middle phishing that captures the post-MFA session cookie, a personal Windows machine with no disk encryption and disabled Defender, a contractor’s home PC syncing your entire SharePoint library to an unencrypted disk — none of these are stopped by MFA. They are stopped by requiring the sign-in to come from a device your organisation manages and continuously evaluates for health. That is what the compliant-device grant does, and it is the concrete mechanism behind the Zero Trust maxim “verify explicitly, assume breach.”
What breaks with it, when built carelessly, is worse than the hole it closes. The device-compliance grant is uniquely dangerous among CA controls because the accounts most likely to need emergency access — break-glass admins, automation identities — are the least likely to be signing in from an enrolled, compliant device. Flip Require compliant on “All cloud apps” with no break-glass exclusion and you lock every administrator out of the very portal needed to undo it. Set the “mark noncompliant” schedule to zero days during rollout and you block every device that is briefly remediating. Leave the tenant default at “no policy assigned = Compliant” and unmanaged devices sail through a grant you believe is enforcing. Confuse compliant (needs Intune) with hybrid-joined (does not) and you block an entire fleet of domain-joined PCs that were never enrolled.
Who hits this: every organisation moving from “MFA everywhere” to real device-based Zero Trust — which in 2026 is most of them, pushed by cyber-insurance requirements, regulatory mandates, and the reality that token theft has made “the user proved who they are” insufficient. It bites hardest on mixed estates mid-migration (cloud-managed laptops next to legacy hybrid-joined desktops), on BYOD-heavy organisations (personal phones that will never enrol), and on anyone who treats the compliant grant as a checkbox rather than a three-system state machine. The fix is almost never “loosen the policy” — it is “understand which of the three systems disagrees about the device, and why.”
To frame the whole field before the deep dive, here is the layered model every later section refines — the three systems, what each one owns, and the failure it causes when it is wrong:
| Layer | What it owns | The signal it produces | Failure when misconfigured | Who typically owns it |
|---|---|---|---|---|
| Entra device registration | The device object and its trustType (registered / hybrid / joined) |
The object CA reads; existence + join type | No object → no device grant can ever pass | Identity / endpoint team |
| Intune enrolment + compliance | Evaluating the device against a compliance policy | isCompliant (true/false) stamped onto the Entra object |
Not enrolled, or policy fails → blocked; “no policy = compliant” default → toothless | Endpoint / Intune team |
| Defender for Endpoint | Continuous machine risk scoring | A risk level (Low/Med/High) fed into compliance | Connector not wired → risk rule never evaluates | Security team |
| Conditional Access | The grant decision at sign-in | Allow / block / require, per policy | Wrong grant type, no break-glass exclusion, “All apps” scope → lockout | Identity team |
| The device platform (OS) | Broker/WAM, PRT, certificate that presents the state | The device identity in the token request | Missing PRT, broken WAM/broker → “device not compliant” on a compliant device | OS / endpoint team |
Learning objectives
By the end of this article you can:
- Explain the device-based access model end to end: the three device
trustTypevalues, howisCompliantis produced and stamped, and how Conditional Access reads the device object at token time. - Author a production Intune compliance policy per platform — every settings class (device health, properties, system security, Defender risk), the actions for noncompliance schedule that functions as the grace period, and the two tenant-level traps.
- Wire the Microsoft Defender for Endpoint risk connector into compliance so a high machine-risk score flips a device noncompliant, and reason about the compliance-state-validity ageing that follows.
- Build the require-compliant, hybrid-joined, and compliant-OR-hybrid grants correctly (including the exact Graph
grantControlsshape) and pick the right one for cloud-native, legacy-domain, and mixed estates. - Scope policies with filters for devices — the rule syntax, every usable attribute, the 15 extension attributes, and the include/exclude trap that silently inverts your intent.
- Split managed desktops (compliant grant) from personal mobiles (app-protection grant) with parallel policies, and know that the legacy approved-client-app grant is retired.
- Stage a rollout safely through report-only → What If → sign-in log analysis, driving
reportOnlyFailureto near-zero before enforcing, then expanding rings. - Diagnose “device not compliant” authoritatively: distinguish sync lag, a stale-aged compliance bit, a missing PRT, a broken WAM/broker, a filter that excluded the device, and a wrong grant — each with the exact Graph query, sign-in log field, or client command that confirms it.
Prerequisites & where this fits
You should already understand Conditional Access fundamentals: that a CA policy is an if-then statement (assignments: users + target resources + conditions → access controls: grant/session), that policies are additive and evaluated together, and that a blocked grant is the union of every applicable policy. You should know what Intune enrolment is (the device is MDM-managed by Intune, receiving policy and reporting inventory), the three Entra device join types (Entra registered / hybrid joined / Entra joined), and how to run Microsoft Graph PowerShell (Connect-MgGraph) and read JSON. Familiarity with managed identities, RBAC, and basic Windows/macOS/iOS/Android device concepts helps.
This sits in the Identity & Endpoint track, at the intersection of Conditional Access and Intune. It assumes the CA design fundamentals from Conditional Access at Scale: Personas & Authentication Context and the break-glass hygiene from Entra Break-Glass Emergency Access, Monitoring & Governance — read that one first, because a device grant without a break-glass exclusion is the fastest way to lock yourself out. It pairs tightly with Intune Filters: Assignment Targeting & Ring Deployment (compliance assignment scoping) and Intune MAM: App Protection Without Enrolment (BYOD), which is the other half of this design — the mobile grant that governs personal phones while the compliant grant governs desktops. The Defender risk half connects to Entra ID Protection: Risk-Based Policies, Tuning & Investigation (the user-risk analogue of the device-risk signal used here).
A quick map of who confirms what during an incident, so you call the right person fast:
| Layer | What lives here | Who usually owns it | Failure classes it can cause |
|---|---|---|---|
| Entra device object | trustType, isCompliant, isManaged |
Identity team | Grant blocked (no object / wrong join type / stale bit) |
| Intune compliance | The policy, evaluation, actions schedule | Endpoint / Intune team | Device shows noncompliant; grace whiplash |
| Defender for Endpoint | Machine risk score + connector | Security team | Risk rule never evaluates; high risk blocks unexpectedly |
| Conditional Access | The grant + filter + scope | Identity team | Lockout; toothless grant; filter excluded the device |
| The client OS / broker | PRT, WAM/broker, device certificate | OS / endpoint team | “Not compliant” on a compliant device (missing PRT) |
| Tenant defaults | “No policy = compliant”, validity period | Endpoint team | Silent disarm; whole-fleet ageing to noncompliant |
Core concepts
Five mental models make every later diagnosis obvious.
Three independent pieces must line up, in order. A “managed” device is allowed in only when all three of these are true, and they are produced by three different systems on three different schedules. First, a device registration state exists in Entra ID — the device object carries a trustType: Entra registered (BYO / workplace-joined), Entra hybrid joined (on-prem AD-joined and synced to Entra), or Entra joined (cloud-native, joined directly to Entra). No object, and no device grant can ever pass — there is nothing for CA to read. Second, a compliance state exists — Intune has enrolled the device, evaluated it against a compliance policy, and stamped isCompliant = true/false onto that same Entra device object. Third, the CA grant — Require device to be marked as compliant and/or Require Microsoft Entra hybrid joined device — reads the object at sign-in and decides. The order matters: registration is upstream of compliance, which is upstream of the grant.
Compliant needs Intune; hybrid-joined does not. This is the single most important fact and the number-one cause of “my domain PCs are blocked” tickets. The compliant grant requires the device to be Intune-enrolled and evaluated — Intune is the only thing that writes isCompliant. The hybrid-joined grant only requires the device to be hybrid-joined (present in on-prem AD, synced to Entra with trustType = ServerAd) and does not need Intune at all. If you flip Require compliant on a fleet of hybrid-joined machines that were never enrolled in Intune, every one of them is blocked, because none of them has ever had isCompliant set to true. For a mixed estate mid-migration, the answer is compliant OR hybrid-joined — cloud-managed machines pass on compliance, legacy domain machines on hybrid join, nothing breaks while you migrate.
Compliance evaluation is asynchronous, and CA reads a snapshot. The chain — device checks in to Intune → Intune evaluates the policy → Intune writes isCompliant to the Entra object → CA reads the object at the next sign-in / token request — is not instant at any hop. Compliance runs on the Intune check-in cycle (minutes to a few hours), not the moment a setting changes. CA evaluates the device object as it exists at token time; even after isCompliant flips, an existing token carries the old decision until the session refreshes or the user re-authenticates. Understanding this lag prevents most “why is it still blocked” confusion — the systems are eventually consistent, not immediately consistent.
The compliance bit ages, and stale means noncompliant. A device that stops checking in does not stay “compliant forever.” The Compliance status validity period (a tenant setting, e.g. 30 days) means a device that has not reported in that window has its isCompliant reverted to false on the Entra object — even if the local Intune client still shows green from its last successful evaluation. This is the subtlest production failure: a proxy blocks the Intune check-in endpoints, devices go quiet, the validity window expires, and CA starts blocking machines whose local status looks fine. Nominally compliant and actively checking in are different things, and CA reads the latter.
The device state must be presented in the token request, and that is the OS’s job. For CA to see a device as compliant, the client must attach a device identity to the sign-in — on Windows via the Primary Refresh Token (PRT) and the Web Account Manager (WAM) broker; on macOS via the Microsoft Enterprise SSO plug-in and the device’s registration; on iOS/Android via the Microsoft Authenticator / Company Portal broker. If the browser or app doesn’t use the broker, or the PRT is missing/expired, the token request carries no device state, and CA sees “unknown device” → not compliant → blocked, on a device that is perfectly compliant in Intune. A huge fraction of “device not compliant” tickets are this: the compliance is real, but the presentation of it failed at the client.
The vocabulary in one table
Before the deep sections, pin down every moving part. The glossary at the end repeats these for lookup; this table is the mental model side by side:
| Concept | One-line definition | Where it lives | Why it matters to the grant |
|---|---|---|---|
| Device object | The Entra representation of a device | Entra ID directory | The thing CA reads; no object → no grant |
trustType |
The join type of the device | On the device object | Chooses which grant (compliant vs hybrid) can apply |
isCompliant |
The compliance bit Intune stamps | On the device object | The exact bit the compliant grant evaluates |
| Compliance policy | Pass/fail rules + noncompliance actions | Intune | Produces isCompliant |
| Actions for noncompliance | The schedule of what happens, and when | Intune policy | The “mark noncompliant” delay is the grace period |
| Compliance status validity | How long a state stays valid without check-in | Intune tenant setting | Expiry ages isCompliant to false |
| MDE risk signal | The machine risk score from Defender | Defender ↔ Intune connector | A compliance rule (“at or under Medium”) |
| Require compliant grant | CA control needing isCompliant = true |
CA policy grant | Needs Intune enrolment |
| Require hybrid-joined grant | CA control needing trustType = ServerAd |
CA policy grant | Does not need Intune |
| Filter for devices | Rule over device attributes to scope a policy | CA policy assignment | Includes/excludes by device, not user |
| Extension attribute | One of 15 writable tags on the device object | Device object (via Graph) | The tagging system filters key off |
| PRT | Primary Refresh Token proving device state | Windows client (WAM) | Missing → device state not presented → blocked |
| Report-only | A policy that evaluates but doesn’t enforce | CA policy state |
The safe staging mode before enforcement |
The device-based access model in depth
Everything downstream depends on getting the object model right, so start here. The Entra device object is the anchor; it is created when a device is registered, and it carries the two fields the grant cares about — trustType (how it joined) and isCompliant (whether Intune says it passes). A device can be registered without being enrolled (an object exists, but no compliance signal), enrolled without being compliant (Intune evaluates it and finds it failing), or every combination. The grant reads the object, so the object’s state — not the local client’s belief about itself — is ground truth for Conditional Access.
The three join types and what each can satisfy
trustType is the field that decides which device grant is even applicable to a machine. There is no compliant-vs-hybrid choice at the CA layer that overrides the physics of registration — a device that only ever workplace-joined cannot satisfy the hybrid grant, full stop.
Join type (trustType) |
Graph value | How it’s created | Typical device | Can satisfy compliant? | Can satisfy hybrid? |
|---|---|---|---|---|---|
| Entra registered (Workplace) | Workplace |
User adds a work account to a personal device (BYOD) | Personal Windows/macOS/mobile | Only if also Intune-enrolled | No |
| Entra hybrid joined | ServerAd |
On-prem AD-joined + Entra Connect device sync + auto-registration | Legacy corporate domain PC | Only if also Intune-enrolled (co-managed) | Yes |
| Entra joined | AzureAd |
Cloud-native join (Autopilot / Out-of-box / bulk) | Modern cloud-managed corporate PC | Yes (typically Intune-enrolled) | No |
Two consequences fall straight out of this table. First, the hybrid grant is only ever satisfiable by hybrid-joined (ServerAd) devices — it is the compatibility bridge for legacy estates, not a general control. Second, an Entra registered (BYOD) device can satisfy the compliant grant, but only if the user also enrols it in Intune — which most BYOD users will refuse, which is exactly why BYOD belongs on the app-protection path, not the compliant path. For a cloud-native fleet, every device is AzureAd and Intune-enrolled, and the plain Require compliant grant is correct.
How isCompliant is produced and where it lives
isCompliant is written by exactly one system — Intune — and read by exactly one system for gating purposes — Conditional Access. It is a boolean on the Entra device object, and its provenance is the Intune compliance evaluation. Confirm it directly with Microsoft Graph rather than trusting any UI, because the whole point of the model is that the object is authoritative:
Connect-MgGraph -Scopes "Device.Read.All"
# The exact fields the compliant/hybrid grants evaluate
Get-MgDevice -Filter "displayName eq 'KV-LT-0421'" |
Select-Object DisplayName, DeviceId, TrustType, IsCompliant, IsManaged, `
OperatingSystem, OperatingSystemVersion, ApproximateLastSignInDateTime
TrustType is the join type (Workplace = Entra registered, AzureAd = Entra joined, ServerAd = hybrid joined); IsCompliant is the exact bit the compliant grant evaluates; IsManaged indicates Intune (or another MDM) manages it. If IsCompliant is empty/false but Intune’s device blade shows the device compliant, you are in one of two states: sync lag (the write hasn’t propagated yet) or a stale-aged bit (the validity window expired). The fields, what produces each, and what a wrong value means:
| Device-object field | Produced by | Correct value for “managed corporate PC” | What a wrong value means |
|---|---|---|---|
trustType |
Registration / join process | AzureAd (cloud) or ServerAd (hybrid) |
Workplace → BYOD; hybrid grant won’t apply |
isCompliant |
Intune compliance evaluation | true |
Blocked by compliant grant; check sync/ageing |
isManaged |
The MDM taking management | true (Intune) |
Not enrolled → isCompliant never set |
operatingSystem |
Registration | Windows / macOS / iOS / Android |
Filter platform mismatch |
deviceOwnership |
Enrolment classification | Company |
Personal → your corporate-only filter excludes it |
approximateLastSignInDateTime |
Directory activity | recent | Stale → likely aged out of compliance |
The end-to-end token-time decision
When a user opens Outlook on the web from a managed laptop, the sequence is: the browser (via WAM/the broker) attaches the device’s PRT to the token request → Entra reads the device object referenced by that PRT → Conditional Access evaluates every applicable policy against trustType / isCompliant (plus user, app, platform, filter) → the grant is satisfied or blocked → a token is (or isn’t) issued. The device state that CA evaluates is a snapshot from the object at that instant; nothing about the device’s live local state enters the decision except through the object. This is why “I just fixed BitLocker” doesn’t immediately unblock you — the fix has to reach the object (via an Intune check-in) before a new sign-in can read it.
Authoring the Intune compliance policy
A compliance policy is two things stapled together: a set of pass/fail rules (the device is compliant iff every rule passes) and an actions-for-noncompliance schedule (what happens, and when, once a rule fails). Build one per platform at Intune admin center → Devices → Compliance → Create policy, because the settings differ per OS and a single “all platforms” policy does not exist. The rule set is where you encode “healthy enough to be trusted”; the actions schedule is where you encode “humane enough not to flood the help desk.”
The settings classes (Windows baseline)
Windows compliance settings group into a handful of classes. Here is a sane production baseline with the choices and the gotchas — you do not need every setting, but you should decide on each class:
| Settings class | Example rules | Sane baseline value | Gotcha |
|---|---|---|---|
| Device Health | Require BitLocker; Require Secure Boot; Require Code Integrity | All on | BitLocker rule needs the device to actually report the state; new devices lag |
| Device Properties | Minimum / maximum OS version; valid OS builds | A supported Windows build floor | A too-high floor instantly marks not-yet-updated devices noncompliant |
| Configuration Manager Compliance (co-managed) | Require device compliance from ConfigMgr | On only if co-managed | Only relevant with the ConfigMgr workload |
| System Security | Require password/PIN; storage encryption; Firewall; TPM; Defender Antimalware + real-time protection; minimum antimalware version | Password + encryption + firewall + Defender RTP | Antimalware version rules churn as signatures update |
| Microsoft Defender for Endpoint | Require the device at or under a machine risk score | Medium | Only evaluates once the MDE-Intune connector is enabled; otherwise silently ignored |
| Custom Compliance (scripted) | A PowerShell discovery script + JSON rule | As needed | The script must return the exact keys the JSON expects |
Two rules carry outsized blast radius. The minimum OS version rule is a fleet-wide time bomb if set aggressively: raise the floor to a build your whole estate hasn’t reached yet and you mark everything below it noncompliant the moment the policy applies — pin the floor to your lowest supported deployed build, not the latest. The Defender risk rule does nothing until the connector is enabled (next section); until then it is a no-op that gives false confidence.
Actions for noncompliance — the schedule that is your grace period
Every policy has an Actions for noncompliance tab, and this is what separates a humane rollout from a help-desk flood. Each action has a schedule (how many days after the device is found noncompliant the action fires). The critical insight: there is no separate “grace period” setting — the “Mark device noncompliant” schedule is the grace period, because it controls when isCompliant actually flips to false and CA starts blocking.
| Action | When (schedule) | Purpose | Rollout setting | Steady-state setting |
|---|---|---|---|---|
| Mark device noncompliant | 0 days (immediate) or after N days | Controls when isCompliant flips false → this is the grace period |
3 days | 1 day (or 0 for high-security) |
| Send email to end user | 0 / 1 / 3 days | Warn before enforcement bites | 0 and 2 days | 0 and 1 day |
| Send push notification | 0 / 1 days | Same, on mobile | 0 days | 0 days |
| Add device to retire list | Late (e.g. 30 days) | Last-resort for abandoned devices | Optional | 30 days |
| Remotely lock the device | Late | Recover a lost/abandoned managed device | Off during rollout | Optional |
Set Mark device noncompliant to 3 days during rollout: a freshly enrolled or briefly-failing device gets three days (and warning emails) before isCompliant flips and CA blocks it. Drop it to 1 day or 0 days (immediate) only once you are confident in the estate and want tighter enforcement. The email/push actions should fire before the mark-noncompliant action so users know why they’re about to be blocked. A subtle but important behaviour: the schedule is measured from when the device is found noncompliant, so a device that dips in and out of compliance can reset its clock — which is usually the humane outcome.
The two tenant-level traps
Two tenant-wide settings under Compliance → Compliance policy settings override everything and are the most common silent misconfigurations:
| Tenant setting | Default | The trap | Correct value (and when to set it) |
|---|---|---|---|
| Mark devices with no compliance policy assigned as | Compliant | Every unmanaged / unevaluated device is treated as compliant → your CA grant is silently toothless | Not compliant — but only after real policies are assigned and grace periods are live |
| Compliance status validity period (days) | 30 | A device that stops checking in ages to noncompliant; too short → transient outages, too long → stale devices trusted | 30 (tune to your check-in reliability) |
The first setting is the classic “the grant does nothing” bug. Left at Compliant, a personal laptop with no Intune enrolment has no policy assigned, is therefore treated as compliant by default, and passes your Require compliant grant — the exact thing you built the grant to stop. You must set it to Not compliant — but flip it only after your real policies are assigned and grace periods are in place, or you will instantly mark every not-yet-evaluated device as failing and cause a self-inflicted outage. The second setting is the ageing mechanism: set it too short and reliable devices with brief check-in gaps get blocked; too long and a device that’s been offline (or compromised and quarantined from check-in) is still trusted.
Assign the policy to a device group or a user group (Intune supports both) — but start with a pilot ring (KV-Pilot-Windows), never All Devices. Assignment scoping is where filters (covered later) and ring deployment intersect; see Intune Filters: Assignment Targeting & Ring Deployment for the full targeting model.
Per-OS settings differences
The settings classes differ meaningfully per platform, and assuming a Windows setting exists elsewhere is a common trip-up. The high-value differences:
| Setting area | Windows | macOS | iOS/iPadOS | Android Enterprise |
|---|---|---|---|---|
| Disk encryption | BitLocker | FileVault | Data protection (enforced by passcode) | Encryption of data storage |
| OS version floor | Build number | Version number | Version number | Version number / security patch level |
| Antimalware | Defender Antimalware + RTP | (limited; system integrity) | N/A (sandboxed) | Google Play Protect / SafetyNet-Play Integrity |
| Jailbreak / root detection | N/A | N/A | Block jailbroken | Block rooted / Play Integrity |
| Defender risk (MDE) | Machine risk score | Machine risk score | Mobile risk (MDE for iOS) | Mobile risk (MDE for Android) |
| Password / PIN | Required, complexity | Required, complexity | Passcode, length | Password, complexity |
| Firewall | Required | Required | N/A | N/A |
The device-health integrity checks are the platform-specific heart of compliance: jailbreak/root detection on mobile (via the platform attestation — Apple’s device integrity, Google’s Play Integrity) is the mobile analogue of Secure Boot / Code Integrity on Windows. Build one policy per platform, assign each to its own pilot group, and expect the rules to differ even where the intent (“the device is healthy”) is identical.
The Defender for Endpoint risk signal
The static compliance rules above are a point-in-time check: is BitLocker on, is the OS current. The Microsoft Defender for Endpoint (MDE) integration adds a continuous signal — a machine risk score (Clear / Low / Medium / High) that MDE computes from active detections, and that Intune consumes as a compliance rule: Require the device to be at or under a machine risk score of X. A device that MDE scores above that threshold is marked noncompliant, and — through the chain you already understand — Conditional Access blocks it. This turns “the device was healthy this morning” into “the device is healthy right now, and not actively compromised,” which is the difference between a compliance checkbox and a real security control.
Wiring the connector
The risk rule is a no-op until the MDE ↔ Intune connector is enabled and device-compliance is switched on within it. The setup, in order:
| Step | Where | What it does | Common miss |
|---|---|---|---|
| 1. Enable the connection | Intune → Endpoint security → Microsoft Defender for Endpoint | Establishes the Intune↔MDE trust | — |
| 2. Turn on Connect Windows/macOS/iOS/Android devices to MDE | Same blade, per platform | Lets MDE onboard those devices | Forgetting a platform → risk never scored there |
| 3. Enable Allow MDE to enforce compliance / device-compliance toggle | Same blade | MDE actually feeds risk into compliance | Left off → the risk rule silently never evaluates |
| 4. Add the machine risk score rule to the compliance policy | Compliance policy → Defender for Endpoint | The rule that reads the risk | Set to Clear accidentally → any detection blocks |
| 5. Onboard devices to MDE | Via Intune onboarding config / EDR policy | Devices actually report risk | Onboarding blob not deployed → no telemetry |
Once wired, the flow is: MDE detects something and raises the machine risk → MDE pushes the risk to Intune → Intune re-evaluates the compliance policy → if risk exceeds the threshold, isCompliant flips false → the Entra object updates → CA blocks at next sign-in. Choosing the threshold is a security-vs-availability trade-off:
| Risk-score threshold (“at or under”) | What it blocks | Availability impact | When to use |
|---|---|---|---|
| Clear | Any device with any detection | High — a single low-severity alert blocks | High-security enclaves only |
| Low | Devices at Medium or High risk | Moderate | Sensitive workloads |
| Medium | Devices at High risk only | Low — only genuinely risky devices blocked | Sensible default for most estates |
| High | Only the worst (effectively “block only critical”) | Minimal | Very availability-sensitive; weak control |
Medium (“block High-risk devices”) is the pragmatic default: it blocks devices MDE considers actively dangerous while tolerating the low-severity noise that would otherwise generate lockout tickets for benign detections. Note the ageing interaction: a device whose risk drops back to Clear does not instantly regain access — MDE must push the lowered risk, Intune must re-evaluate, and the object must update, so remediation-to-access has the same lag as any compliance change.
Building the require-compliant Conditional Access policy
With compliance producing isCompliant, the CA policy is where you consume it. Create it at Entra admin center → Protection → Conditional Access → New policy, and — this is non-negotiable — create it in Report-only first (see the staging section). The assignments and grant matter enormously; the two most dangerous mistakes both live here.
The grant choices
The device grant is one or two controls plus a “require one / require all” operator. Choosing the wrong combination is the number-one lockout cause:
| Grant configuration | Passes when… | Right for | Blast radius if wrong |
|---|---|---|---|
| Require device to be marked as compliant | isCompliant = true (Intune) |
Cloud-native, all-Intune estates | Blocks every non-enrolled device (incl. hybrid-only) |
| Require Microsoft Entra hybrid joined device | trustType = ServerAd |
Legacy pure-hybrid estates | Blocks every cloud-native / BYOD device |
| Both, Require one of the selected controls (OR) | Either compliant OR hybrid | Mixed estates mid-migration | Safest for heterogeneous fleets |
| Both, Require all of the selected controls (AND) | Compliant and hybrid | Devices you want to be both | Blocks cloud-native (not hybrid) and hybrid-not-enrolled |
For a heterogeneous estate mid-migration, compliant OR hybrid-joined with Require one of the selected controls is the pragmatic grant: cloud-managed machines pass on compliance, legacy domain machines pass on hybrid join, nothing breaks while you migrate. Do not pick Require all across both unless you genuinely want devices to satisfy each simultaneously — that combination blocks a cloud-native (AzureAd) laptop because it is not hybrid, and blocks a hybrid PC that was never Intune-enrolled because it is not compliant. Almost everyone who selects “all” meant “one of.”
The assignments — where lockouts are born
The grant is only half the policy; the assignments decide who and what it applies to, and two assignment choices are where tenant-wide outages come from:
| Assignment | Safe day-one value | Dangerous value | Why |
|---|---|---|---|
| Users — include | Pilot group (KV-Pilot-Windows) |
All users | A bad grant on all users is a tenant outage |
| Users — exclude | Break-glass accounts + service/automation identities | (nothing excluded) | Break-glass signs in from unmanaged devices; no exclusion = admin lockout |
| Target resources | Office 365 | All cloud apps | “All apps” sweeps in the admin portals and registration endpoints you need to fix the policy |
| Conditions → Device platforms | The platforms you’ve piloted (e.g. Windows) | All / none | Mis-scoping platforms blocks OSes you haven’t prepared |
| Conditions → Client apps | As needed | (default) | Legacy-auth clients can’t present device state → hard-blocked |
The two rules that prevent the worst outages: always exclude break-glass (a device-compliance grant is especially lethal to break-glass because the recovery account will almost never be on a compliant device — verify the exclusion on the new policy every single time), and scope to Office 365, not All cloud apps, on day one — because “All cloud apps” includes the Microsoft admin portals and the device-registration endpoints, so a misconfigured grant on “All apps” can lock you out of the very tools needed to undo it. See Entra Break-Glass Emergency Access, Monitoring & Governance for the full break-glass hygiene this depends on.
The policy as Graph
The equivalent shape via Graph (POST /identity/conditionalAccess/policies) — note it ships as report-only by design:
{
"displayName": "CA-Require-Compliant-O365-Pilot",
"state": "enabledForReportingButNotEnforced",
"conditions": {
"applications": { "includeApplications": ["Office365"] },
"users": {
"includeGroups": ["<pilot-group-id>"],
"excludeUsers": ["<breakglass-1-id>", "<breakglass-2-id>"],
"excludeGroups": ["<automation-identities-group-id>"]
},
"platforms": {
"includePlatforms": ["windows"]
}
},
"grantControls": {
"operator": "OR",
"builtInControls": ["compliantDevice", "domainJoinedDevice"]
}
}
The API names are historical and worth memorising because they don’t match the portal labels: compliantDevice is the marked-compliant grant; domainJoinedDevice is the hybrid-joined grant (not “domain-joined” in the on-prem sense). operator: "OR" is Require one of the selected controls; "AND" is Require all. The state values map as follows — this is the field you flip to go live:
Graph state value |
Portal label | Behaviour |
|---|---|---|
enabledForReportingButNotEnforced |
Report-only | Evaluates every sign-in, records the would-be result, enforces nothing |
enabled |
On | Fully enforcing |
disabled |
Off | Not evaluated at all |
Create the policy via Graph PowerShell so it is repeatable and reviewable as code:
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
$params = @{
displayName = "CA-Require-Compliant-O365-Pilot"
state = "enabledForReportingButNotEnforced" # report-only
conditions = @{
applications = @{ includeApplications = @("Office365") }
users = @{
includeGroups = @("<pilot-group-id>")
excludeUsers = @("<breakglass-1-id>", "<breakglass-2-id>")
}
platforms = @{ includePlatforms = @("windows") }
}
grantControls = @{
operator = "OR"
builtInControls = @("compliantDevice", "domainJoinedDevice")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
Filters for devices: scoping by device attributes
A filter for devices matches (or excludes) on properties of the device object rather than the user — ownership, OS, model, join type, manufacturer, or one of 15 extension attributes. It is the scalpel that lets you say “compliance for corporate Windows only” or “exclude this kiosk fleet” without authoring a dozen policies. The filter lives in the CA policy’s assignments (Conditions → Filter for devices) and is a rule expression over device attributes, plus an include/exclude mode.
The rule syntax and attributes
The filter is configured with three fields — Configure (Yes/No), Mode (Include/Exclude), and Rule (the expression):
Filter for devices
Configure : Yes
Mode : Include (or Exclude)
Rule : device.trustType -eq "ServerAD" -and device.isCompliant -eq True
The usable device attributes (combine with -and / -or, group with parentheses) — this is the vocabulary of every filter you’ll write:
| Attribute | Example value | Operators | Use for |
|---|---|---|---|
device.deviceOwnership |
"Company" / "Personal" |
-eq, -ne |
Corporate-only vs BYOD scoping |
device.operatingSystem |
"Windows" / "macOS" |
-eq, -ne, -startsWith |
Per-OS policy without the platform condition |
device.trustType |
"ServerAD" / "AzureAD" / "Workplace" |
-eq, -ne |
Hybrid-only / cloud-only scoping |
device.isCompliant |
True / False |
-eq, -ne |
Compliance-aware filters |
device.model |
"Surface Pro 9" |
-eq, -startsWith, -contains |
Model-based scoping |
device.manufacturer |
"Microsoft Corporation" |
-eq, -contains |
Vendor-based scoping |
device.extensionAttribute1..15 |
"kiosk" |
-eq, -ne, -startsWith, -contains |
Your own tagging system |
device.deviceId |
a GUID | -eq, -in |
Pinning specific devices |
device.displayName |
"KV-KIOSK-07" |
-eq, -startsWith, -contains |
Name-pattern scoping |
device.isRooted |
True / False |
-eq |
Excluding jailbroken/rooted |
Common building blocks, ready to paste:
| Need | Rule |
|---|---|
| Corporate-owned only | device.deviceOwnership -eq "Company" |
| Specific OS | device.operatingSystem -eq "Windows" |
| Hybrid-joined only | device.trustType -eq "ServerAD" |
| Cloud-joined only | device.trustType -eq "AzureAD" |
| Tag a fleet for exclusion | device.extensionAttribute1 -eq "kiosk" |
| Model-based | device.model -startsWith "Surface" |
| Corporate Windows that’s compliant | device.deviceOwnership -eq "Company" -and device.operatingSystem -eq "Windows" -and device.isCompliant -eq True |
The include/exclude trap
This is the filter mistake that silently inverts your intent, so internalise it. The filter Mode interacts with the grant in a way that is not symmetric, and the interaction confuses even experienced admins:
| Mode | Meaning | Combined with a block grant | Combined with a require-compliant grant |
|---|---|---|---|
| Include | Policy applies to devices matching the rule | Blocks the matched devices | Requires compliance only for matched devices |
| Exclude | Policy applies to devices NOT matching the rule | Blocks everything except matched | Requires compliance for everything except matched (matched devices are exempt) |
The trap: Include and Exclude are about which devices the policy applies to, not “allow” vs “deny.” An Exclude filter of device.extensionAttribute1 -eq "kiosk" on a require-compliant policy means “apply this compliance requirement to every device except kiosks” — i.e. kiosks are exempt from needing compliance. That is usually what you want (carve kiosks out without weakening the grant for anyone else). But people routinely write Include ... -eq "kiosk" thinking it excludes kiosks, and instead they’ve made the policy apply only to kiosks — leaving every other device ungated. Always read the mode as “the policy applies to devices where the rule is [true for Include / false for Exclude],” and validate with What If before enforcing.
Extension attributes — powerful and over-claimed
The 15 device extension attributes (extensionAttribute1…15) are the most powerful and most misunderstood part of filters. They are a tagging system you own on the device object, and they are written via Microsoft Graph on the device object — not the AD user’s msDS-cloudExtensionAttribute fields, not the on-prem AD computer object, not the Intune device record. This confusion sends people editing the wrong object for hours. Set one via Graph so a filter can key off it:
Connect-MgGraph -Scopes "Device.ReadWrite.All"
$deviceObjectId = (Get-MgDevice -Filter "displayName eq 'KV-KIOSK-07'").Id
Update-MgDevice -DeviceId $deviceObjectId -BodyParameter @{
extensionAttributes = @{ extensionAttribute1 = "kiosk" }
}
# Verify the tag landed on the right object
Get-MgDevice -DeviceId $deviceObjectId |
Select-Object DisplayName, @{n='ext1';e={ $_.ExtensionAttributes.ExtensionAttribute1 }}
Where extension attributes come from and don’t, so you tag the right thing:
| Attribute source | Is it the CA filter attribute? | Written via | Notes |
|---|---|---|---|
Entra device extensionAttributes |
Yes | Graph on the device object | The one filters use |
Entra user onPremisesExtensionAttributes |
No | Sync from on-prem AD user | User object, not device |
| On-prem AD computer attributes | No | AD tooling | Not synced into the CA filter attribute |
| Intune device category / notes | No | Intune | Different store; not a CA filter attribute |
Two practical patterns close the section. An Exclude filter of device.extensionAttribute1 -eq "kiosk" carves shared/kiosk devices out of the require-compliant policy without weakening it for anyone else. An Include filter of device.deviceOwnership -eq "Company" keeps the grant on corporate hardware only, leaving BYOD to the app-protection path. Treat the 15 attributes as documented, owned tags — write down which attribute means what, because nothing in the platform tells you extensionAttribute3 is your “PCI-scope” flag.
Device-based vs app-based: managed desktops and personal mobiles
The require-compliant grant is right for managed endpoints and wrong for personal phones. Demanding Intune compliance on a BYOD phone forces full enrolment — which gives your organisation management authority over a personal device and which users will (rightly) refuse, driving them to shadow-IT workarounds. The clean architecture is two parallel policies: the compliant grant governs desktops (device-based), and a separate app-protection grant governs mobiles (app-based, no enrolment required).
The two-policy split
| Dimension | Desktop policy (device-based) | Mobile policy (app-based) |
|---|---|---|
| Platforms | Windows, macOS | iOS, Android |
| Client apps condition | (default) | Mobile apps and desktop clients |
| Grant | Require compliant or hybrid-joined | Require app protection policy (Intune MAM) |
| Enrolment required? | Yes (compliant needs Intune) | No — MAM protects the app, not the device |
| Protects | The whole device | Corporate data inside approved apps |
| User friction | Managed corporate hardware | Zero enrolment; user keeps a personal device |
The app-protection policy (Intune MAM) approach protects corporate data within managed apps (Outlook, Teams, the mobile Office apps) — enforcing PIN, encryption, copy-paste restrictions, and selective wipe of corporate data — without the organisation managing the whole device. It is the correct control for BYOD mobiles, and it is a full topic in its own right; see Intune MAM: App Protection Without Enrolment (BYOD) for authoring the App Protection Policies the Require app protection policy grant depends on. Without an assigned APP, the grant has nothing to require and blocks the sign-in.
The retired approved-client-app grant
A critical 2026 fact that breaks old designs: the legacy Require approved client app grant has been retired — it stopped functioning in early March 2026. Any policy still authored against it no longer enforces. New (and migrated) mobile policies must use Require app protection policy instead. The migration and the distinction:
| Grant | Status (2026) | What it required | Replacement |
|---|---|---|---|
| Require approved client app | Retired (stopped working early March 2026) | The app is on Microsoft’s approved-client list | Require app protection policy |
| Require app protection policy | Current | The app has an Intune App Protection Policy applied | (this is the replacement) |
If you inherit a tenant with mobile CA policies, audit for the retired grant first — a policy that looks like it’s protecting mobile may be silently doing nothing. Convert each to Require app protection policy and confirm the App Protection Policies are assigned to the mobile user population.
Session control as a third option
For unmanaged-but-low-risk web access, Conditional Access App Control (session control via Defender for Cloud Apps) is a third grant — a monitored or restricted browser session rather than an outright block. It lets an unmanaged device reach a web app but strips or watches risky actions (block download, block copy, monitor only), which is the right answer when “block entirely” is too blunt for a given app and audience. See Defender for Cloud Apps: Shadow IT & Session Policies for the session-control mechanics. The three grant families, side by side:
| Grant family | Device requirement | User experience | Best for |
|---|---|---|---|
| Device-based (Require compliant / hybrid) | Managed + compliant device | Transparent on managed devices | Corporate desktops/laptops |
| App-based (Require app protection policy) | App is MAM-protected (no device enrolment) | Slight friction inside managed apps | BYOD mobiles |
| Session-based (Use CA App Control) | None (unmanaged allowed) | Restricted/monitored browser session | Unmanaged web access to specific apps |
Per-OS specifics: how each platform presents device state
The “device not compliant” error is disproportionately an OS-side problem — the compliance is real in Intune and on the object, but the client failed to present the device state in the token request. Each platform has a different broker and a different failure mode, and knowing your platform’s mechanism is half the diagnosis.
Windows — PRT and WAM
On Windows, the Primary Refresh Token (PRT) is the artefact that proves device identity and state to Entra; it is issued when the device registers/joins and is presented by the Web Account Manager (WAM) broker during token requests. Browsers must use WAM (Edge natively; Chrome via the Windows Accounts extension; Firefox via configuration) or they present no device state and CA sees an unknown device → not compliant. Confirm the PRT on the device:
:: Run as the signed-in user (not elevated) — shows the device SSO state
dsregcmd /status
:: Key lines to read:
:: AzureAdJoined : YES (or DomainJoined : YES for hybrid)
:: AzureAdPrt : YES <- the PRT must be present
:: AzureAdPrtAuthority / AzureAdPrtUpdateTime
AzureAdPrt : YES is the field that matters: if it is NO, the device cannot present its state and CA will block it regardless of Intune compliance. Common Windows presentation failures and fixes:
| Symptom | Cause | Confirm | Fix |
|---|---|---|---|
| Compliant device blocked in Chrome, works in Edge | Chrome not using WAM | dsregcmd /status shows PRT=YES |
Install Windows Accounts extension / enable browser SSO |
PRT absent (AzureAdPrt : NO) |
Registration incomplete, expired, or clock skew | dsregcmd /status |
Re-trigger registration; fix time sync; re-sign-in |
| Hybrid device not seen as hybrid | Device sync not completed via Entra Connect | Device object missing / trustType wrong |
Confirm Connect device sync; wait for object |
| Works, then blocks after a while | PRT expired and didn’t renew | AzureAdPrtUpdateTime old |
Ensure network to Entra; re-authenticate |
macOS — the Enterprise SSO plug-in
On macOS, device state is presented via the Microsoft Enterprise SSO plug-in (delivered through an Intune configuration profile) plus the device’s registration. Without the SSO plug-in profile, Safari/Chrome sign-ins don’t carry device state and compliant Macs get blocked. The Mac-specific chain: enrol in Intune → deploy the Enterprise SSO extension profile → the device registers → the plug-in presents state on token requests. See Intune macOS Management: Platform SSO, FileVault & DDM for deploying the SSO extension correctly.
iOS / Android — the broker apps
On mobile, the broker is Microsoft Authenticator (iOS) or the Company Portal / Authenticator (Android); apps and the system browser present device state through it. On these platforms the compliant grant requires enrolment (so it’s a corporate-mobile control), while BYOD mobiles use the app-protection grant instead. The per-OS presentation mechanism, summarised:
| OS | Device-state broker | Delivered by | “Not presented” failure looks like |
|---|---|---|---|
| Windows | WAM + PRT | Join/registration | Blocked in non-WAM browser; PRT=NO |
| macOS | Enterprise SSO plug-in | Intune config profile | Blocked until SSO extension deployed |
| iOS/iPadOS | Microsoft Authenticator broker | Authenticator app | Blocked if app not brokering / not enrolled (for compliant grant) |
| Android | Company Portal / Authenticator | Company Portal app | Blocked if Company Portal absent (for compliant grant) |
Staging the rollout: report-only, What If, sign-in logs
Never flip a device grant straight to On. The device-compliance grant has the largest surprise blast radius of any CA control because its correctness depends on three asynchronous systems, so the staging discipline is not optional. The safe sequence has three instruments.
Report-only
Set the policy state to Report-only (enabledForReportingButNotEnforced): it evaluates every sign-in and records what it would have done, enforcing nothing. Leave it for at least a full business cycle — a week — so daily, weekly, and edge-case sign-ins all get sampled. Report-only is the single most important safety net; it turns “we hope this works” into “we have data on exactly who breaks.”
What If
Use Conditional Access → What If to simulate a specific user + app + device-state + platform combination and see which policies apply. Run it for every persona before enforcing:
| Persona to simulate | Expected result | If it’s wrong |
|---|---|---|
| Compliant pilot user, Windows, Office 365 | Grant satisfied (passes) | Check the object’s isCompliant; check filter |
| Noncompliant device (BitLocker off) | Blocked | If it passes → “no policy = compliant” trap |
| Break-glass account, unmanaged device | Not applied | If applied → fix the exclusion immediately |
| Hybrid-only legacy PC (not Intune) | Passes via the hybrid control | If blocked → you’re using compliant-only, not OR |
| Kiosk device (tagged) | Not applied (excluded by filter) | If applied → filter mode is inverted |
| BYOD mobile | Governed by the mobile policy, not this one | If this one applies → platform scope wrong |
What If evaluates the policy logic against stated inputs; it does not verify the device’s actual current state, so pair it with real sign-ins from real devices.
Sign-in log analysis
This is where you find surprises before users do. In Entra → Monitoring → Sign-in logs, the Report-only tab shows, per sign-in, whether each report-only policy would grant, block, or require. The results you care about:
| Report-only result | Meaning | Action |
|---|---|---|
reportOnlySuccess |
Would have passed | Fine |
reportOnlyFailure |
Would have blocked this sign-in | Your list of who breaks — remediate before enforcing |
reportOnlyInterrupted |
Would have required interactive action (e.g. re-auth) | Investigate; usually acceptable |
reportOnlyNotApplied |
Policy didn’t apply (scope/exclusion) | Confirm this is intended (e.g. break-glass) |
If sign-ins are exported to Log Analytics, query them directly to quantify the impact and get the exact user/device list:
SigninLogs
| where TimeGenerated > ago(7d)
| mv-expand policy = todynamic(ConditionalAccessPolicies)
| where policy.displayName == "CA-Require-Compliant-O365-Pilot"
| extend reportOnlyResult = tostring(policy.result)
| where reportOnlyResult in ("reportOnlyFailure", "reportOnlyInterrupted")
| summarize impacted = dcount(UserPrincipalName),
sample = make_set(UserPrincipalName, 20)
by reportOnlyResult, tostring(DeviceDetail.operatingSystem),
tostring(DeviceDetail.isCompliant)
| order by impacted desc
reportOnlyFailure is your enforcement risk: the list of users/devices that break the moment you switch the policy on. Drive it to effectively zero — enrol/remediate the devices, fix the scope, or add a filter exclusion — then set state to enabled. Expand the ring (pilot → department → all) one step at a time, re-checking the report-only data at each step. The rollout as a staged sequence:
| Stage | state |
Scope | Gate to advance |
|---|---|---|---|
| 1. Report-only | enabledForReportingButNotEnforced |
Pilot group | A week of data collected |
| 2. What If sweep | (unchanged) | All personas | Every persona resolves correctly |
| 3. Drive failures to zero | (unchanged) | Pilot | reportOnlyFailure ≈ 0 |
| 4. Enforce pilot | enabled |
Pilot group only | Pilot stable for a few days |
| 5. Expand rings | enabled |
Dept → all | Re-check report-only at each ring |
Architecture at a glance
Picture the system as a left-to-right pipeline across three planes, because that layout mirrors exactly how a sign-in flows and where each failure bites. On the far left sits the device plane: a managed endpoint (Windows/macOS/iOS/Android) that has (a) an Entra device object with a trustType, and (b) an Intune enrolment. Intune runs the compliance policy against the device on each check-in — evaluating device health (BitLocker/Secure Boot), OS-version floor, system security, and the Defender for Endpoint machine-risk signal fed in from the MDE connector — and stamps the result as isCompliant back onto the Entra device object. That write is the arrow crossing from the device plane into the directory.
The centre is the directory plane — the Entra device object holding the two fields that decide everything: trustType (registered / hybrid / joined) and isCompliant. This object is the single source of truth; nothing about the device’s live local state reaches the decision except through it, and the Compliance status validity period governs how long a value stays trusted before ageing to false. When the user opens Office 365, the client’s broker (WAM+PRT on Windows, the Enterprise SSO plug-in on macOS, Authenticator/Company Portal on mobile) attaches the device identity to the token request — the arrow from the device plane into the right-hand plane.
The right is the policy plane — Conditional Access reading the device object at token time. Two grant paths run in parallel: the device-based path (Require compliant OR hybrid-joined, scoped by a filter for devices to corporate hardware, excluding kiosks by extension attribute) governs desktops, while the app-based path (Require app protection policy) governs BYOD mobiles. A break-glass exclusion sits across both paths as a bypass lane so recovery accounts are never gated. The decision — allow / block / require — is emitted here, and in Report-only mode it’s recorded (as reportOnlySuccess / reportOnlyFailure) rather than enforced. Read the whole picture as: Intune produces the signal → the directory object holds it → the client presents it → Conditional Access decides on it. Every “device not compliant” ticket is a break somewhere along that single left-to-right arrow, and the diagnostic is to walk it from whichever end you can observe.
Real-world scenario
Nordwind Manufacturing, a 9,000-seat industrial firm, ran identity-only Conditional Access (MFA + sign-in risk) and, pushed by a cyber-insurance renewal, moved to require a compliant device for Office 365. Their estate was mixed: about 5,500 Autopilot-provisioned AzureAd Windows laptops (Intune-managed), 2,800 legacy ServerAd hybrid-joined desktops on the factory floor (domain-joined, not Intune-enrolled), and a long tail of BYOD phones. The endpoint team was six engineers; they staged carefully — a full report-only week on a 300-device pilot, What If runs for each persona, reportOnlyFailure driven to zero — and flipped Require compliant OR hybrid-joined to On for Office 365 on a Tuesday.
Within the hour the help desk lit up: Outlook and Teams failures from Autopilot laptops that were demonstrably Compliant in Intune. The report-only week hadn’t predicted it, which is what made it alarming. The breakthrough came from asking the right first question — does the Entra object agree with the Intune blade? — and running one Graph query against the affected ring:
Connect-MgGraph -Scopes "Device.Read.All"
# Windows devices that signed in recently but the OBJECT says non-compliant
Get-MgDevice -All -Filter "operatingSystem eq 'Windows'" |
Where-Object {
-not $_.IsCompliant -and
$_.ApproximateLastSignInDateTime -gt (Get-Date).AddDays(-2)
} |
Select-Object DisplayName, IsCompliant, TrustType, `
ApproximateLastSignInDateTime, RegistrationDateTime |
Measure-Object
It returned ~340 devices: Compliant in Intune’s blade, but IsCompliant = false on the Entra object. Root cause: their Compliance status validity period was 30 days, and a large Autopilot batch had a check-in gap — a proxy change on the corporate VLAN had bypassed and then blocked the Intune check-in endpoints (*.manage.microsoft.com, *.dm.microsoft.com) for that subnet. Those devices had stopped reporting to Intune weeks earlier; the 30-day validity window expired; isCompliant aged to false on the object even though each device’s local Intune client still showed green from its last successful evaluation. CA read the stale-aged object and blocked. Report-only had sampled sign-ins, not the silent ageing of the compliance bit — so it saw nothing wrong right up until the bit expired.
The fix was two-pronged and fast. Immediately: re-scope the CA policy with a transient grace filter — an Exclude filter on device.extensionAttribute2 -eq "checkin-remediation", with that tag written via Graph onto the affected device IDs — so those ~340 machines fell out of enforcement while they recovered, without weakening the grant for the other 8,660 devices. In parallel: unblock *.manage.microsoft.com and *.dm.microsoft.com on the proxy so check-ins resumed. As each device checked in and re-evaluated to compliant, its bit refreshed on the object; the team then removed the extensionAttribute2 tag, folding it back into enforcement. Full recovery took about six hours, with zero data-loss and no revenue impact, versus the day-long outage a “turn the policy off” reflex would have caused. The lesson on the wall: “Report-only samples sign-ins, not the ageing of the compliance bit. Before you enforce, confirm devices are actively checking in — not just nominally compliant.” They added a standing alert on devices whose ApproximateLastSignInDateTime was recent but IsCompliant was false, catching the divergence early ever after.
Advantages and disadvantages
The three-system device-compliance model is the highest-signal CA control there is — and its power and its fragility come from the same source: it depends on Intune, Entra, and CA all agreeing about a device, asynchronously. Weigh it honestly:
| Advantages (why the model is worth it) | Disadvantages (why it bites) |
|---|---|
| Moves trust from “password + phone” to “a continuously-evaluated managed device” — the core Zero Trust win | Depends on three asynchronous systems agreeing; eventual, not immediate, consistency |
| Stops token theft / AiTM: a stolen cookie replayed from an unmanaged device fails the device grant | The compliance bit ages; a check-in gap silently blocks nominally-compliant devices |
| The compliant OR hybrid grant bridges mixed estates so migration doesn’t require a big-bang cutover | Require compliant on a non-enrolled fleet blocks all of it; easy to pick the wrong grant |
| Filters for devices scope precisely (corporate-only, exclude kiosks) without policy sprawl | The include/exclude mode silently inverts intent; a mis-set filter ungates everyone |
| The MDE risk signal makes compliance continuous, not point-in-time | The risk rule is a silent no-op until the connector is fully wired |
| Report-only + What If + sign-in logs give a real dry run before enforcement | Defaults are unsafe: “no policy = compliant” disarms the grant; “mark noncompliant = 0 days” whiplashes rollout |
| The Entra device object is a single, queryable source of truth (Graph) | “Not compliant” often means the client didn’t present state (missing PRT/broker), not that the device is actually noncompliant |
The model is right for any organisation serious about Zero Trust device posture — which cyber-insurance and regulation increasingly mandate. It bites hardest on mixed estates (pick the OR grant), on teams that treat it as a checkbox (the defaults will disarm or lock out), and on BYOD-heavy shops that try to force enrolment instead of using the app-protection path. Every disadvantage is manageable — but only if you know it exists and staged for it, which is the entire point of the discipline in this article.
Hands-on lab
Build the full stack in a test tenant (or a scoped pilot), confirm compliance flows to the object, and verify a compliant device passes while a noncompliant one is blocked — all staged through report-only so nothing enforces until you say so. Use a test user and 1–2 test devices; a Microsoft 365 E3/E5 or EMS trial tenant with Intune is sufficient.
Step 1 — Create pilot groups and a break-glass exclusion group.
Connect-MgGraph -Scopes "Group.ReadWrite.All", "Device.Read.All"
# Pilot group for the compliance policy + CA policy
New-MgGroup -DisplayName "KV-Pilot-Windows" -MailEnabled:$false `
-SecurityEnabled:$true -MailNickname "KV-Pilot-Windows"
# Confirm your break-glass accounts exist and note their object IDs
Get-MgUser -Filter "startswith(userPrincipalName,'breakglass')" |
Select-Object DisplayName, Id, UserPrincipalName
Expected: a new security group, and your two break-glass account IDs. If you don’t have break-glass accounts yet, stop and create them first — do not proceed with a device grant without them.
Step 2 — Author a Windows compliance policy (portal). At Intune → Devices → Compliance → Create policy → Windows 10 and later:
- Device Health: Require BitLocker = Require; Require Secure Boot = Require.
- Device Properties: Minimum OS version = your lowest deployed supported build.
- System Security: Require a password = Require; Encryption of data storage = Require; Firewall = Require.
- Actions for noncompliance: Mark device noncompliant = 3 days (the grace period); Send email = 0 days and 2 days.
- Assignments: the
KV-Pilot-Windowsgroup.
Expected: the policy shows as assigned; give it time to evaluate on the next device check-in.
Step 3 — Set the tenant defaults safely. At Intune → Devices → Compliance → Compliance policy settings: confirm Compliance status validity period = 30 days. Leave Mark devices with no compliance policy assigned as at Compliant for now — you flip it to Not compliant only after real policies cover your production estate. (In this lab, leave it as-is so you don’t block yourself.)
Step 4 — Confirm compliance reached the Entra object. After a test device checks in and evaluates, verify the object — the whole point of the model is that the object is authoritative:
Get-MgDevice -Filter "displayName eq 'KV-LT-TEST01'" |
Select-Object DisplayName, TrustType, IsCompliant, IsManaged, OperatingSystem
Expected: IsCompliant : True, TrustType : AzureAd (or ServerAd for a hybrid test device). If IsCompliant is empty, wait for the next check-in (sync lag) — do not proceed until the object agrees with Intune.
Step 5 — Create the CA policy in report-only.
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
$pilot = (Get-MgGroup -Filter "displayName eq 'KV-Pilot-Windows'").Id
$bg1 = "<breakglass-1-id>"; $bg2 = "<breakglass-2-id>"
$params = @{
displayName = "CA-Require-Compliant-O365-Pilot"
state = "enabledForReportingButNotEnforced" # REPORT-ONLY
conditions = @{
applications = @{ includeApplications = @("Office365") }
users = @{ includeGroups = @($pilot); excludeUsers = @($bg1, $bg2) }
platforms = @{ includePlatforms = @("windows") }
}
grantControls = @{ operator = "OR"
builtInControls = @("compliantDevice", "domainJoinedDevice") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
Expected: the policy is created in report-only, scoped to Office 365, pilot users only, break-glass excluded, compliant-OR-hybrid grant.
Step 6 — Run What If for every persona. In Entra → Conditional Access → What If, simulate: (a) a pilot user on a compliant Windows device → policy applies, grant satisfied; (b) a break-glass account on any device → Not applied; © a noncompliant device → applies, would block. Confirm each matches the expected-result table above.
Step 7 — Analyse the report-only signal. After a day, in Entra → Sign-in logs → Report-only tab (or the KQL query above), find any reportOnlyFailure. Expected in a healthy pilot: near-zero. Any failure is a device to enrol/remediate before you’d enforce.
Validation checklist. You built a compliance policy with a real grace period, confirmed isCompliant reached the Entra object via Graph, created a report-only CA policy with the correct compliant-OR-hybrid grant and a verified break-glass exclusion, validated every persona in What If, and read the report-only signal — all without enforcing a thing. To go live you would only flip state to enabled after reportOnlyFailure is zero. The lab steps mapped to what each proves:
| Step | What you did | What it proves |
|---|---|---|
| 2 | Compliance policy with Mark noncompliant = 3 days | The grace period is the actions schedule |
| 3 | Left “no policy = Compliant” untouched | The tenant default is a deliberate, dangerous switch |
| 4 | Graph-confirmed IsCompliant on the object |
The object, not the blade, is what CA reads |
| 5 | Report-only CA policy, break-glass excluded | Safe staging + the lockout-prevention exclusion |
| 6 | What If per persona | The policy logic is correct before enforcement |
| 7 | Read reportOnlyFailure |
You know exactly who breaks before they do |
Cleanup. Delete the CA policy (Remove-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId <id>), the compliance policy, and the pilot group. Because you never enforced (report-only throughout) and never flipped the tenant default, there is nothing to un-break — which is the whole point of staging.
Common mistakes & troubleshooting
This is the playbook — the part you bookmark for the ticket that says “my device is Compliant in Intune but Conditional Access won’t let me in.” First as a scannable table you read mid-incident, then the reasoning for the entries that bite hardest.
| # | Symptom | Root cause | Confirm (exact cmd / portal path) | Fix |
|---|---|---|---|---|
| 1 | Device Compliant in Intune blade, but CA blocks it | isCompliant not yet written (sync lag) |
Get-MgDevice ... | Select IsCompliant = empty/false; Intune shows green |
Wait for next Intune check-in; then re-sign-in (new session) |
| 2 | Was working, now blocked; device went quiet in Intune | Compliance validity aged the bit to false | Object IsCompliant=false but ApproximateLastSignInDateTime recent; check-in gap |
Restore check-in (network/proxy to *.manage.microsoft.com); grace-filter the ring meanwhile |
| 3 | Blocked in Chrome/Firefox, works in Edge | Browser not using WAM → no device state presented | dsregcmd /status shows AzureAdPrt : YES |
Install Windows Accounts extension / enable browser SSO |
| 4 | Blocked; dsregcmd shows AzureAdPrt : NO |
PRT missing/expired → device state never presented | dsregcmd /status |
Re-trigger registration; fix time sync; re-authenticate |
| 5 | Every hybrid-joined domain PC is blocked | Grant is Require compliant on a non-enrolled fleet | Sign-in log: failure reason “compliant”; devices not in Intune | Change grant to compliant OR hybrid-joined (OR operator) |
| 6 | Unmanaged devices sail through the grant | “No policy assigned = Compliant” tenant default | Compliance policy settings shows Compliant | Set to Not compliant (after real policies are live) |
| 7 | Kiosk/shared devices unexpectedly blocked (or unexpectedly ungated) | Filter include/exclude inverted | What If on a tagged device; read filter Mode | Flip Include↔Exclude to match intent; re-run What If |
| 8 | Admins locked out of the portal after enforcing | Grant on All cloud apps, no break-glass exclusion | Policy scope = All apps; break-glass not excluded | Use break-glass to scope to Office 365 + exclude break-glass |
| 9 | Every briefly-remediating device blocks during rollout | Mark noncompliant at 0 days (no grace) | Compliance policy → Actions = 0 days | Set to 3 days during rollout; tighten later |
| 10 | macOS Compliant but blocked in browser | Enterprise SSO plug-in not deployed | No SSO extension profile assigned; Mac registered | Deploy the macOS Enterprise SSO extension via Intune |
| 11 | Legacy Outlook/ActiveSync client hard-blocked | Legacy-auth client can’t present device state | Sign-in log: client app = “Other clients”/legacy | Move to modern-auth client; block legacy auth separately |
| 12 | High-risk device suddenly blocked | MDE risk rule flipped it noncompliant | Compliance shows Defender-risk rule failing; MDE alert | Remediate the MDE detection; risk drops → re-evaluates |
| 13 | Defender-risk rule “does nothing” | MDE connector / device-compliance toggle off | MDE connector blade shows disabled | Enable connector + “allow MDE to enforce compliance” per platform |
| 14 | Compliant device sometimes blocked, inconsistently | Existing token carried old (blocked) state | Passes on fresh sign-in, fails on cached session | Sign out fully / use a fresh session; token refresh picks up new state |
| 15 | Automation/service sign-in blocked by the grant | Non-interactive identity has no device | Sign-in log: service principal / no device | Exclude the automation identity from the device-grant policy |
The expanded reasoning for the entries that cause the most wasted hours:
1. Compliant in Intune, blocked by CA — sync lag. The Intune blade and the Entra object are different stores updated on different schedules. Intune shows the result of the last evaluation; the object shows what was written to Entra, which lags by a check-in. Confirm: Get-MgDevice ... | Select IsCompliant returns empty/false while Intune shows green. Fix: wait for the next check-in, then start a fresh sign-in — an existing token won’t reflect the new state.
2. Was working, now blocked — the aged compliance bit. The subtlest and highest-impact failure (the Nordwind scenario). A device that stops checking in has its isCompliant reverted to false after the Compliance status validity period, even though its local Intune client still shows compliant. Confirm: the object shows IsCompliant = false while ApproximateLastSignInDateTime is recent — the tell-tale divergence — and Intune’s last check-in for the device is old. Fix: restore check-in connectivity (usually a proxy/firewall blocking *.manage.microsoft.com / *.dm.microsoft.com); as an emergency, add an Exclude filter tagging the affected devices so they fall out of enforcement until they re-evaluate.
4. AzureAdPrt : NO — the PRT is missing. CA can only evaluate device state that the client presents, and on Windows that presentation is the PRT. No PRT, no device state in the token request, and CA sees an unknown device → not compliant — on a device that is genuinely compliant. Confirm: dsregcmd /status shows AzureAdPrt : NO. Fix: re-trigger device registration, correct clock skew (PRT is time-sensitive), and re-authenticate; the PRT re-issues.
5. Every hybrid domain PC blocked — wrong grant. The single most common design error: Require compliant on a fleet of hybrid-joined machines that were never Intune-enrolled. None of them has ever had isCompliant set, so all are blocked. Confirm: the sign-in log failure reason cites the compliant control, and the devices are absent from Intune. Fix: change the grant to compliant OR hybrid-joined with the OR operator, so hybrid PCs pass on join type while cloud-managed ones pass on compliance.
6. Unmanaged devices sail through — the toothless grant. The grant is on, but “no policy assigned = Compliant” means unmanaged/unevaluated devices are treated as compliant and pass. Confirm: Compliance policy settings shows Compliant for the default. Fix: set it to Not compliant — but only after your real policies cover the production estate, or you’ll instantly block every not-yet-evaluated device.
7. Kiosks blocked or ungated — filter inversion. The include/exclude mode is about which devices the policy applies to, not allow/deny. Confirm: run What If on a tagged device and read the Mode. Fix: to exempt kiosks from the compliance requirement, use Exclude device.extensionAttribute1 -eq "kiosk"; Include with the same rule would apply the policy only to kiosks and ungate everyone else.
14. Inconsistent blocking — the token snapshot. CA evaluates the device state at token time, and an existing token carries whatever decision it was issued under. So a device can pass on a fresh sign-in and “fail” on a cached session that predates the compliance flip. Confirm: it works in a fresh/incognito session but fails in the existing one. Fix: sign out fully; the new session’s token request re-reads the current object state.
Best practices
- Break-glass first, always — and verify the exclusion every time. Two cloud-only
*.onmicrosoft.comGlobal Administrators, long random passwords, excluded from every CA policy, sign-in-alerted. A device grant is especially lethal to break-glass; confirm the exclusion on the new policy before it goes anywhere near On. - Scope to Office 365, not All cloud apps, on day one. “All apps” sweeps in the admin portals and registration endpoints you need to fix a bad policy. Widen scope only after the grant is proven.
- Use compliant OR hybrid-joined for any mixed estate. Cloud-managed devices pass on compliance, legacy hybrid PCs on join type. Reserve plain Require compliant for all-Intune fleets; never use Require all unless you truly mean “both.”
- Make the “mark noncompliant” schedule your grace period. 3 days during rollout, tightened to 1 (or 0 for high-security) once the estate is stable. Fire warning emails before it.
- Set “no policy assigned = Not compliant” — but only after policies are live. Left at Compliant, the grant is silently toothless; flipped too early, it blocks the whole fleet.
- Tune the Compliance status validity period and alert on divergence. Alert when a device’s
IsCompliantis false but its last sign-in is recent — that’s the aged-bit failure before it becomes an outage. - Read filter Mode as “the policy applies to devices where the rule is true (Include) / false (Exclude).” Validate every filter in What If; the inversion is the most common filter bug.
- Split desktops from mobiles: compliant grant for desktops, Require app protection policy for BYOD. Never force enrolment on personal phones. Audit for the retired approved-client-app grant and convert it.
- Wire the MDE connector fully (per platform) before relying on the risk rule. Enable the connection, connect each platform, turn on device-compliance enforcement, then add the machine risk rule — otherwise it’s a silent no-op.
- Stage through report-only for a full week, run What If for every persona, drive
reportOnlyFailureto zero, then enforce ring by ring. Report-only samples sign-ins, not the ageing of the compliance bit — confirm devices are actively checking in, not merely nominally compliant. - Manage CA and compliance policies as code (Graph/Bicep/Terraform), reviewed in PRs. A wrong grant operator or an inverted filter is a boot-time landmine; treat these policies like production config, not portal clicks.
- Ensure the client can present state per OS: WAM/PRT on Windows (browser SSO extension for Chrome/Firefox), the Enterprise SSO plug-in on macOS, Authenticator/Company Portal on mobile.
Security notes
- This grant is a security control, not a convenience. It closes the token-theft / AiTM gap that MFA alone leaves open: a stolen post-MFA session cookie replayed from an unmanaged device fails the device grant. Treat it as a primary defence, staged carefully rather than avoided.
- Least privilege on the Graph scopes that touch devices. Writing extension attributes needs
Device.ReadWrite.All; reading state needs onlyDevice.Read.All. Grant the narrower scope to anything that only reads, and protect the write scope — it can re-tag devices in and out of enforcement. - Protect the break-glass accounts as crown jewels. They are excluded from the very control that would otherwise stop credential misuse, so compensate with long random passwords, storage in a physical safe / privileged vault, and sign-in alerts on every use. See Entra Break-Glass Emergency Access, Monitoring & Governance.
- Layer the MDE risk signal for continuous assurance. Static compliance (“BitLocker on”) is point-in-time; the machine-risk rule makes a device that becomes actively compromised fail compliance and lose access within a check-in — defence in depth over a one-time check.
- Don’t let the grant become a false sense of security while toothless. The “no policy = Compliant” default means the control can be on and doing nothing. Audit that real policies cover the estate and the default is Not compliant.
- Combine with privileged-access controls for admins. Device compliance for admin sessions pairs with PIM just-in-time elevation; see Privileged Identity Management (PIM/PAM) Architecture.
- Block legacy authentication separately. Legacy-auth clients can’t present device state and are hard-blocked by the grant anyway — but block them explicitly so they can’t bypass modern controls elsewhere.
- Keep the device object model auditable. Since the Entra device object is the source of truth, monitor changes to compliance state and extension attributes; an attacker who could flip
isCompliantor a filter tag could bypass the grant.
Cost & sizing
The device-compliance stack is licensing-gated, not compute-gated — there’s no per-transaction cost, but the required licences are the real spend, and they’re per-user.
- Conditional Access requires Microsoft Entra ID P1 (per user/month) at minimum; risk-based conditions (the user-risk analogue) need P2. CA is included in Microsoft 365 E3 (P1) and E5 (P2), and in EMS E3/E5.
- Intune (compliance policies, MDM) is included in Microsoft 365 E3/E5, EMS E3/E5, or standalone Intune Plan 1. The compliant grant is worthless without Intune, so Intune licensing is non-negotiable for this design.
- Microsoft Defender for Endpoint (the machine-risk signal) needs MDE Plan 1/Plan 2 — included in Microsoft 365 E5 / E5 Security, or standalone. The static compliance rules work without it; only the risk rule requires it.
- App Protection Policies (MAM) for the BYOD mobile path are included with Intune — no extra cost, just configuration.
There is essentially no marginal runtime cost: compliance evaluation, the CA decision, and the Graph writes are platform functions, not billed operations. The sizing question is licence coverage, not capacity. A rough per-user monthly picture (indicative INR list-price bands; negotiate via EA/CSP):
| Component | Licence that includes it | Rough INR / user / month (indicative) | Notes |
|---|---|---|---|
| Conditional Access (P1) | Entra ID P1 / M365 E3 / EMS E3 | ~₹500–700 (P1 standalone) | Baseline for the compliant grant |
| Risk-based conditions (P2) | Entra ID P2 / M365 E5 / EMS E5 | ~₹800–1,000 (P2 standalone) | Only if you use user-risk too |
| Intune (compliance + MAM) | Intune P1 / M365 E3 / EMS E3 | ~₹700–900 (Intune P1 standalone) | Required — no Intune, no compliance |
| Defender for Endpoint (risk) | MDE P1/P2 / M365 E5 Security | ~₹300–1,000 depending on plan | Only for the machine-risk rule |
| App Protection Policies | (included with Intune) | ₹0 incremental | The BYOD mobile grant |
The pragmatic packaging: Microsoft 365 E3 covers CA (P1) + Intune for the whole desktop-compliance + MAM design; add E5 (or E5 Security) for the MDE risk signal and P2 risk conditions. Most organisations already hold E3 for other reasons, so the incremental cost of building this stack is often zero — the spend is the licence you already own, and the “cost” is the engineering discipline to stage it safely.
Interview & exam questions
1. What is the difference between the Require compliant and Require hybrid-joined CA grants, and when do you use each? Require compliant needs the device to be Intune-enrolled and evaluated (isCompliant = true); Require hybrid-joined only needs the device to be hybrid Entra-joined (trustType = ServerAd) and does not need Intune. Use compliant for cloud-native / Intune-managed estates, hybrid for legacy pure-domain estates, and compliant OR hybrid-joined (OR operator) for mixed estates mid-migration.
2. A device is Compliant in the Intune blade but Conditional Access blocks it. Name three distinct causes and how you’d confirm each. (a) Sync lag — isCompliant not yet written to the Entra object; confirm with Get-MgDevice ... | Select IsCompliant (empty/false while Intune shows green). (b) Aged compliance bit — the device stopped checking in and the validity period expired; confirm via the object showing IsCompliant=false with a recent last sign-in but an old Intune check-in. © Missing PRT / broker — the client didn’t present device state; confirm with dsregcmd /status (AzureAdPrt : NO) on Windows.
3. What does “Mark devices with no compliance policy assigned as: Compliant” do, and why is it dangerous? It’s a tenant default: any device with no assigned compliance policy is treated as compliant, so unmanaged/unevaluated devices pass the Require compliant grant — silently making it toothless. Set it to Not compliant, but only after real policies cover the estate, or you’ll instantly block every not-yet-evaluated device.
4. Where does the grace period for compliance live? In the Actions for noncompliance schedule — specifically the Mark device noncompliant action’s delay (e.g. 3 days). There is no separate “grace period” setting; that delay controls when isCompliant actually flips to false and CA starts blocking.
5. Explain the include/exclude trap in filters for devices. The filter Mode controls which devices the policy applies to, not allow/deny. Include rule applies the policy only to devices matching the rule; Exclude rule applies it to devices not matching. To exempt kiosks from a compliance requirement you use Exclude on their tag; Include on the same tag would apply the policy only to kiosks and leave everything else ungated.
6. How does the Defender for Endpoint risk signal integrate with device compliance, and what must be enabled? MDE computes a machine risk score; Intune consumes it as a compliance rule (at or under a risk level). The MDE↔Intune connector must be enabled, the platform connected, and device-compliance enforcement toggled on within it — otherwise the risk rule is a silent no-op. A risk above the threshold flips isCompliant false and CA blocks at next sign-in.
7. Why is the compliant-device grant especially dangerous to break-glass accounts? Break-glass (recovery) accounts almost never sign in from an enrolled, compliant device, so if they aren’t excluded, a device-compliance grant is the first thing that blocks your recovery account — locking you out of the portal needed to undo the policy. Exclude break-glass from every CA policy and verify it every time.
8. Why do personal phones belong on the app-protection path rather than the compliant grant? Require compliant needs Intune enrolment, which gives the org management authority over the whole personal device — users refuse it. Require app protection policy (Intune MAM) protects corporate data inside managed apps (PIN, encryption, selective wipe) without enrolling the device, so it’s the correct BYOD-mobile control.
9. A user gets in from Edge but is blocked from the same device in Chrome. What’s happening? Chrome isn’t using the WAM broker, so it doesn’t attach the device’s PRT to the token request — CA sees an unknown device and blocks, even though the device is compliant. Fix by installing the Windows Accounts extension (or enabling browser SSO) so Chrome presents device state; dsregcmd /status confirms the PRT is present.
10. What replaced the Require approved client app grant, and why does it matter? It was retired (stopped functioning in early March 2026) and is replaced by Require app protection policy. It matters because a legacy mobile policy still authored against the retired grant no longer enforces — so a tenant can look protected while doing nothing; audit and convert those policies.
11. Describe the compliance→CA token flow and where a stale token bites. Device checks in → Intune evaluates → writes isCompliant to the Entra object → CA reads the object at the next sign-in/token request. CA evaluates a snapshot at token time, so an existing token carries the old decision until the session refreshes — which is why a just-remediated device can still be blocked on a cached session but passes on a fresh sign-in.
12. How do you stage a device-compliance policy safely, and why isn’t report-only alone sufficient? Report-only (a full week) → What If for every persona → drive reportOnlyFailure to zero → enforce ring by ring. Report-only alone isn’t sufficient because it samples sign-ins, not the silent ageing of the compliance bit — so you also confirm devices are actively checking in (recent Intune check-in), not merely nominally compliant, before enforcing.
These map to SC-300 (Identity and Access Administrator) — Conditional Access, device-based access, Intune compliance integration; MD-102 (Endpoint Administrator) — compliance policies, device enrolment, the MDE connector; and SC-200 (Security Operations Analyst) — the Defender for Endpoint risk signal. A compact cert map:
| Question theme | Primary cert | Objective area |
|---|---|---|
| Compliant vs hybrid grant; CA design | SC-300 | Implement Conditional Access |
| Compliance policy authoring; actions/grace | MD-102 | Manage compliance policies |
| MDE risk connector + rule | MD-102 / SC-200 | Endpoint security; Defender integration |
| Filters for devices; extension attributes | SC-300 | Conditional Access assignments |
| App protection (MAM) vs device compliance | MD-102 | Manage app protection policies |
| Report-only / What If / rollout staging | SC-300 | Plan and implement CA |
Quick check
- A fleet of hybrid-joined, non-Intune-enrolled domain PCs is entirely blocked after you enable a device grant. What grant did you pick, and what should it be?
- Where is the compliance “grace period” configured, and what value would you use during a rollout?
- Your Require compliant grant is on, but unmanaged laptops are getting in. What tenant setting is almost certainly the cause?
- A Windows device is Compliant in Intune but CA blocks it, and
dsregcmd /statusshowsAzureAdPrt : NO. What’s wrong, and is the device actually noncompliant? - You want to exempt kiosk devices (tagged
extensionAttribute1 = "kiosk") from a require-compliant policy. Do you use an Include or an Exclude filter, and why?
Answers
- You picked Require device to be marked as compliant, which needs Intune enrolment — these devices were never enrolled, so
isCompliantwas never set and all are blocked. It should be Require compliant OR hybrid-joined with the OR operator, so the hybrid PCs pass ontrustType = ServerAdwhile cloud-managed devices pass on compliance. - In the compliance policy’s Actions for noncompliance tab, via the Mark device noncompliant action’s delay — there is no separate grace-period setting. Use 3 days during rollout so briefly-failing devices aren’t blocked instantly, then tighten later.
- The “Mark devices with no compliance policy assigned as: Compliant” tenant default (Compliance policy settings). Left at Compliant, unmanaged/unevaluated devices are treated as compliant and pass the grant. Set it to Not compliant (after your real policies are live).
- The Primary Refresh Token is missing, so the client can’t present the device’s state in the token request; CA sees an unknown device and blocks. The device is not actually noncompliant — its compliance is real, but the presentation of it failed. Re-trigger registration / fix time sync / re-authenticate to reissue the PRT.
- Use an Exclude filter with
device.extensionAttribute1 -eq "kiosk". Filter Mode controls which devices the policy applies to: Exclude means “apply to everything except matched devices,” so kiosks fall out of enforcement while everyone else stays gated. An Include filter with the same rule would apply the policy only to kiosks and ungate every other device.
Glossary
- Device object — the Entra ID representation of a device; carries
trustTypeandisCompliant, and is the single source of truth Conditional Access reads. trustType— the device join type on the object:Workplace(Entra registered / BYOD),ServerAd(hybrid joined),AzureAd(Entra joined / cloud-native).isCompliant— the boolean Intune stamps onto the device object after evaluating a compliance policy; the exact bit the Require compliant grant reads.- Compliance policy — an Intune policy of pass/fail rules (device health, OS version, system security, Defender risk) plus actions for noncompliance; produces
isCompliant. - Actions for noncompliance — the schedule of what happens (mark noncompliant, email, push, lock, retire) and when; the “mark noncompliant” delay is the grace period.
- Compliance status validity period — the tenant setting for how long a compliance state stays valid without a check-in; on expiry,
isCompliantages to false. - MDE risk signal — the machine risk score (Clear/Low/Medium/High) from Microsoft Defender for Endpoint, consumed by a compliance rule (at or under a level) via the MDE↔Intune connector.
- Require compliant grant — the CA control (
compliantDevice) needingisCompliant = true; requires Intune enrolment. - Require hybrid-joined grant — the CA control (
domainJoinedDevice) needingtrustType = ServerAd; does not require Intune. - Filter for devices — a CA assignment that includes/excludes based on device-object attributes (ownership, OS, join type, model, extension attributes) rather than the user.
- Include / Exclude mode — the filter Mode controlling which devices the policy applies to (matching / not-matching the rule) — not allow vs deny.
- Extension attribute — one of 15 writable tags (
extensionAttribute1..15) on the Entra device object, set via Graph; the tagging system filters key off. - PRT (Primary Refresh Token) — the Windows artefact proving device identity/state, issued at registration and presented by WAM during token requests; missing PRT → device state not presented → blocked.
- WAM (Web Account Manager) — the Windows broker that attaches the PRT to token requests; non-WAM browsers present no device state.
- Enterprise SSO plug-in — the macOS extension (deployed via Intune) that presents device state during sign-in; the Mac analogue of WAM.
- App Protection Policy (MAM) — an Intune policy protecting corporate data inside managed apps (PIN, encryption, selective wipe) without enrolling the device; the BYOD-mobile grant.
- Report-only — a CA policy
state(enabledForReportingButNotEnforced) that evaluates every sign-in and records the would-be result without enforcing; the safe staging mode. - What If — the CA simulation tool that evaluates policy logic against a stated user/app/device/platform to see which policies apply and what they’d decide.
Next steps
You can now build, scope, stage, and debug device-compliance gating end to end. Build outward:
- Next: Conditional Access at Scale: Personas & Authentication Context — the policy-set architecture this grant slots into (personas, protected actions, auth context).
- Related: Intune MAM: App Protection Without Enrolment (BYOD) — author the App Protection Policies the Require app protection policy grant depends on (the mobile half of this design).
- Related: Intune Filters: Assignment Targeting & Ring Deployment — the assignment-scoping and ring model for rolling compliance out safely.
- Related: Entra Break-Glass Emergency Access, Monitoring & Governance — the exclusion hygiene that keeps a device grant from locking you out.
- Related: Entra ID Protection: Risk-Based Policies, Tuning & Investigation — the user-risk signal that layers with the device-risk signal used here.
- Related: Intune Windows Update Rings & Feature Update Profiles — keep the OS-version compliance rule satisfiable by governing updates in rings.
- Related: Autopilot Device Preparation, Entra Join & Migration — provision the cloud-native, Intune-managed devices that pass the compliant grant cleanly.