A gate exception in Safeguard is a request to set aside one Block for one finding: the developer selects the policy and the finding, writes a business justification, sets an expiration date and submits it, approvers are notified and decide, and Safeguard records an audit trail. Exceptions expire automatically. What Safeguard cannot decide for you is how long they should last, who is allowed to grant them and how often someone looks back at them, and those three choices decide whether your gates stay honest.
This post is about that design work. It assumes you already have policies linked to gates. If you do not, start with From plain English security policy to release gates in Safeguard, which covers writing policies, the Block, Warn and Notify Actions and wiring a gate into CI. Here we stay on the exception process: when to grant one, how to scope it, how to set expiry, who owns each step, what the audit record holds and how to review the lot without it becoming a monthly chore nobody does.
Key takeaways
- Policies and gates (GA). Each policy has one Action: Block, Warn or Notify. Approval happens through the exception workflow.
- Gate exceptions (GA, part of Policies and gates). A request names the policy and the finding, carries a business justification and an expiration date, and goes to approvers. The workflow records an audit trail.
- Guardrail exceptions (GA, part of Guardrails and enforcement). The Guardrails docs say an approver with the right role grants an exception for a specific asset for a specific duration, it appears in the audit log and it expires automatically. Emergency breakglass exceptions need two-person approval and alert the security channel.
- Unwaivable rules. In the policy YAML a rule can carry an
exceptionblock withallowed: falseand a list ofapprovers, so some rules can never be set aside. - Mitigations and risk acceptance (GA, part of vulnerability management). A finding-level record with a type, justification, approver, optional evidence, scope and, for risk acceptances, an expiry date. Safeguard notifies 14 days and 7 days before expiry and on the day.
- Audit (GA). An append-only audit log of who, what, when, where and why, exception history in compliance reports, and events for granted and expired exceptions.
- CSAF and VEX upload (GA) is the better tool when a product is not affected at all. An exception says "affected, accepted for now"; a VEX statement says "not affected, and here is why".
- What you own: the expiry rules, the separation between requester and approver, the review cadence and what happens when an exception is renewed for the third time.
Why the exception process decides whether a gate survives
Every team that turns a gate to Block meets the same day. A release is ready, a finding blocks it, the fix is not ready, and somebody senior says ship it. What happens next decides whether the gate is a control or a decoration.
If there is no designed path, people make one. The common ones are familiar:
- The skip variable. A CI variable that skips the scan "just for this release", which is still set six months later.
- The policy downgrade. Someone changes a policy from Block to Warn to get one release out. That relaxes the rule for every gate and every pipeline that links it.
- The admin bypass. A repository administrator merges past a required check. Safeguard never sees it, and the only record is in your source control audit log.
- The chat approval. "Approved, go ahead" in a channel. No scope, no expiry, no link to the finding.
- The forever waiver. An exception with an expiry date three years out, granted in a hurry and never looked at again.
Each of these has the same three defects. Nobody can say how long it lasts, nobody can say who owns it, and nobody can reconstruct it for an auditor. A designed exception process fixes exactly those three things, which is why this post is organised around expiry, ownership and audit.
There is a quieter reason to care too. Every exception granted against a policy is evidence that the policy, the remediation capacity or the release plan does not match reality. Tracked, that tells you which rules are wrong.
What the standards ask for
No major framework forbids exceptions. They assume you will have them and ask you to handle them on purpose.
NIST SP 800-218 (SSDF 1.1)
The Secure Software Development Framework mentions exceptions in several places:
- PO.1.2 asks you to identify and document all security requirements for the organisation's software development. Its Example 7 is direct: establish and follow processes for handling requirement exception requests, including periodic reviews of all approved exceptions.
- PO.1.3, which covers requirements for third-party software, has an example in the same spirit: address risk when acquired third-party components do not meet your security requirements, including periodic reviews of all approved exceptions to requirements. Most gate exceptions are about open source dependencies, so this one applies to you more often than its third-party label suggests.
- PO.4.1 asks you to define criteria for software security checks and track them through the lifecycle. Example 5 asks you to record security check approvals, rejections and exception requests as part of the workflow and tracking system.
- PW.1.2 asks you to track and maintain the software's security requirements, risks and design decisions. Its examples ask you to record the response to each risk, including the rationale for any approved exception, and to keep records of risk responses and approved exceptions for auditing and maintenance.
Read together: have a process, record every decision with its rationale, and review approved exceptions periodically. Most programmes skip the review.
NIST Cybersecurity Framework 2.0
CSF 2.0 gives exceptions their own outcome. ID.RA-07 reads: changes and exceptions are managed, assessed for risk impact, recorded and tracked. Next to it, ID.RA-06 says risk responses are chosen, prioritised, planned, tracked and communicated, and GV.RR-02 says roles, responsibilities and authorities related to cybersecurity risk management are established, communicated, understood and enforced. That last one is the ownership half of this post: who may grant an exception is a defined authority, not whoever is awake.
NIST SP 800-53 Rev. 5
If you work to 800-53 or a framework derived from it, three controls frame exceptions:
- RA-7 Risk Response asks you to respond to findings from assessments, monitoring and audits in line with your organisational risk tolerance. Accepting a finding for a time is one such response, and it has to fit a stated tolerance.
- CA-5 Plan of Action and Milestones asks you to document planned remediation actions to correct weaknesses and reduce known vulnerabilities, and to keep that plan updated from assessments and continuous monitoring. An exception with a fix date is, in substance, a plan of action item.
- PM-4 Plan of Action and Milestones Process asks for a process that keeps those plans developed, maintained and reported, including for supply chain risk management.
AU-6 Audit Record Review asks you to review and analyse audit records for unusual activity, which is how you notice an approver who grants everything.
OWASP Top 10 CI/CD Security Risks
CICD-SEC-1, Insufficient Flow Control Mechanisms, describes attackers abusing branch protection exclusions to push unreviewed code toward production, and recommends avoiding exclusions of users or branches from those rules. The bypass you build for emergencies is also an attack path. Keep it narrow, named and recorded.
CISA and known exploited vulnerabilities
CISA's Known Exploited Vulnerabilities catalog lists vulnerabilities with evidence of active exploitation. BOD 22-01, which once set fixed KEV deadlines for federal agencies, is revoked; CISA's page says it is superseded by BOD 26-04, which prioritises security updates based on risk. Either way, a known exploited vulnerability in production is the strongest candidate for a rule you never waive.
The standards side by side
| Requirement | What it asks for | What Safeguard provides | What you still own |
|---|---|---|---|
| SSDF PO.1.2, Example 7 | An exception process with periodic review of approved exceptions | Exception requests with justification, expiry and approvers (GA); exception history in compliance reports | The review cadence and who runs it |
| SSDF PO.4.1, Example 5 | Record approvals, rejections and exception requests in the workflow | The exception workflow records an audit trail; the audit log records state changes | Linking each exception to a ticket or pull request |
| SSDF PW.1.2 | Record the rationale for each approved exception and keep records | Business justification on the request; justification and evidence fields on mitigations | Writing justifications an auditor can follow |
| CSF 2.0 ID.RA-07 | Exceptions managed, assessed for risk impact, recorded and tracked | Expiry, automatic lapse, statuses, dashboards for exceptions open and expiring | The risk assessment behind each decision |
| CSF 2.0 GV.RR-02 | Defined roles and authorities | Built-in roles that separate requesting from managing exceptions; custom roles | Who holds which role, and separation of duties |
| SP 800-53 CA-5 and PM-4 | Plans of action for known weaknesses, kept current | Expiry dates and expiry notifications as review points | The fix plan and milestones themselves |
| SP 800-53 AU-6 | Review audit records for unusual activity | Filterable, exportable audit log | Actually reviewing it |
| OWASP CICD-SEC-1 | No unreviewed paths to production, no blanket exclusions | Exceptions scoped to a policy and finding, or an asset and duration; two-person breakglass | Branch protection and admin bypass settings in your source control |
How Safeguard handles exceptions
Safeguard has more than one place where "accept this for now" lives. They look similar, they answer different questions, and mixing them up is the root of most messy exception registers.
1. Gate exceptions on the Policies & Gates page
The Policies & Gates docs describe gates as checkpoints that enforce policies, block deployments when policies fail, integrate with CI/CD pipelines and require approvals for exceptions. The request flow is five steps:
- Click Request Exception.
- Select the policy and the finding.
- Provide a business justification.
- Set an expiration date.
- Submit for approval.
The workflow behind it is also five steps: the developer creates the request, approvers are notified, an approver reviews and decides, the exception is granted or denied, and an audit trail is recorded. The compliance reports on the same page list compliance status by policy, exception history, violation trends and audit documentation.
2. Guardrail exceptions and breakglass
The Guardrails & Enforcement docs describe the same idea for guardrails, the policy-as-code rules Safeguard enforces on your behalf. Every blocking guardrail supports time-boxed exceptions:
- An approver with the right role grants an exception for a specific asset for a specific duration.
- Exceptions appear in the audit log and expire automatically.
- Emergency breakglass exceptions require two-person approval and trigger alerts in the security channel.
The same page shows how a rule can opt out of exceptions entirely. A rule in the policy YAML can carry an exception block:
rules:
- id: no-known-exploited-critical
description: Block production images containing KEV-listed CVEs.
condition: |
any(
vulnerabilities,
severity == "critical" AND kev == true
)
effect: BLOCK
exception:
allowed: false
approvers: [ "security-leads@company.com" ]
That excerpt is from the Guardrails docs, trimmed to one rule. allowed: false makes the rule unwaivable. approvers names who may approve exceptions for rules where they are allowed. We have not run it; treat it as the shape the docs show, and check the current docs before you copy it.
3. Risk acceptance on the Mitigations tab
Gate exceptions live with the gate; mitigations live with the vulnerability. The Mitigations docs describe a tab on each project for applied fixes, risk acceptances and false positives. You create one from the Vulnerabilities tab through the row menu, Add Mitigation:
| Field | What it holds | Required |
|---|---|---|
| Type | Risk Acceptance, False Positive, Workaround or N/A | Yes |
| Justification | The reason for the mitigation | Yes |
| Expiration Date | When to review or expire (Risk Acceptance only) | No |
| Approved By | Who approved it | Yes |
| Evidence | Supporting documentation | No |
| Scope | This version only, or all versions | Yes |
A mitigation has a status: Active, Expired (past its date, needs review), Revoked (manually cancelled, with a reason) or Superseded (replaced by a fix or a new mitigation). For risk acceptances the docs offer expiry presets of 30, 90, 180 and 365 days, or a custom date, and Safeguard notifies you 14 days before expiry, 7 days before and on the day. The review flow is to filter the tab by Status: Expired, then for each one extend it if still valid, revoke it if no longer applicable, or upgrade to a fix if one is available. All mitigation actions are logged: who created it, when and why, and who changed it and what changed.
The docs also describe Mitigation Policies under Settings, which auto-apply mitigations: CVE exemptions, package exemptions, a severity threshold that auto-accepts below a level, and development-only auto-acceptance, scoped to an organisation or a project. Treat these with care. A mitigation policy is a standing exception with no expiry of its own. It belongs in the same review as policy changes, not in the same bucket as a 30-day risk acceptance.
4. VEX: when it is not an exception at all
If the vulnerable component is present but your product is not affected, for example because the vulnerable function is never called or the feature is compiled out, you do not need an exception. You need a statement that the product is not affected and why. Safeguard's CSAF and VEX upload (GA) is built for that, and the statement travels with your SBOM to customers. We cover it in Ingest and share VEX and CSAF in Safeguard.
"Not affected" is a technical claim you can be asked to prove; "affected, accepted until 30 November" is a risk decision someone owned. Do not record one as the other.
Which record to use
| Situation | Use | Why |
|---|---|---|
| A Block policy fails on a release, the fix is planned, and you accept the risk until then | Gate exception | Scoped to the policy and finding, with expiry and approver, on the gate that blocked |
| A blocking guardrail stops one asset, and you accept it for a defined window | Guardrail exception | Scoped to the asset and duration, recorded in the audit log |
| Production is down and approvers are unreachable | Breakglass exception | Two-person approval and an alert to the security channel |
| A vulnerability is real and present, you accept it for a time, and want the decision visible on the project | Mitigation, type Risk Acceptance, with expiry | Lives with the finding, has statuses and expiry notifications |
| A compensating control is in place | Mitigation, type Workaround, with evidence | Records the control rather than pretending the risk is accepted bare |
| The product is not affected | VEX statement | A claim with a justification your customers can read |
| The same exception keeps coming back for many projects | Change the policy, not the exceptions | A rule that needs constant waivers is the wrong rule |
| A fixed version exists | Fix it | Autonomous remediation (GA, ships switched off with every category on Manual) or a developer pull request |
Designing expiry
Expiry is the single most important property of an exception. An exception without a credible end date is a policy change nobody approved.
Tie expiry to the fix plan, not the calendar
"90 days" is the expiry most exceptions get, and it is wrong for most of them. Ask instead: what event ends this exception?
- A fixed version exists but upgrading is work. The exception ends when the upgrade ships. Set expiry to the planned release date plus a short buffer, often two to four weeks.
- Upstream has no fix yet. The exception ends when upstream releases, or when you choose another route. Set a review date, often 30 days, not a fix date you cannot know.
- A compensating control carries the risk. The exception ends when the control is no longer needed. Set a review date tied to the control's own review, and record the control as a Workaround mitigation with evidence.
- The component is being removed. The exception ends with the removal. Set expiry to the removal milestone.
The Mitigations presets (30, 90, 180, 365 days) are useful as review cycles. Use them as the maximum you allow for each class, not the value you pick by default.
A starting expiry policy
There is no standard table for this; here is one we would start from and then tune with data. Your risk tolerance, your sector rules and your contracts come first.
| Finding class | Maximum expiry | Renewal allowed | Who may approve |
|---|---|---|---|
| Known exploited, in production | Not waivable (allowed: false), or breakglass only | No | Two people, for breakglass only |
| Critical, reachable, internet facing | 14 days | Once, with a new justification | Security lead |
| Critical or high, fixed version exists | 30 days | Once | Security lead |
| Critical or high, no fix upstream | 30 day review, renewable | Yes, with evidence of what changed | Security lead |
| Medium and low | 90 days | Yes | Team lead, with security informed |
| License policy | Until the legal review closes, at most 90 days | Yes, with legal sign-off | Legal or open source office |
| Development-only assets | Use a scoped policy rather than exceptions | Not applicable | Security lead, as a policy change |
Two things to notice. First, the rows are about risk, not about the policy name. Use whatever the finding's severity, exploitation status and reachability say. If you need help reading those signals, Prioritise vulnerabilities with reachability, EPSS and KEV in Safeguard walks through them. Second, the top row is a policy decision, not an exception decision. Make it once, in calm conditions, and encode it in the rule.
What happens at expiry
The Guardrails docs say exceptions expire automatically. The Webhooks & Events docs list a policy.exception_expired event for a time-boxed exception that expired. On the Mitigations side, an expired risk acceptance moves to the Expired status and shows up in the review filter.
Plan for the consequence. Once an exception lapses, it no longer covers the finding, so if the finding is still there you should expect the gate to fail on its next evaluation. The Policy outcomes docs say a policy is evaluated when it is linked to a gate and again after new assessment data arrives for the product. That means a lapsed exception can surface at an awkward moment, on whatever scan comes next. The fix is boring: use the 14 day and 7 day notifications as the trigger for the owner to either finish the fix or file a renewal with new evidence, and do not wait for the gate to tell you.
Renewal is a new decision
A renewal should never be a date edit. Treat it as a new request with a justification that says what changed, a different approver where your team is big enough, and escalation on the second renewal. Of the three Mitigations review outcomes (extend, revoke, upgrade to a fix), make extend the hardest to choose.
Designing ownership
An exception has at least four roles attached to it, and the most common failure is one person holding all four.
| Role | What they do | Who it should be |
|---|---|---|
| Requester | Opens the request, writes the justification, proposes the expiry | The developer or team that owns the asset |
| Approver | Decides, with authority to accept the risk | Security lead, or a named risk owner for the asset |
| Fix owner | Delivers the change that ends the exception | Usually the requester's team, named in the justification |
| Reviewer | Looks at all open and expired exceptions on a schedule | Security programme owner, not an approver of the same exceptions |
What the roles in Safeguard allow
The RBAC, Teams & Organizations docs describe built-in roles that map onto this separation:
- Developer (team scope): view findings on assigned assets, run auto-fix against them, request exceptions.
- Security Engineer (org or team scope): triage and remediate findings; cannot modify policy.
- Security Lead (org or team scope): manage policies, exceptions, workflows and integrations.
- Auditor (org scope): read-only access to all audit records, findings and compliance evidence.
- Owner and Admin (organisation): everything, with Admin excluding billing and tenant deletion.
- Viewer: read-only within scope.
Custom roles are composed from a permissions matrix and can carry restrictions, such as an environment or a maximum severity. The same docs say enterprise tenants can require re-authentication for sensitive actions, and name policy changes and approving exceptions as examples. Turn that on if it is available to you. An approval that needs a fresh login is a deliberate act.
One caveat from reading the docs: the Organization & User Management page describes a different, simpler set of roles (Tenant Admin, Manager, User and Viewer) and a permissions matrix in which Tenant Admin, Manager and User can all manage mitigations. Check which model your workspace shows before you design around either, and if Users can manage mitigations in your setup, decide whether a developer recording their own risk acceptance is acceptable for your programme. For most teams it is not, for anything above medium severity.
Rules that keep ownership clean
- The requester never approves. Not even for low severity, not even on a Friday.
- Approvers are named in advance. Use the
approverslist on rules where your policy YAML supports it, and keep the list short. - Every exception names a fix owner. If nobody will fix it, it is not an exception; it is a permanent risk acceptance and should be escalated as one.
- The reviewer is not the approver. Someone who did not grant the exceptions should read the register. That is what AU-6 style review means in practice.
- Approvals happen in Safeguard, not in chat. A message saying "approved" is not a record.
Designing scope
The narrower an exception, the less it can hide.
- One policy, one finding. The gate exception flow asks you to select both. Do not clear a whole gate for a release; you will clear findings you have never read.
- One asset, one duration, as the Guardrails docs describe. If ten services need the same exception, fix the policy.
- This version only, by default. The Mitigations form asks whether the record covers this version only or all versions. "All versions" means the next release, which may have a fix available, still carries the acceptance. Choose it only when you have a reason.
- No exceptions on rules marked unwaivable. Use
allowed: falsefor the handful of rules where the answer is always no.
Designing the justification
The justification is the part an auditor reads. Write it for someone who was not in the room, a year from now.
"Release deadline" is not a justification. A useful one answers five questions:
- What is accepted. The finding, the package and version, the asset and the environment.
- Why the risk is acceptable for now. Reachability, exposure, a compensating control, or why the fix is blocked.
- What ends it. The fix plan and its date, or the upstream event you are waiting for.
- Who fixes it. A team or person.
- Where the work is tracked. A ticket or pull request link.
Here is an illustrative justification in that shape. It is an example of the text you would write, not output from Safeguard:
Accepting: high severity finding in a transitive XML parser dependency,
payments-api, production.
Why acceptable now: vulnerable parser entry point is not called by our code
(reachability shows no path); service is internal only.
Ends when: upgrade of the parent library to the release that pulls the fixed
parser, planned for release 4.12 on 14 Nov.
Fix owner: payments platform team.
Tracking: ticket PAY-2291.
The audit log in the RBAC docs records a "why" for each state change, described as the linked ticket, pull request or policy exception where one is provided. Fill it. A ticket link turns an exception from a decision into a commitment someone can be held to.
Designing the audit trail
You do not have to build an audit trail for exceptions; Safeguard records one. You do have to know where it is, what it holds and how you will use it.
What gets recorded
- The exception workflow. The Policies & Gates docs say the workflow ends with an audit trail recorded, and the compliance reports include exception history, violation trends and audit documentation.
- Guardrail exceptions. The Guardrails docs say exceptions appear in the audit log, and that every guardrail decision is logged to the Safeguard audit stream and counted in an enforcement dashboard of allow, warn and block trends by policy, team and asset class.
- The audit log itself. The RBAC docs describe every state-changing action being recorded with who (user, service or workload identity), what (the action, with before and after where applicable), when (UTC and time zone), where (IP, session and client type) and why. They describe the log as append-only and cryptographically chained, retained for the period your tenancy allows: 90 days by default and configurable up to seven years for Enterprise tenants.
- Mitigations. Every mitigation action is logged with who, when and the justification or the change.
The Organization & User Management docs show where to read it: Settings › Audit Log, filter by user, action and date, and export.
Ninety days of audit log does not cover an annual audit. Configure longer retention where your tenancy allows it, or export the log on a schedule into your evidence store, before the first audit.
Events for your own systems
The Webhooks & Events docs list three events that matter here:
| Event | When it fires |
|---|---|
policy.violation | A BLOCK or WARN fired |
policy.exception_granted | An exception was approved |
policy.exception_expired | A time-boxed exception expired |
A fourth, findings.vulnerability.suppressed, fires when an exception is granted or a false positive is confirmed, and audit.action fires for any state-changing action in the audit log. The docs say you create a webhook subscription on the Webhooks page with the endpoint URL, the event types, a signing secret and an optional filter, that payloads are signed so you can verify them, and that there is no CLI command for this yet.
The two exception events are the useful ones for a programme. Send policy.exception_granted to the channel where your security team works, so every approval is seen by someone other than the approver. Send policy.exception_expired to the owning team, so the lapse arrives as a task, not as a surprise failed build.
Dashboards
The Analytics & Dashboards docs describe a Compliance dashboard at Home › Dashboards that includes exceptions open and expiring, next to framework readiness and evidence completeness. Put that tile in front of whoever runs the monthly review.
Step by step: an exception process you can run
This walkthrough uses only screens and fields that Safeguard's docs describe. Where the docs do not show a screen, we describe the outcome and leave the clicks to your workspace.
Before you start
- Policies are linked to gates, and policy outcomes are on for your workspace (the docs say Safeguard turns them on per workspace; no Outcome column on Policies › Gates means ask your Safeguard contact).
- You know which policies are set to Block. Warn and Notify already let the gate pass, so exceptions only matter for Block.
- Your expiry table and role assignments are written down.
1. Mark the rules you will never waive
Pick the few rules where the answer is always no, typically known exploited critical vulnerabilities in production. Where your policies are defined in YAML, add an exception block with allowed: false to those rules, as the Guardrails docs show. Everything else stays waivable through the normal flow.
2. Assign roles
Give developers a role that can request exceptions but not manage policies. Give approval authority to a small, named group with a role that can manage exceptions. Give your internal audit or GRC team a read-only auditor role. If your tenant supports re-authentication for approving exceptions, turn it on.
3. Route the events
On the Webhooks page, create a subscription for policy.exception_granted and policy.exception_expired, with your signing secret, pointing at the system your security team watches. If your team lives in a chat tool, route the subscription there so approvals are seen by more than the approver.
4. Request an exception when a Block lands
When a gate fails on a finding you are not going to fix before release, the asset owner opens the request:
- Click Request Exception.
- Select the policy and the finding that failed.
- Write the justification in the five-part shape above, with the ticket link.
- Set the expiration date from your expiry table, matched to the fix plan.
- Submit for approval.
5. Decide
The approver reviews the finding, the justification and the expiry against your table. Approve, deny, or send it back with a shorter expiry. The decision and the audit trail are recorded. If the request is for a rule marked unwaivable, there is nothing to approve; the answer is the fix or the breakglass path.
6. Record the risk on the finding where it helps
If the same accepted risk should be visible on the project's vulnerability list, add a mitigation from the Vulnerabilities tab with Add Mitigation: type Risk Acceptance (or Workaround if a compensating control carries it), the same justification, the approver in Approved By, evidence attached, scope set to this version only, and the same expiry date. Use one record type consistently per class of decision so your register does not double count.
7. Watch expiry
By the 7 day notification, the fix should be in review or a renewal filed with new evidence. The exceptions open and expiring tile is the security team's view of the same thing.
8. Review monthly
Once a month, the reviewer works through:
- Expired mitigations. On the Mitigations tab, filter by Status: Expired. Extend, revoke or upgrade to a fix for each.
- Exception history. From the Policies & Gates compliance reports, list exceptions granted in the month by policy and approver.
- Renewals. Any exception on its second renewal goes to escalation.
- Approver spread. If one approver grants nearly all exceptions, or never denies one, talk to them.
- Outliers. Any exception with an expiry beyond your table's maximum.
9. Report quarterly
Export the audit log for the quarter from Settings › Audit Log, plus the exception history report, into your evidence store. Write a short summary: exceptions granted, denied, expired, renewed and fixed, by policy. That summary is what an SSDF PO.1.2 periodic review or a CSF ID.RA-07 assessment looks for.
10. Change the rule when the data says so
If a policy produces most of your exceptions, the policy is wrong for your estate today, or the fixes need help from autonomous remediation. Narrow it, for example to reachable or known exploited findings, set it to Warn while you work down the backlog, or fund the remediation. Then record that decision as a policy change, with its own owner and date.
Breakglass, briefly
An exception accepts a known finding for a planned window. Breakglass is for production emergencies when normal approvers are unreachable. The Guardrails docs give you the Safeguard side: two-person approval and an alert to the security channel. The runbook is yours: name the two approvers in advance, prefer a short exception on the specific finding over anything wider, never downgrade the policy to ship one release, keep source control admin bypass for last (OWASP CICD-SEC-1 advises against exclusions from branch protection), and review within one business day.
Measuring whether the process works
You cannot manage what you only see during an audit. Five numbers tell you most of what you need, and Safeguard records the raw material for each.
| Metric | How to compute it | What a bad trend means |
|---|---|---|
| Override rate | Exceptions granted divided by gate failures, per policy per month | The rule and reality have drifted |
| Renewal rate | Exceptions renewed at least once, as a share of exceptions expired | Fix plans are not real, or capacity is short |
| Median exception age | Days from grant to fix or lapse | Expiry is being set by the calendar, not the fix |
| Expiring in 14 days | Count from the exceptions open and expiring view | A wave of failed builds is coming |
| Approver concentration | Share of approvals by the top approver | Separation of duties is weakening |
Gate failures come from the Outcome column and evaluation history on Policies › Gates; exceptions from the exception history report and the events. The Policy outcomes docs also say Safeguard's MCP server (GA) has read-only tools for gate outcomes, policy outcomes and evaluation history, when outcomes are on and your MCP access settings allow them, so you can ask an assistant which gates failed most last month without building a report.
How exceptions become compliance evidence
When an auditor asks how you handle exceptions to your secure development requirements, the answer should be a set of records, not a narrative:
- Requirement and process: the policy, its Action, its gates, the unwaivable rules, your expiry table and role assignments.
- Decisions: exception history and mitigation records with justification, approver, evidence and expiry.
- Review and trend: monthly notes, quarterly summaries with the audit log export, and override and renewal rates by policy.
The Compliance and GRC suite (GA) is where policy results and framework evidence come together; Continuous compliance in Safeguard shows how controls, evidence and tests connect. If you sell to the US federal market, the same records support the secure development attestation; Brief your CEO before signing the CISA secure software attestation explains what that signature covers and why accuracy matters.
What Safeguard does not do
- It does not choose your expiry or your risk tolerance. Safeguard records the date you set and enforces the lapse. Whether 30 days is right for a reachable high severity finding is your decision, and the docs do not prescribe one.
- It does not run your periodic review. Exception history, expiry notifications and dashboards are the inputs. SSDF's periodic review of approved exceptions still needs a person, a calendar entry and a written outcome.
- It does not see bypasses outside Safeguard. A CI variable that skips the scan, a policy edited from Block to Warn, or a repository administrator merging past a required check are visible only in your pipeline configuration, Safeguard's policy change history or your source control audit log. Close those paths in your own systems.
- It does not judge whether a justification is true. "Not reachable" in a justification is a claim. Check it against the finding's reachability data, and prefer a VEX statement if the product is genuinely not affected.
- The docs do not show an exception request from the CLI or CI. The documented request flow is in the Safeguard app. The CLI fails a build on a gate; it does not file or approve exceptions.
- The
/v1REST endpoints described on some docs pages are not available yet. Several pages used here, including Mitigations, Webhooks & Events and Analytics, carry a banner saying so. Use the app, the webhook subscription page and the exports, not API calls.
Common mistakes
- One exception for the whole gate. Clearing a gate for a release clears findings nobody has read. Scope every exception to one policy and one finding.
- Default expiry of 90 days. Use the fix plan to set the date, and the class maximum as a ceiling.
- Requester approves their own exception. Separate the roles in Safeguard and in your process.
- Downgrading a policy to ship one release. That changes the rule for every gate and every pipeline that links it. Use an exception.
- Using exceptions for not-affected findings. That hides good analysis behind a risk decision. Publish a VEX statement instead.
- "All versions" scope on a mitigation by habit. The next release may already carry a fix. Default to this version only.
- Audit log retention shorter than the audit window. Configure longer retention or export on a schedule.
- Renewing by editing the date. A renewal is a new request with new evidence and, ideally, a different approver.
FAQ
How do I request a policy exception in Safeguard?
On the Policies & Gates page, click Request Exception, select the policy and the finding, give a business justification, set an expiration date and submit it for approval. Approvers are notified, one reviews and decides, and the audit trail is recorded.
Do Safeguard gate exceptions expire automatically?
Yes. The Guardrails docs say exceptions expire automatically and appear in the audit log, and the Webhooks & Events docs list a policy.exception_expired event. For risk acceptances on the Mitigations tab, Safeguard notifies you 14 days and 7 days before expiry and on the day.
Can I stop certain policies from ever being waived?
Yes, where your policy is defined in YAML. The Guardrails docs show an exception block on a rule with allowed: false, which makes the rule unwaivable, and an approvers list for rules where exceptions are allowed.
Who can approve an exception in Safeguard?
The RBAC docs describe a Security Lead role that manages policies and exceptions, and a Developer role that can request exceptions but not manage them. Enterprise tenants can require re-authentication before approving an exception. Who holds the approver role, and whether the requester can ever approve, is your decision.
What is the difference between a gate exception and a risk acceptance mitigation?
A gate exception sets aside a Block for a specific policy and finding on a gate. A mitigation of type Risk Acceptance records the accepted risk on the vulnerability itself, with an approver, evidence, scope, status and expiry.
Should I use an exception or a VEX statement?
Use VEX when the product is not affected, for example because the vulnerable code is never called. Use an exception when the product is affected and you accept the risk for a defined time. One is a technical claim, the other a risk decision.
How long should a security exception last?
As long as the fix plan needs and no longer. A common pattern is 14 to 30 days for critical and high findings with a fix, a 30 day review when upstream has no fix, and up to 90 days for medium and low.
Exceptions buy time; they do not remove the vulnerable version. The section below is how Safeguard helps close the gap an exception covers, so the exception can lapse because the fix landed, including when upstream has not shipped one yet.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The CLI demo is a real session: ask the interactive terminal to fix the lodash CVE in a repository, and it reads the finding and advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, and pushes nothing. That is the move that lets an exception lapse on schedule: fix the finding behind it, push, and let the gate pass without a renewal.
Click through it at your own pace, or open it full screen.
The Claude demo connects Claude to Safeguard with OAuth and chooses which tools Claude can use; install Safeguard from Claude's connector directory to get there. With policy outcomes on, the read-only gate tools answer which gates failed and how often, which is the first half of an override rate for your monthly review.
Click through it at your own pace, or open it full screen.
To set this up on your own workspace, download Safeguard from safeguard.sh/download and read the Policies & Gates and Mitigations guides in the Safeguard docs.
Quick check
A developer asks to clear a whole gate for tomorrow's release because three findings block it. What should the approver do?
Decline the gate-wide request and ask for three exceptions, each naming its policy and finding, with a justification, a fix owner and an expiry matched to the fix plan. The request flow in Safeguard already asks for a policy and a finding, and scoping each one keeps the audit trail readable and stops unread findings from slipping through.
A risk acceptance on a reachable high severity finding is about to be renewed for the second time. What does a good process do?
Treat the renewal as a new request with new evidence and a different approver where possible, and escalate it, because a second renewal means the fix plan, the capacity or the policy is wrong. The Mitigations review flow offers extend, revoke or upgrade to a fix; extend should be the hardest to choose.
Sources
- Safeguard docs: Policies & Gates
- Safeguard docs: Policy outcomes and actions
- Safeguard docs: Guardrails & Enforcement
- Safeguard docs: Mitigations
- Safeguard docs: RBAC, Teams & Organizations
- Safeguard docs: Organization & User Management
- Safeguard docs: Webhooks & Events
- Safeguard docs: Analytics & Dashboards
- NIST SP 800-218, Secure Software Development Framework 1.1
- NIST SP 800-218 full text (PDF)
- NIST Cybersecurity Framework 2.0 (PDF)
- NIST SP 800-53 Rev. 5
- NIST SP 800-53 Rev. 5 control catalog (OSCAL JSON)
- OWASP CICD-SEC-1: Insufficient Flow Control Mechanisms
- CISA Known Exploited Vulnerabilities Catalog
- CISA: BOD 22-01 (revoked, superseded by BOD 26-04)
Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.