The policies are enabled. The rings are on. From here almost everyone stops, and stopping is the mistake that turns a good deployment into a decaying one. A Conditional Access framework is not a project you finish. It is a system you operate, and the day after you enable the last ring is the first day of the part that actually determines whether the tenant stays secure. This is the article about that part, and it is the one that separates a baseline that stays trustworthy from a folder of policies that were correct once.
The reason this matters is that a Conditional Access deployment decays in ways you cannot see from the policy list. Exclusion groups accumulate members. Report-only policies sit forgotten. Someone edits a policy in the portal at two in the morning during an incident and never reverts it. Break-glass accounts drift out of working order precisely because nobody ever uses them. None of that shows up as an alert. All of it shows up eventually as a breach or an outage. The operating model exists to make the invisible decay visible on a schedule, before it costs you.
Exclusions are where the framework leaks
Every exception you granted is a small hole you opened on purpose, and holes opened on purpose have a way of staying open long after the purpose is gone. The framework’s structure helps here, because every policy has its own dedicated exclusion group and no group is shared between policies, which means an exclusion means exactly one thing and its blast radius is knowable. But structure is not governance. Governance is the recurring act of looking.
So every exclusion group gets a named owner and a quarterly access review, and the review asks one question of every member: why is this account still here. An exclusion that was justified for a migration six months ago and never removed is not an exclusion anymore. It is an unmonitored bypass, and it is the exact shape of the thing an attacker looks for. The reviews are on the calendar, not left to when someone remembers, because the entire failure mode is that nobody remembers. Alongside the reviews, membership changes on these groups are alerted, and the highest priority alert in the tenant is a change to the exclusion group on the global MFA policy, because adding an account there removes its second factor, and a silent addition to that group is either a mistake you need to catch in minutes or an attack you need to catch in minutes. There is no version of that change that should happen unwatched.
Break-glass is a fire extinguisher, and you test it
The break-glass accounts are excluded from everything, which is what makes them the way back in when a policy change locks everyone out, and it is also what makes them the most dangerous accounts in the tenant if they are neglected. They are the one door with no lock on it, and a door with no lock only helps you if it still opens and if you would notice someone else using it.
So they get tested quarterly, on the calendar, as a deliberate act. You sign in with each one, confirm it still reaches the portal, confirm its credential still works, and confirm the sign-in alert on it actually fired. That last check is the one people skip and the one that matters most, because a break-glass account whose sign-in does not raise an alarm is worse than not having one. It is an unwatched master key. The whole value of a break-glass account is that it is there when you need it and loud when anyone uses it, and neither of those properties survives being assumed rather than verified. A framework that ships the account and never tests it has shipped a comforting idea, not a control.
Report-only is where policies go to be forgotten
Report-only is essential during rollout and corrosive afterward. A policy left in report-only is doing nothing while looking like it is doing something, and that gap between appearance and reality is exactly the sort of thing that gets a tenant breached with the security team believing it was covered. The framework’s habit is a monthly review of everything still in report-only, and every one of those policies gets a recorded decision: enable it because it has proven itself, extend it with a reason and a date, or remove it because it is never going to enforce and pretending otherwise is just clutter. Nothing stays in report-only without a dated reason attached. The moment a policy can sit in that state indefinitely with no one accountable for moving it, you have grown shelfware inside your own security posture, and shelfware that looks like a control is worse than no control because it stops you looking for the real one.
Watching the right things
Monitoring a Conditional Access deployment is less about volume and more about watching the few signals that mean something. Sign-in failures grouped by policy, reviewed weekly, tell you whether a policy is biting something it should not, and a spike on the foundation blocks is usually good news, attack traffic finding a closed door, rather than a problem. Password-spray telemetry deserves its own attention, because Conditional Access never sees a failed first factor, so the count of authentication failures per client application is your early warning for a spray campaign that the CA layer will only meet after the attacker already has a valid password. On a tenant running the agent policies, the agent inventory gets reconciled against the approved list on a schedule, because default-deny for agents is only as good as your knowledge of which agents are supposed to exist.
And then there is drift, which is the quiet one. Someone will edit a policy in the portal, because the portal makes it easy and makes the history invisible, and the edit will not match the framework you deployed. So the framework ships its validator as an operational tool, not just a release gate. You run it monthly against an export of the live tenant, and it catches the policy whose scope was emptied, the exclusion group that was swapped, the break-glass exclusion that was quietly removed. The same checks that keep the repository honest keep the tenant honest, and they catch the manual change that no alert would have told you about.
Change control, and the discipline that makes reverting possible
The portal makes bad changes easy and makes their history disappear, which is a dangerous combination for the control plane of your access model. So changes to Conditional Access go through a small, unglamorous ritual: export the current state, make the change, run the validator, record what you did. The export is the part that turns a mistake into an inconvenience instead of a crisis, because reverting becomes a restore of a known-good state rather than an attempt to remember what a policy looked like last Tuesday. And when you do revert, you set the policy back to report-only rather than deleting it, because the report-only history is the evidence you will want when you work out why the change was wrong in the first place.
The direction this points, and the hardening worth planning toward, is protecting the framework from privileged change itself. A protected action with a phishing-resistant authentication context on Conditional Access policy modification means that altering the access model requires the strongest credential the tenant has, which closes the gap where an attacker who has compromised an admin session simply deletes the policies that would have stopped them. That is the endgame: a framework that not only enforces access but guards its own definition.
None of this is exciting, and that is the point. Day-two operations on a Conditional Access framework is the deliberate practice of keeping something boring, because boring is what secure looks like when it is working. The policies were the easy part. The reviews on the calendar, the break-glass test nobody wants to run, the monthly drift check against a tenant that keeps trying to drift, the change ritual you follow even when you are in a hurry, that is the part that is still protecting the customer a year from now. A baseline is a snapshot. An operating model is what keeps the snapshot true.
Repo: github.com/VirtualCaffeineIO/vcio-ca-framework
Conditional Access
‹ Previous: [CA 4.3] Day One: TAP, Autopilot, and Protecting the Bootstrap




