Yes, expiry should follow the reason. A deferral because no fix exists needs a short clock tied to a fix. A not reachable finding should expire when the code changes. A withdrawn advisory needs a data check rather than a timer. One default for everything is easy to set and often wrong.
The problem with one number
Many teams pick 90 days and apply it to every suppression. That works as a floor, but it ignores what each reason actually depends on. A suppression is true only while its reason is true, so the expiry should track what could make the reason false.
Suggested defaults by reason
These are starting points, not rules. Adjust to your risk appetite.
| Reason | What makes it false | Suggested expiry |
|---|---|---|
| No fix available | A fix ships | 30 to 60 days, or when a fix is published |
| Mitigation in place | The control is changed or removed | 90 days, plus re-test when the control changes |
| Not reachable | New code calls the vulnerable function | Next dependency upgrade or 180 days |
| Component not present | The build changes | Next release that touches the build |
| Advisory withdrawn or disputed | The record is updated again | Re-check data at each scanner database refresh |
| Deferred for priority | The queue frees up | 30 days, one renewal at most |
Event triggers beat calendars
Calendar expiry catches neglect. Event triggers catch change. Good tooling supports both:
- Expire on upgrade of the affected package.
- Expire when the finding appears in a newly known exploited list.
- Expire when the owner leaves or the repository changes hands.
If your tool supports only dates, add a note field and a review habit for the events.
Shorter for higher severity
A critical finding with a reachable path and a deferral reason should get days, not months. A low severity finding with a documented not reachable result can sit longer. A simple rule: halve the default for each severity step up.
Limit renewals
Count renewals. One renewal with new evidence is normal. Three renewals mean the underlying issue needs real work, not another extension. See renewing or re-reviewing.
Time zones and edges
Pick a convention for the end moment, such as end of day UTC, and write it down. Surprises at midnight cause avoidable pages. Our note on expiry timestamps has more.
Try it yourself
Click through it at your own pace, or open it full screen. Look for how new advisories surface on projects you already scanned, which is why a reason can stop being true without any code change.
A worked example
Say a team defers a high severity finding because no fix exists. The record gets a 30 day end date and a mitigation note. At day 30 the finding returns. A fix has shipped, so the owner upgrades and deletes the entry. Had the record carried a blanket 180 days, the fix would have sat unused for five months while the entry kept the gate green.
Quick check
Is 90 days a good default for every suppression?
It is a reasonable ceiling. Shorten it for deferrals and high severity, and tie not reachable findings to upgrades.
What if the tool only supports dates?
Use dates, and add a review note listing the events that should reopen the decision.
Last reviewed: 19 October 2026.