A security exception for a vulnerable dependency should state the package and finding, why it cannot be fixed now, what reduces the risk meanwhile, who accepts it, and when it expires. An exception without an expiry date is a permanent decision made by accident.
When an exception is the right tool
Sometimes a fix does not exist, the upgrade breaks a customer contract, or the vulnerable function is never called. In these cases an exception is honest. The alternative is a long list of overdue items that everyone ignores.
An exception is not the same as marking a finding as a false positive. A false positive means the finding is wrong. An exception means the finding is right and you accept it for a time.
Template
| Field | What to write |
|---|---|
| Package, version, ecosystem | Exact identity, ideally as a package URL |
| Finding | Advisory or CVE identifier and severity as scored by your policy |
| Where it is used | Services and products affected |
| Reason a fix is not possible now | No fixed version, breaking change, vendor dependency, or similar |
| Exposure analysis | Is the vulnerable code reachable? Is input attacker controlled? Is the service internet facing? |
| Compensating controls | Input validation, network restriction, feature flag off, monitoring rule |
| Risk owner | A person with authority to accept the risk, not just the requester |
| Plan | Specific next step, such as upgrade planned for a named release |
| Expiry date | Fixed date, shorter for higher severity |
| Review trigger | Events that end the exception early, such as public exploit reports |
Rules for approvers
- The approver is the owner of the affected product or a delegate, with security consulted.
- Time limits are short enough to force a real plan. Choose limits per severity and write them in the policy.
- Renewal needs a new written reason. If the plan has not moved, renewal goes up one level.
- Critical findings that are known to be exploited in the wild should not be accepted without executive sign off.
- Every exception appears in a register that reports count, age and owners.
Making it checkable
If your gate blocks builds on severity, an approved exception should create a temporary rule with the same expiry date. When it expires, the gate starts failing again. This avoids the common failure where the document expires but the suppression stays forever.
What to report
Report to leadership the number of open exceptions, how many are past expiry, oldest age and the packages that appear repeatedly. Repeated packages are candidates for replacement.
Quick check
Is "not reachable" a good enough reason alone?
It is a strong input, but record how you determined it and re-check when the code changes. Reachability can change with a refactor.
Who can accept the risk?
Someone who owns the affected product or service and has authority over the consequences. A developer filing the request should not approve it alone.
Safeguard scans dependencies and builds SBOMs, runs reachability analysis, and applies policies and gates on pull requests, so the rules in this post can be checked automatically. Autonomous fix PRs are off by default, with every category on Manual. You can run a free scan at gold.safeguard.sh/scan.
Last reviewed: 19 October 2026.