Track each vulnerability against each component with a status from a short fixed list, a written reason, an owner and a date. Four statuses cover most needs: under investigation, affected, not affected and fixed. The reason is what makes a status believable later.
The four statuses
| Status | Meaning | What to record |
|---|---|---|
| Under investigation | Known issue, no decision yet | Owner, due date |
| Affected | The product is exposed and needs action | Planned fix or mitigation, target date |
| Not affected | The vulnerable code or condition is absent or not reachable | The reason, with evidence |
| Fixed | A release without the issue has shipped | The release identifier |
These match the vocabulary common in vulnerability exchange documents, which makes a later export to a customer easier. If you extend the list, do it sparingly. Every added status is another thing to explain.
Why the reason matters
"Not affected" is the status that gets challenged. A customer or assessor will ask why. Typical reasons are that the vulnerable function is never called, the component is present but not loaded, a configuration blocks the path, or the code was removed in a build step. Write the reason in a sentence and attach evidence, such as a reachability result or a test. A status with no reason is an opinion.
The post on why VEX needs an SBOM and matching VEX statements to components go deeper.
Rules for a clean record
- One status per vulnerability per component per release. A fix in release 5 does not change release 4.
- Record who decided. A named approver for not affected decisions.
- Date everything. Statuses age. A not affected decision may be wrong after a code change.
- Re-review on change. Revisit when the component version changes or code that touches it changes.
- Keep history. Do not overwrite. Append a new status with a new date.
Sheet limits
In a sheet, a status column is easy to add. The problems come later. There is no enforced vocabulary unless you add validation, history shows that the cell changed but not why, and the same finding across releases needs separate rows that drift apart. When an advisory is updated or a fix is released, nobody is notified. A platform can hold status as a structured field per release with reasons and approvals, and can surface items whose reasons have expired.
Practical workflow
- New finding arrives. It starts as under investigation, owner assigned from the ownership fields.
- Triage using reachability, exposure and fix availability.
- Set affected or not affected with a reason.
- For affected, create a ticket and link it.
- On release, set fixed and note the version.
- Include statuses in customer communications through a VEX style file when asked.
For prioritising, see from inventory to insight.
Where Safeguard fits
Safeguard provides reachability analysis, which gives evidence for a not affected decision, and autonomous remediation with fix PRs, which is off by default with every category on Manual. The free scan at gold.safeguard.sh/scan shows findings on your own code.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at how a finding moves from known issue to an available fix, and which status you would record at each step.
Quick check
Can I mark everything not affected to clear the list?
You can, but it will not survive a customer question. Each not affected needs a reason and evidence.
Should status be per product or per component?
Per vulnerability, per component, per release. Roll up for reporting, but record at that level.
Last reviewed: 19 October 2026.