Platform teams rarely burn out because a policy blocked something once. They burn out because every exception becomes a custom negotiation, nobody agrees on the path forward, and temporary carve-outs never leave. A sane workflow gives engineers a real escape hatch while keeping governance trustworthy.
Why exception workflows exist
Good platform governance is not about winning every argument. It is about making the safe path normal, making the risky path visible, and making the temporary path reversible.
That is where exception workflows come in. They are not a loophole for avoiding standards. They are a control for handling real-world edge cases such as legacy workloads on a retirement plan, platform features that have not reached a region yet, or situations where the control intent is met through another method.
The workflow matters because the technical object is only half the story. The rest is ownership, business context, evidence, approval, timeboxing, and a review loop that actually removes old decisions instead of memorializing them forever.
The four controls people usually mix together
Azure gives you several ways to avoid or soften policy enforcement, but they are not interchangeable. Pick the wrong one, and you either hide risk or create extra admin noise.
Control | Best use | Where it lives | What it does | Main risk |
notScopes | Known carve-out at assignment time | Policy assignment | Excludes child scopes or resources from evaluation | Can hide broad gaps if used as a dumping ground |
DoNotEnforce | Safe rollout and testing | Policy assignment | Evaluates without enforcing the effect during create or update | Teams treat test mode as permanent mode |
Exemption: Waiver | Temporary accepted non-compliance | Policy exemption object | Accepts the risk for a defined scope and assignment | Becomes permanent if nobody owns expiry |
Exemption: Mitigated | Intent met another way | Policy exemption object | Documents that the control objective is satisfied through another measure | Weak evidence turns this into wishful thinking |
Why this distinction matters: excluded scopes are part of the assignment design. Exemptions are explicit exceptions to an assignment. DoNotEnforce is useful for safe rollout, but it is not a substitute for a reviewable exception process.
The opinionated blueprint
Here is the version that keeps work moving without creating policy archaeology six months later.

Figure 1. A sane workflow moves from intake to exit. The review step is what makes the workflow trustworthy.
1) Intake with evidence, not vibes
Start with a request form or ticket that forces the requester to name the policy assignment, scope, affected service, business driver, and target timeline. If they cannot say what they are asking to bypass, they are not ready for an exception.
Make the form ask one painful question: what happens if this is not approved? That separates true delivery blockers from convenience requests.
2) Triage the control choice before you approve anything
The fastest win is stopping teams from using exemptions as the default answer. Sometimes the better move is to narrow the assignment, add a notScope, or switch the rollout to DoNotEnforce while you validate impact. Use exemptions when the assignment is right but a specific case still needs a temporary or alternate path.
This is also where you decide whether the request is a Waiver or Mitigated case. Waiver means accepted non-compliance for now. Mitigated means the control intent is already satisfied through another method and you can prove it.
3) Keep scope narrow and make ownership obvious
Approve at the smallest scope that solves the problem. Do not exempt an entire subscription because one workload is blocked inside one resource group. Name both a business owner and a technical owner. One owns the risk. The other owns the implementation and cleanup.
If you cannot find those owners, stop. Missing ownership is usually a governance smell, not a paperwork issue.
4) Timebox the exception on day one
Waivers should have an expiration unless there is a very strong reason not to. Also set a review cadence before expiry. Expired exceptions should not surprise anyone.
Azure preserves the exemption object for record keeping after expiration, but the exemption is no longer honored. That is useful for audit history, but only if your reporting catches it.
5) Implement it as code and attach the change record
Create the exemption through your approved automation path instead of portal-only clicks. That keeps the request traceable, reviewable, and repeatable across environments. Record the change ticket, approver, and evidence links in metadata so the next reviewer is not starting blind.
If the policy assignment targets an initiative, be precise about whether the exemption applies to the whole initiative or only selected policy definition reference IDs.
6) Review, remove, or redesign the platform path
Every review should end with one of three outcomes: remove the exception, renew it with fresh evidence, or fix the platform so the exception is no longer needed. That last one matters most because repeated exemptions often reveal where the paved road is incomplete.
If the same request appears three times in a quarter, it probably belongs in your platform backlog, not your exception backlog.
The minimum fields every exemption should carry
This is the boring part that saves everyone later. Put these fields in your request form, your repo metadata, or both.
Field | Why it matters | Operator note |
Request ID | Connects the exemption to an intake or change record. | No orphaned exemptions. |
Policy assignment ID | Shows exactly which assignment is being bypassed. | Never approve against a vague policy name alone. |
Scope | Limits blast radius. | Default to the narrowest workable scope. |
Category | Separates Waiver from Mitigated. | The approval and evidence bar may differ. |
Business justification | Explains why the exception exists. | Keep it specific enough that a reviewer can challenge it. |
Compensating controls or evidence | Proves alternate protection for mitigated cases. | Screenshots are fine. Better is a durable evidence link. |
Business owner | Owns the risk acceptance. | This should not be a generic team mailbox. |
Technical owner | Owns implementation and cleanup. | Tie it to a real platform or service owner. |
Expiration and review date | Prevents silent permanence. | Review before expiry, not after. |
Exit criteria | Defines what must happen to remove it. | Retire app, redesign landing zone, fix dependency, and so on. |
Six operator rules that keep the system sane
1. No owner, no exemption A request without named business and technical owners should stop at triage. | 2. Scope narrow or do not approve Fix one workload, not an entire hierarchy, unless the whole hierarchy is the real problem. |
3. Waivers should expire Permanent waivers need senior scrutiny because they usually signal a standard that is not landing. | 4. Mitigated means evidence If the control intent is met another way, write down how and where that evidence lives. |
5. Treat exceptions as code Portal-only exceptions create drift because they are hard to review, compare, and reapply cleanly. | 6. Repeated requests are platform feedback When the same request keeps coming back, improve the paved road instead of normalizing the detour. |
A practical first 30 days
If your current state is messy, do not start by designing the perfect form. Start by getting control of the backlog you already have.
Week | Focus | What to do | Success signal |
1 | Inventory | List every active exemption, notScope, and long-running DoNotEnforce assignment you can find. | You know the actual backlog. |
2 | Classify | Mark each item as design choice, temporary waiver, mitigated case, or cleanup candidate. | The pile starts to make sense. |
3 | Standardize | Set default durations, approvers, evidence fields, and review cadence. | New requests stop improvising the workflow. |
4 | Automate reviews | Publish a monthly or biweekly review pack with owner, expiry, and exit criteria. | Old decisions become visible and actionable. |
Three common patterns and the better answer
Scenario | Bad habit | Better answer |
Legacy workload due for retirement in 90 days | Approve an endless waiver because cleanup is inconvenient. | Use a time-boxed Waiver tied to the retirement milestone and review it before the date slips. |
New control rolling out across a broad estate | Issue dozens of one-off exemptions while the platform team learns impact. | Use DoNotEnforce during safe rollout, then convert only true edge cases into exceptions. |
Control met another way for a single workload | Call it mitigated without proof. | Use a Mitigated exemption only when evidence is recorded and easy for a reviewer to validate. |
Bottom line
The healthiest exception workflow is not the one with the nicest form. It is the one that keeps the paved road strong while giving real projects a controlled, reviewable way around a short-term blocker.
That means clear control selection, narrow scope, named owners, evidence, expiration, and a review loop that removes old decisions. Do those well and platform teams stay credible. Skip them and you end up with policy debt disguised as flexibility.