SecurityZero Trust

Conditional access is a policy, not a prayer

Your sign-in rules decide who gets into everything you run. Treat them like code: track every change, test in report-only mode and keep a rehearsed way back.

Cohash Security Practice May 2026 updated October 2026 12 min read 6 chapters 3-question check
part 1 of 11 · Identity security, from the ground up
A full business cycle Report-only Pilot ringenforces Staged rings Change in git All users

the ideaChange access policies the way you'd ship code: report-only, then rings, rollback at hand.

after reading, you can
  • Put conditional access policies under version control so every change has a diff, an author and someone who reviewed it.
  • Read report-only results, looking for the service accounts and devices the policy would wrongly block.
  • Explain how a bad policy is kept small by ring rollouts and alarmed break-glass, plus a rollback you've rehearsed.

Conditional accessdefinitionRules evaluated at each sign-in that look at conditions such as user, device or location, and then allow, block or demand more proof. policies decide, on every sign-in, who gets into everything you run. In most tenants they're still edited by hand, in production, with no history and no test. The control guarding your front door deserves at least the engineering discipline you give a config file. Put it in version control, stage the rollout and rehearse the rollback. Anything less is hoping the last admin clicked the right box.

in plain wordsPractice: plan this quarter

Conditional access decides who gets in at every sign-in, and it often goes untested

When someone at your company signs in to Microsoft 365, or any app tied to Microsoft Entra, Entra checks a set of rules before it lets them through. Those rules are conditional access policies. They look at who is signing in, on which device and from where. Depending on the answers, the person gets in, gets asked for more proof first, or gets turned away. In many companies an admin edits these rules by hand on the live system, with no history and no test run. One wrong click can lock out the whole company. Another can quietly let a stolen password straight in.

think of it like this

Picture the security desk in an office lobby, working from a binder of rules: staff need a badge, visitors need an escort after six, contractors only go to two floors. If anyone can scribble in that binder without signing it, nobody can say later why the night guard waved a stranger through. Treating policies as code means every change to the binder is signed, checked by a second person and easy to undo.

who should care
  • Companies on Microsoft 365 or Entra ID
  • IT and identity admins
  • Security teams
  • Owners who face audits
  • Managed IT providers
chapter 01

Why it matters to you

A conditional access mistake goes one of two ways. A policy that's too strict locks people out, sometimes the very admins who could fix it, and the help desk lights up. A policy with a gap lets in someone who shouldn't be there, and nothing on screen tells you.

The gap is the one that hurts. An exclusion added for a travelling executive or a broken app often stays forever. If that policy was the only thing asking for a second check, anyone who phishes that person's password gets in on the password alone. The sign-in log just records the policy as not applied.

We've argued before that zero trust is a proof obligation: every access decision is a claim you should be able to evidence. Conditional access is where that gets mechanical, since the policies are the claims. This note is about keeping them provable while you change them, which mostly comes down to three disciplines.

how the attack worksHow someone gets in with just a phished passwordNothing here is a bug in Entra. The policy does exactly what it says, and what it says is out of date.
  1. 01 An exclusion gets added

    An admin takes one person out of the MFA policy to fix an urgent problem. Nobody writes down why, or for how long.

  2. 02 Everyone forgets it

    Weeks later the exclusion is still there. Nothing tracks it, so nothing reminds anyone to take it out.

  3. 03 The password gets phished

    Someone sends the excluded person a fake sign-in page, and they type their password into it. The attacker now holds a working password.

  4. 04 The policy doesn't apply

    The attacker signs in. Entra sees the user is excluded, marks the policy Not applied and asks for nothing more.

  5. 05 The attacker is in

    Mail, files and whatever else that account can open are exposed. Nothing failed, so there may be no alert at all.

how it worksHow we'd ship a policy change so nobody gets locked outThe same change, made with a history, a test run and a way back.
  1. 01 Write the change in git

    An admin opens a pull request against the policy file instead of clicking around in the live portal. Whoever reads it later can see who made the change and why.

  2. 02 A second person reviews it

    A colleague reads the diff before anything goes live. Firewall changes already get this, so the sign-in rules should too.

  3. 03 Run it in report-only mode

    Entra checks every real sign-in against the new rule and writes down what it would have done. Nobody gets blocked yet.

  4. 04 Read the would-be blocks

    After a full business cycle, the team reads who would have been stopped. Service accounts, odd devices and month-end jobs show up here.

  5. 05 Turn it on for a pilot ring

    The policy starts enforcing for IT and a few volunteers, the people who wrote it among them. If it breaks something, it breaks for them first.

  6. 06 Widen it ring by ring

    Next come staged groups, one after another, until everyone is covered. Nobody moves to the next ring while the last one is still throwing errors.

  7. 07 Watch it, keep the way back

    A lockout-spike alert is armed before each ring. If it fires, the team reverts to the previous version they've already rehearsed.

For the engineers, the export is the easy part. Microsoft Graph lists every policy at GET /identity/conditionalAccess/policies with the Policy.Read.All permission, so a scheduled job can pull the whole tenant into a repository. Each sign-in in the Entra sign-in logs then has Conditional Access and Report-only tabs that show which policies applied and which didn't.

The What If tool under Conditional Access simulates one sign-in for a user or service principal before you change anything. It doesn't follow service dependencies, though, so a test for Teams won't show the Exchange Online policy sitting behind it. Use it to check a single case, and use report-only data to see the whole tenant.

chapter 02

What changes when policies become code

side by sideThe same policies, run two ways
Edited by hand in the portal
  • Admins click changes straight into the live tenant
  • Nobody reviews a change before it takes effect
  • The audit log keeps old and new values for 30 days by default, then they're gone
  • Exclusions pile up with no owner and no end date
  • To roll back, someone has to remember what the policy used to say, usually under pressure
Managed as code
  • Every change is a commit with an author and a reason
  • A second person approves the diff first
  • Git keeps every version, so last year's policy is still one command away.
  • Exclusions come with an owner and an end date, and someone has to renew them on purpose
  • To roll back, you redeploy the last good version from git and check the sign-ins

Policies are production code, so give them a repository. A tenant's CA configuration should live in version control, exported as code and deployed through review, so nobody has to reconstruct it from memory after an incident. Every change gets a diff, an author, a reviewer and a reason, and every past state can be restored.

After any access incident someone asks what changed, and what the policy said at the time. A portal edit history can't answer that well. Entra's audit log does record old and new values for each change, but by default it only keeps them for 30 days. A git log makes the question trivial, however long ago the change was.

Policy-as-codedefinitionKeeping policies in version control as files and deploying through review. That way each change is tracked and can be undone. also kills the classic driftdefinitionWhen a live configuration slowly wanders away from what you intended, often through emergency edits nobody tracked. failure, where the emergency exclusion added at 2 a.m. quietly becomes permanent because nothing tracked it. Exclusions deserve the same rigor. Give each one a named owner and a written reason, put an expiry date on it, and review the list on a schedule. An exclusion list that only ever grows is a policy quietly repealing itself.

If a firewall change needs a peer review, the rule set that gates your identity provider needs one more. It decides who reaches every app at once, so one bad edit there costs far more than one bad firewall rule.

Report-only mode is your staging environment, so use it like one. No policy should enforce on day one. Entra's report-only modedefinitionA setting where the policy runs against real sign-ins and logs what it would have done. Nobody actually gets blocked. evaluates a policy against real sign-in traffic and logs what it would have done. That makes it a staging environment for access decisions, fed by production load.

Run new policies there for a full business cycle. A quiet weekend tells you very little. Month-end batch jobs, the quarterly finance crunch and that one legacy client that can't satisfy a device claim all need to appear in the would-be-blocked data before enforcement.

Then read the results like a test report. Would-be blocks against service accounts mean you've found automation that authenticates like a human. Would-be blocks against an executive's unmanaged tablet mean a conversation is cheaper now than a lockout later.

Enforce only when the projected impact matches the intended impact, because that match is your evidence the policy is correct. If the policy is already live, Microsoft suggests a report-only copy with your edits first. Compare the two side by side, and only then touch the real one.

Nobody has tested a conditional access policy that has never run in report-only mode. People have just taken it on faith.
ca-rollout-planexample output
# require-compliant-device: staged enforcement
policy: require-compliant-device  // v7, in git
phase 1: report-only · all users (Mac, iOS, Android excluded) · 30 days
phase 2: enforce · pilot ring (IT + volunteers)
phase 3: enforce · staged rings → all users
excluded: break-glass ×2 · alarmed on any use
rollback: revert to v6 · rehearsed · < 5 min
✓ lockout-rate alert armed before every phase

Engineer the blast radius before you need it. The worst CA failure is self-inflicted: a policy that locks out the administrators who could fix it. Roll out in rings, starting with a pilot group that includes the people who wrote the policy, then move through staged cohorts. A bad interaction then burns one team and the tenant stays up.

Keep at least two break-glass accountsdefinitionEmergency admin accounts excluded from normal access policies. You only use them when everything else has failed, and you watch them closely. excluded from every conditional access policy that blocks or restricts sign-in. Alarm them so loudly that any use triggers an immediate investigation, because an exclusion nobody watches is a backdoor. Microsoft now recommends a passkey (FIDO2) security key for these accounts, or certificate sign-in if you already run a PKI, since those satisfy its mandatory MFA rules.

Then rehearse the rollback. Know which version you revert to, who is authorized at 3 a.m., and how long propagation takes, and measure that last one rather than guessing.

Sign-in failure telemetry with alerting on lockout spikes closes the loop. With that in place you hear about a lockout from your alerts first, and the burning help desk just confirms it.

chapter 03

What to do now

What to do now, by who you are

Business ownerthis month
  • Ask your IT lead or provider who can change your sign-in rules, and whether each change is recorded and reviewed. They should be able to answer in a minute.
  • Ask for the list of people left out of your MFA policy, with a reason and an end date for each. A long list with no reasons is a gap.
  • Ask when the emergency admin accounts were last tested. Microsoft says to check them at least every 90 days.
IT and identity adminsthis week
  • Export every policy through Microsoft Graph into a repository and commit it. That first commit is your known-good version.
  • List every exclusion and give each one an owner and an expiry. Remove the ones nobody claims, in a change window.
  • Put new policies in report-only first. Before you edit an enforced one, copy it to report-only with the change and compare.
  • Check that at least two emergency access accounts exist, are cloud-only and sit outside every blocking policy.
Security teamthis week
  • Alert on any sign-in by an emergency access account. Microsoft's guidance is an alert on every use, then a review of what was done.
  • Alert on Update Conditional Access policy events in the audit log. Send that log somewhere that keeps it longer than 30 days.
  • Review sign-ins where a policy shows Not applied because the user was excluded. Those are the sign-ins your rules never checked.
chapter 04

Harden so the next one hurts less

Make the next policy change boring

  1. 01
    Export on a schedule and diff it

    Run a nightly export of every policy through Graph and compare it with what's in git. Any difference means someone changed the live tenant by hand, and you find out the next morning instead of during the next incident.

  2. 02
    Give every exclusion an expiry

    Put exclusions in named groups, with an owner and an end date written down in the repository. When the date passes, the review flags it and someone has to renew it on purpose or let it go.

  3. 03
    Use phishing-resistant keys for break-glass

    Register a FIDO2 security key, or certificate sign-in, for the emergency accounts, and make it different from what your normal admins use. Store the keys in separate secure places that more than one admin can reach.

  4. 04
    Test the emergency accounts

    Sign in with each emergency account at least every 90 days and check the alert fires. Tell the monitoring team first, so the drill doesn't start a real incident.

  5. 05
    Keep logs longer than 30 days

    Send the Entra sign-in and audit logs to Log Analytics, a storage account or your SIEM. Incident reviews often start months after the change that caused them.

  6. 06
    Rehearse the rollback

    Time how long it takes to revert to the previous version and for the change to reach the whole tenant. Write the steps down where the on-call person can find them at 3 a.m.

  7. 07
    Write a contingency policy in advance

    Microsoft recommends contingency policies you can switch on during an outage to restore access for critical users. They're far easier to write calmly in advance than in the middle of a lockout.

2+emergency access accounts Microsoft recommends you keep
90 dayslongest gap Microsoft advises between break-glass tests
30 dayshow long the Entra audit log keeps policy changes by default
60–90 minhow long an issued token keeps working in apps without continuous access evaluation
before

Before: rules edited by hand on the live tenant

An admin clicks a change straight into production. Nobody reviews it, the history fades after the audit log's default window, and there's no tested way back.

Before: rules edited by hand on the live tenant An admin clicks a change straight into production. Nobody reviews it, the history fades after the audit log's default window, and there's no tested way back. 01 · PEOPLE 02 · ENTRA 03 · USERS clicks a change applies at once enforced for all Admin portal session Entra admin center Live CA policies no review, no copy Every sign-in © Cohash · cohash.com
01 · PEOPLE02 · ENTRA03 · USERS Admin: portal session Admin portal session Entra admin center Entra admincenter Live CA policies: no review, no copy Live CApolicies no review, no copy Every sign-in Every sign-in clicks a change enforced for all © Cohash · cohash.com
after

After: policies shipped through review and rings

Changes go through git and review, then report-only and rings. Sign-in and audit logs feed alerts, and the last good version is one revert away.

After: policies shipped through review and rings Changes go through git and review, then report-only and rings. Sign-in and audit logs feed alerts, and the last good version is one revert away. 01 · CHANGE 02 · DEPLOY 03 · ENTRA 04 · WATCH diff approved deploys logs alarm on any use revert on a spike Git repository policy files Pull request review Deploy pipeline Microsoft Graph CA policies report-only, then rings Break-glass accounts excluded, alarmed Log store and alerts sign-in and audit logs © Cohash · cohash.com
01 · CHANGE02 · DEPLOY03 · ENTRA04 · WATCH Git repository: policy files Git repository policy files Pull request review Pull requestreview Deploy pipeline: Microsoft Graph Deploy pipeline Microsoft Graph CA policies: report-only, then rings CA policies report-only, thenrings Break-glass accounts: excluded, alarmed Break-glassaccounts excluded, alarmed Log store and alerts: sign-in and audit logs Log store and alerts sign-in and audit logs approved deploys logs alarm on any use revert on a spike © Cohash · cohash.com
chapter 05

If an account is compromised

If an account is compromised

Sometimes the gap is found the hard way: a sign-in that should have hit MFA didn't, and someone else used the account. Work through these phases in order. Fixing the policy is part of the response, so the same door doesn't stay open.

  1. 01Containfirst hour
    • Disable the account and select Revoke sessions in the Entra admin center, or run Revoke-MgUserSignInSession. The attacker can't get new tokens after that.
    • Exchange, SharePoint and Teams usually drop the session within minutes. Other apps can keep working until their access token expires, typically an hour or a little more, so watch the account through that window.
    • If the account syncs from on-premises Active Directory, disable it there too and reset the password twice, as Microsoft advises.
  2. 02Investigatefirst day
    • Open the attacker's sign-ins in the Entra sign-in logs and read the Conditional Access tab. It shows which policies applied, which were Not applied, and why.
    • Filter the audit log to Conditional Access and read recent changes. An exclusion added shortly before the break-in is a strong lead.
    • Check whether the emergency access accounts signed in. Any use nobody can explain is part of the incident.
  3. 03Close the gapfirst day
    • Remove or narrow the exclusion that let the sign-in through, and put the fix in git the same day. An emergency edit that never reaches the repository is the next drift.
    • If you skip report-only for an urgent fix, keep the lockout alerts on screen and the rollback ready.
  4. 04Remove and recoverdays 1 to 3
    • Remove any sign-in methods the attacker registered, and look for mailbox forwarding or deletion rules they set up.
    • Go through the apps this account has consented to and remove anything the user doesn't recognise. An app left behind can give the attacker a way back in.
    • Re-enable the account with a new password and a phishing-resistant method once you're sure the attacker is out.
  5. 05Report and learnas required
    • If personal data may have been read, check what you owe customers, regulators and your cyber insurer. Some deadlines are short, so ask early.
    • Write down which policy failed and why, then give every remaining exclusion an owner and an expiry. The next audit will ask for exactly that.
chapter 06

How this could play out

How this could play out

01 Phishedpassword 02 Excludedowner no end date 03 MFA policy Not applied 04 Client files
scenario 01High risk
A small firm with one forgotten exclusion
the setup
A 25-person accounting firm runs on Microsoft 365. Months ago the owner was taken out of the MFA policy while travelling with a broken phone, and nobody put them back.
what happens
The owner gets an invoice email, clicks through and types their password into a fake login page. The attacker signs in from abroad. The MFA policy shows Not applied, and the client tax files in OneDrive are open to them.
what to do
Remove the exclusion, revoke the owner's sessions and reset the password. Then ask the IT provider for every exclusion, each with a reason and an end date.
01 Untestedpolicy 02 All usersat once 03 Adminslocked out 04 Break-gla…sign-in 05 Revertlastversion
scenario 02Medium risk
A mid-size company that enforced on day one
the setup
A logistics company with a few hundred staff switches a compliant-device policy on for all users straight away. It never ran in report-only mode.
what happens
The warehouse scanners' service accounts and finance's month-end batch job fail together, and two admins on personal laptops are locked out too. The help desk queue fills up before lunch.
what to do
Sign in with a break-glass account and switch the policy back to report-only. Then export the policies to git, run report-only for a full business cycle and roll out by rings.
01 Stolen adminsession 02 Adds anexclusion 03 Policy-changealert 04 Redeploy fromgit
scenario 03High risk
An enterprise where an attacker edits the policy
the setup
A manufacturer keeps its conditional access policies in git and deploys them through a pipeline. Security alerts on every policy change made outside that pipeline.
what happens
An attacker with a stolen admin session adds their own account to a policy exclusion. The audit log event fires an alert, and the nightly export shows the live tenant no longer matches the repository.
what to do
Revoke the admin's sessions, redeploy the policy from git and review every sign-in the exclusion let through. Then move standing admin rights to time-limited, approved activation.

Many teams can start on their own by exporting the policies and listing the exclusions. If you'd rather have help, Cohash's identity practice runs the same review, and our IAM assessment ends in a ranked, costed roadmap.

key takeaways

What to take from this

  1. 01

    Keep conditional access policies in version control and peer-review the changes. Incident questions then turn into plain git queries.

  2. 02

    Leave it in report-only for a full business cycle. Don't enforce until the projected impact matches what you intended.

  3. 03

    Engineer the blast radius before the bad deploy. That means ring rollouts and alarmed break-glass exclusions, plus a rehearsed rollback.

  4. 04

    Treat every exclusion as temporary. Give it an owner and an end date, and alarm the break-glass accounts so any use gets looked at.

fact-checked October 2026 against vendor and official documentation · where to go next
  1. IAM practice
  2. Book a 30-minute working session with a senior engineer
01Is report-only mode safe to turn on?

Yes. It doesn't block anyone or prompt for MFA, it only logs what would have happened. One catch: a report-only policy that requires a compliant device can still make Mac, iPhone and Android users pick a device certificate. Leave those platforms out of report-only device policies and staff won't get confused.

02Why would we keep admin accounts that skip our security rules?

Because a bad policy or an outage can lock out every normal admin, and someone still has to get in to fix it. Microsoft recommends at least two of these emergency accounts. They sit outside blocking policies, but they're protected with a security key, alarmed on every sign-in and tested at least every 90 days.

next step

Tell us what you're running. We'll tell you what we'd do first.

A 30-minute working session with a senior engineer. No slides.

useful to bring
  • The platform and the version you're on
  • Where you need to get to, and by when
  • What's custom: rules, plugins, integrations
  • Any audit finding or deadline driving it