[GSA 3] The Microsoft Profile and Conditional Access: The Cheapest Security Win You Own

The compliant network check turns network position into something your identity system asserts rather than something you maintain a list of. It is included with the licence you already hold, and it stops at a boundary that shapes every decision later in this series.


Most of what Global Secure Access sells you costs money. The part that matters most does not. If your tenant holds Entra ID P1, you already own the Microsoft traffic profile, and with it a Conditional Access control that changes what network position means. It is the cheapest defence against token theft available to you today, and it stops at a boundary that shapes every decision in the rest of this series.

What the check actually asserts

A named location in Conditional Access asserts something about an address. You enumerate the egress ranges you trust, you mark them trusted, and from then on you own a list that goes stale every time a circuit changes, an office moves, or somebody stands up a new branch without telling you. The list is not the control. The list is the maintenance burden you accept in order to have the control.

The compliant network check asserts something different. It does not claim the user is at an address you trust. It claims their traffic arrived through your tenant’s instance of the Global Secure Access service, which means it passed the client that you deployed, under the profile that you enabled, for a user you assigned. The signal is tenant bound by construction. A policy requiring a compliant network in your tenant cannot be satisfied by a user coming through somebody else’s tenant, which closes the obvious attack of standing up your own instance of the service and pointing it at the target.

You stop maintaining a list of addresses and start asserting a property of the path.

That is a change in the kind of statement you are making, not a refinement of the old one. The authority moves from your network documentation, which is always slightly wrong, into the identity system, which knows in the moment whether the traffic came through the service or not. It also retires a piece of architecture that has survived far longer than it deserved: the practice of hairpinning traffic back through a corporate VPN concentrator purely so that the source address looks right to an IP-based policy. That was never a security control. It was a way of making a security control believe something.


Why it defeats replay, and where it stops

Token theft is the attack this control was built for. An adversary who lifts a refresh token from a workstation, or a session cookie from a phished browser, does not need the password and does not need to satisfy multifactor authentication again. They need only to present the token from wherever they are. Every strong authentication control you own was already satisfied, in the past, by the real user.

Enforcement happens in two places, and the difference between them is the difference between a good control and a complete one. At the authentication plane, Entra ID evaluates the compliant network condition every time a token is issued. A stolen refresh token replayed from a machine that is not connected to your instance of the service is refused, immediately, and nothing further is granted. That half is decisive. At the data plane, services that participate in continuous access evaluation reject an access token that is being replayed from outside the compliant network in near real time, and Microsoft Graph is the example they name. Everything that does not participate holds its access token for the full lifetime, which sits between sixty and ninety minutes by default.

So the honest description is not that token replay stops working. It is that the window collapses from indefinite to roughly an hour on the resources that cannot evaluate continuously, and to minutes on the ones that can, and that no new access can be minted at all. For a control that arrives at no additional licence cost, that is an unusually good trade, and it is the reason I open every Global Secure Access engagement with this profile rather than with the products people actually asked about.


One switch wearing two names

There is a piece of confusion in Microsoft’s own documentation worth clearing up before you plan anything, because it will otherwise cost you an afternoon. The compliant network signal and source IP restoration are described on different pages, under different names, as though they were separate features with a dependency between them. One page states flatly that you must enable source IP restoration in order to target the compliant network in Conditional Access. They are the same control. There is a single tenant setting that turns on Conditional Access signalling from the service, and enabling it is what produces both the restored source address in your logs and the named location that represents the compliant network. If you go looking for a second toggle you will not find one.

Source IP restoration is worth understanding on its own terms, because it changes what your logs mean. Without it, everything arrives from the service edge, and every sign-in in your tenant appears to originate from an anycast range shared with every other customer. With it, the original egress address of the user is restored into the sign-in logs, the audit logs, Identity Protection, and location evaluation in Conditional Access. You see one or the other, never both, which is a real design decision rather than an oversight: if you have built anything that depends on recognising the service address, restoring the client address will break it.

The limit is that only Microsoft resources evaluate location policies against the restored address. Anything else protected through the service does not know the original address, so an IP-based policy pointed at a third party will not behave the way the same policy pointed at Exchange Online does. That asymmetry is worth writing down in your policy documentation, because it is invisible in the policy blade and it produces a class of ticket that is very hard to diagnose from the user’s side.


Continuous evaluation, and the mode that will surprise you

The service authenticates its own tunnels with Entra ID tokens, and it prefers tokens that participate in continuous access evaluation. That is what allows a revocation event to reach a connected client rather than waiting for a token to expire. The published timings are specific enough to plan against: the signal reaches the client in roughly two to five minutes, the client prompts the user three times with a two minute grace period each, and a client that cannot reauthenticate is disconnected from the network after about ten minutes. The events that trigger it are the ones you would expect, including a disabled account, a password reset, a revocation of refresh tokens, and a high user risk detection.

What surprises people is that this is opportunistic by default. If a client cannot obtain a continuously evaluated token, it is issued an ordinary one and carries on. That fallback is deliberate, and it is the reason Microsoft advises against disabling the feature: the failure mode is already graceful. There is an optional strict enforcement mode that removes the grace, and it does exactly what its name says. Access stops the moment the address seen by the resource provider is not permitted by policy.

Strict enforcement is where I would slow down. Microsoft documents that turning it on can block users who are, by every other measure, inside a trusted range, and the reason is the asymmetry from the previous section: resources that do not know the original source address cannot evaluate a location policy against it. If you run IP-based location policies against anything other than Microsoft resources, strict enforcement and those policies will fight, and the user loses. Leave it off until you have satisfied yourself that source IP restoration covers every path your location policies touch.

One caution about platform coverage, offered because I would rather you know the documentation is unsettled than trust a summary of it. The known limitations page states that only the Windows client supports universal continuous access evaluation, and names a minimum version, and says other platforms fall back to ordinary tokens. The macOS client release notes record continuous access evaluation support in a release from June 2025. Both are current pages, they describe the same mechanism, and Microsoft has not reconciled them. Plan for Windows, verify anything you intend to claim about macOS in your own tenant, and do not build a control that assumes parity.


Tenant restrictions, scoped honestly

The same profile carries universal tenant restrictions, which is the control that stops a user on your managed device from signing into a foreign tenant with a personal or third-party account and moving data sideways out of your estate. The service tags the traffic, so it works regardless of browser or operating system, and it accepts a clientless branch as well as a client, which makes it one of the few controls in this family that does.

Its scope needs stating precisely, because the marketing framing and the documented behaviour are not the same size. Enforcement through this service covers the authentication plane on every platform, and covers the data plane for Microsoft Graph only. The anonymous paths that people actually worry about, the anonymously shared document link and the anonymous meeting join, are handled as data plane protection, and the mechanism Microsoft names for Microsoft 365 data plane coverage is the Windows device path with Group Policy, not this one. If a client tells you tenant restrictions has closed anonymous sharing across their estate because they enabled it here, they have been sold a larger claim than the documentation supports.

Worth knowing for the same reason: no Microsoft page states that universal tenant restrictions is generally available by name. Authentication plane protection in the underlying tenant restrictions feature is documented as generally available, and the entitlement table lists this capability without a preview marker on a page that marks previews. That is enough to deploy on. It is not enough to write a sentence claiming a general availability date, and I would not put one in a client document.


The boundary that shapes the rest of this series

Everything above applies to Microsoft traffic and, where you licence it, to general internet traffic. None of it reaches the private applications you are about to publish. That is the single most consequential fact in this series, and it is stated three ways in Microsoft’s documentation for anyone who wants to check: the known limitations page says the compliant network check is not supported for Private Access applications; the entitlement table marks the check only in the column for the Microsoft traffic profile and leaves the Private Access column blank; and the universal Conditional Access page says plainly that there is no support for targeting the Private Access tunnel and that you must target Private Access enterprise applications individually.

The control that makes Microsoft traffic safe does not reach the private applications you are about to publish.

It is worth being careful about why, because there is a plausible explanation that is wrong. The service does exclude its own resources from a compliant network policy automatically, and the sign-in logs show those exclusions under names that include one for private resources, which invites the conclusion that private applications are simply excluded along with everything else. They are not. What is excluded is the tunnel the client authenticates to, along with the internal policy service, and that exclusion exists to stop the client locking itself out of the machinery it needs in order to work. A Private Access application is an ordinary enterprise application in your tenant, and it is not on that list.

Which produces an odd situation at exactly the configuration Microsoft’s own guidance recommends. The reference policy targets all resources. Private Access applications are resources. So the policy reaches them, while the control it applies is documented as unsupported there, and no page describes what happens next: whether the condition passes, blocks, or is quietly ignored. I have not found a first-party statement in either direction, and I am not willing to guess in print about a configuration whose failure mode is users losing access to internal file shares. Treat it as untested territory, keep your private applications under their own policies where the controls are documented to work, and satisfy yourself in a lab before you scope a compliant network requirement across everything.

The design consequence is larger than the operational one. Private Access gets Conditional Access at the application, which means multifactor authentication, device compliance and risk conditions per published application, and that is genuinely useful. What it does not get is a control that asserts the traffic came through your service at all. So the compliant network check protects the identity plane and the Microsoft estate, and the security of your private applications rests on assignment and on per-application policy. Two different arguments, two different sets of evidence, and any deployment plan that treats them as one thing will overstate what it has achieved.


Where a branch office fits, and where it does not

There is a clientless path into this service. You build a tunnel from the equipment at a site to the service edge, and every device behind it is carried without any software installed, which is the answer for the printer, the camera, the appliance and the operating system nobody supports a client on. It is genuinely useful and it is genuinely narrow, and the narrowness is not obvious from the product page.

A site connected this way can satisfy the compliant network check. That is a real capability and it is the reason I raise remote networks in this article rather than later: for a device that cannot run a client, a site tunnel is the only way it will ever pass a compliant network policy. What that site does not get is the identity half. Conditional Access identity controls applied to acquired traffic, meaning multifactor authentication or device compliance evaluated against the traffic itself, are documented as enforced only where the client is installed. Neither does a user-aware security profile reach it, because user awareness comes from the client. What a clientless site gets is the tenant-wide baseline profile and nothing more granular.

So the honest way to describe a site tunnel is that it buys you a network signal without the identity controls. That is worth having for the population that cannot be given a client, and it is not a substitute for one. It also carries no Private Access at all, which is a hard product boundary rather than a licensing one, so a branch tunnel is never the way you reach an internal file server. And one warning that costs nothing to heed: Microsoft’s own quickstart for this feature contains a sentence implying full Conditional Access enforcement without a client, which contradicts the limitations page. The limitations page is the one to believe.


The exclusions, and the one you will wish you had made

A compliant network policy scoped broadly is a blocking policy, and blocking policies earn their exclusions by argument rather than by habit. The service’s own resources are excluded for you, which is the anti-lockout plumbing described earlier. Beyond that there is a short list you have to construct yourself, and two of its members are easy to miss.

The first is device enrolment. A device that is not yet enrolled cannot be running your client, and a policy that requires a compliant network in order to reach the enrolment service creates a dependency that resolves in neither direction. Microsoft’s guidance is to exclude the enrolment and management applications explicitly, and the reasoning is worth repeating to whoever reviews your policy set, because on paper it looks like a weakening of the control rather than the precondition for having one.

The second only applies if you have adopted the explicit forward proxy, the preview path for devices that cannot run a client at all, and it is genuinely counterintuitive. That proxy authenticates the session with Entra ID before the connection is established, and Entra ID traffic must be excluded from proxy configuration by design. So the authentication that gates the proxy does not itself travel through the proxy, the compliant network signal is absent when it happens, and a policy scoped to all applications will fail closed against the proxy’s own service principal. The remedy is to exclude that principal by hand. It is not among the automatic exclusions, and the automatic ones are what make everybody assume the anti-lockout work has been done for them.

Break-glass accounts sit outside this policy for the same reason they sit outside every other blocking policy in your tenant, and service principals are not subject to policies scoped to users in the first place, which is a fact worth confirming rather than assuming when somebody asks why a synchronisation account is unaffected.

There is one more thing that has to sit outside the blocking path, and it is not a policy exclusion at all, which is why it gets missed. If you write a policy that blocks acquired internet traffic on a device that is not compliant, a device that has fallen out of compliance cannot reach the management service that would let it become compliant again. The user is not locked out of an application. They are locked out of the path back. The remedy is a deliberate bypass in the traffic profile for the management endpoints, including anything a custom compliance evaluation reaches out to. It costs one decision made in advance and it is close to unrecoverable at scale afterwards, because the population that needs the fix is the population that cannot receive one. This is the first thing I look for when I inherit somebody else’s deployment, and it is almost never present.


The bootstrap gap is structural, not a defect

The client runs after a user has signed in and depends on a primary refresh token to obtain its profile. That single sentence determines the shape of your rollout. A device coming out of the box, sitting in Autopilot, has no signed-in user and therefore no client and therefore no compliant network. A kiosk or a shared device running a userless or first-run flow is in the same position. So is any provisioning bench.

This is not something to be fixed. It follows from where the client sits in the boot order, and any design that requires a compliant network during provisioning is asking for a property the platform cannot supply at that moment. The answers are the ones this blog has used for the equivalent problem in the Conditional Access framework: time-boxed exclusions that expire, a named location for a staging bench, or a policy that stays in report-only until the population it covers can actually satisfy it. What I would not do is grant a permanent exclusion to a provisioning group, because a permanent exclusion to solve a temporary condition is how estates acquire a set of accounts nobody can explain three years later.

The related exposure is the client’s own disable control. Any user can pause the client from the system tray unless you have set the value that restricts that action to a privileged account. If your compliant network policy is enforcing, then a user who pauses the client has locked themselves out of Microsoft 365, which they will report as an outage. Set the restriction before you enforce, not after, and read the report-only discipline in [CA 2.1] Testing Conditional Access before you flip anything, because everything that doctrine says about report-only applies here with more force than usual.


Where this sits relative to the framework

Readers who run the [CA 4] VCIO CA Framework will want to know whether a compliant network policy becomes part of it. My answer for now is that it sits alongside the framework rather than inside it, and the reason is a distinction the framework is built on.

The core of that framework assumes a licence and nothing else. Import it into any tenant with Entra ID P1 and every policy in it is capable of evaluating, which is what makes it safe to ship as a baseline and safe to gate with a validator. A compliant network policy assumes considerably more: an activated service, an enabled profile, an assigned population, and a client deployed on every device in scope. In a tenant that has none of those, the policy cannot pass for anyone, and a baseline that ships a policy which fails for every user in report-only is not a baseline, it is noise. The framework already has the mechanism for this problem, in the form of editions that carry policies with a dependency the core does not have, and that is where this belongs at the next revision.

Until then, write the policy to the framework’s naming convention so it drops into an existing estate without argument, keep its exclusion group dedicated to it rather than shared, and hold it to the same rule as everything else in that catalogue: report-only until the evidence says otherwise, and one policy per intent. If you are wiring it into an estate that already runs the framework, [CA 1] Conditional Access: The Real Control Plane is the argument for why a network condition belongs in the policy engine at all rather than in the network.


What I would actually do first

Activate the service, enable the Microsoft traffic profile, deploy the client to a pilot group small enough that you know everyone in it by name, turn on the signalling that produces the compliant network location, and write the policy in report-only. Then read the sign-in logs for a fortnight and look for the populations that never satisfy the condition, because that list is the real design document. It will contain the provisioning bench, the shared devices, the contractor laptops nobody enrolled, and at least one service that authenticates in a way nobody remembered. Fix or exclude each one on its merits, then enforce.

What makes this worth doing before anything else in the product is the ratio. The licence is already paid for, the deployment is a client and a policy, and the control it buys is the one that addresses the attack that actually happens to the estates I work in. Private Access and Internet Access are larger projects with real business cases, and they can wait. This cannot, and it is the only part of Global Secure Access I would describe as urgent.

The build sheet takes it from here, with the client packaging, the exact settings, the policy and its exclusions, and an end-to-end test that proves the block actually happens rather than assuming it. If you have arrived here without reading the argument for why network access belongs to the identity system in the first place, [GSA 1] Global Secure Access: Identity at the Network Edge makes it.


Global Secure Access
‹ Previous: [GSA 2] Paying for the Edge: Licensing Without the Fog
Next: [GSA 3.1] Build Sheet: The Microsoft Profile and the Compliant Network Policy