Conditional Access baselines across MSP-managed tenants
4 min readMarkdown version
Author the policy once, create it in each tenant in report-only state, review the impact in sign-in logs, then enable it. Conditional Access policies are created and read through Microsoft Graph v1.0, and updates are a partial PATCH that returns 204 and preserves fields you did not send, which means a drifted policy can be corrected by patching the changed fields back rather than deleting and recreating it. Deleting a Conditional Access policy to recreate it removes an enforced control in the gap, so it is the wrong remediation path.
Report-only exists precisely for this
Conditional Access policies have three states: enabled, disabled, and enabled for reporting but not enforced. The third one evaluates the policy against real sign-ins and records what would have happened, without blocking anyone.
For a fleet rollout this is not an optional nicety. A require-MFA policy that looks obviously correct will still catch a service account, a conference room device or a legacy client somewhere in a client's estate, and finding that in the sign-in logs is much better than finding it in a phone call.
The update semantics that make rollback safe
Conditional Access policies are updated with a partial PATCH: you send only the fields you are changing and the response is 204 No Content. Microsoft's wording on what happens to the rest is worth reading exactly: properties not included in the request body maintain their previous values, or are recalculated based on changes to other property values. So it is not a blind merge, but it does mean correcting a drifted policy is a targeted write rather than a replacement.
This is the opposite of the Intune Settings Catalog, where the settings navigation property has no separate write verb and a correction can require replacing the policy. Two governance surfaces, two different safe remediation strategies, and a tool that treats them the same way will eventually do the wrong one.
What goes in a baseline
The specifics belong to your practice and your clients' risk appetite, but the shape is consistent across MSPs.
- MFA for administrators: The least controversial control and the one with the largest effect.
- Block legacy authentication: The change most likely to break something, and the reason report-only exists.
- Device compliance for company resources: Only meaningful where device management is actually in place, so it is often tenant-conditional.
- Sign-in risk and user risk policies: Depends on the licensing the tenant holds, which varies across a fleet more than anything else in the list.
- Break-glass exclusions: Every tenant needs at least one excluded emergency access account, and it needs to be tested, not assumed.
Why one baseline never applies unchanged
The tempting design is one canonical policy JSON pushed to every tenant. It fails immediately, because the object references tenant-specific identifiers: the break-glass accounts, the excluded service principals, the groups the policy targets. These do not exist in another tenant.
So a baseline is a template plus per-tenant bindings, not a blob. Keep the parts that must be identical identical, keep the parts that must differ explicit, and be able to answer 'which tenants deviate from the baseline and how' without opening thirty portals.
How rugged.sh handles it
The Conditional Access baselines rugged.sh ships are authored report-only, so applying one cannot lock anybody out of a tenant on the day you apply it. The baseline is recorded as the golden state, drift is scanned on a schedule alongside Intune policy, and remediation patches the changed fields back rather than deleting the policy. The scan and the remediation are per customer tenant and both are audited.
Questions people ask
- What are the Conditional Access policy states?
- enabled, disabled, and enabledForReportingButNotEnforced. The last one evaluates the policy against real sign-ins and records the outcome without enforcing it, which is how a new baseline should be rolled out to a tenant you do not want to lock anyone out of.
- How do I update a Conditional Access policy without overwriting everything?
- Send a partial PATCH containing only the fields you are changing. Graph returns 204 No Content. Properties you did not include keep their previous values, or are recalculated if they depend on something you did change, so a drifted policy is corrected by patching the difference rather than replacing the object.
- Should I delete and recreate a Conditional Access policy that has drifted?
- No. Deleting it removes an enforced security control until the replacement is created, which is a window you do not want in a customer tenant. Patch the changed fields back instead.
- Can I use the same Conditional Access baseline in every tenant?
- The controls can be identical, but the object cannot: policies reference tenant-specific groups, break-glass accounts and service principals. Treat a baseline as a template with per-tenant bindings, and track which tenants deviate from it.
Sources
Microsoft's behaviour described above was read from these pages on the dates shown. Claims that come from our own testing against a live Azure subscription carry that date inline.
- Microsoft Learn: conditionalAccessPolicy resource type (Graph v1.0) (read September 10, 2026)
- Microsoft Learn: Update conditionalAccessPolicy (read September 10, 2026)