Vulnerability Management Process Template
A finding register that keeps what each scanner reported beside the severity your own environment gives it, plus the procedure behind it.
Free download · No account needed
Triage Procedure
How this team decides what counts as work
1. What is in scope, and what is not
The repositories, images, hosts and cloud accounts anybody scans, and the ones deliberately left out. A finding on an asset nobody agreed to scan is a scope question rather than a severity question, and it gets answered here instead of in the queue.
2. Where the exports come from
Each tool by name, what it actually covers, and which of them overlap. Two tools covering one estate is the ordinary case and the reason the register collapses rows.
3. Severity vocabulary
The four or five words this team uses and what each one means here. Not the scanner's words: a scanner reports whatever its advisory source said. This is the vocabulary the reconciled column is checked against, and until it exists the register has nothing to reconcile to.
4. The clock, and what starts it
Days to remediate per severity, whether the clock starts at publication, at first detection or at triage, and which date wins when a published exploitation deadline is shorter than your own. One sentence, decided in advance, because it is decided badly under pressure.
5. What counts as reachability evidence
The forms of proof that justify a downgrade: a lockfile section naming a build-only dependency, a call-path analysis that found no path, a check of what is in the deployed artifact. Anything else is an opinion with a green cell next to it.
6 to 10
Who may accept a risk and up to what severity, the longest an exception may run, what a compensating control has to look like to count, who verifies a fix and how, and where a finding on somebody else's system goes.
A scanner's severity column looks like a property of the vulnerability. It is a property of which database the scanner asked, and in what order. Trivy resolves severity from the distribution's own advisory first, from GitHub's database for GHSA identifiers, and from the National Vulnerability Database only as a fallback. The number is also a base score, which the specification names CVSS-B and hands to you unfinished: applying the threat and environmental metrics is the consumer's job.
The same vulnerability then arrives several times over, and the tools say why. Grype's identity for a finding is the vulnerability id, the advisory namespace it came from, and the package. Change the namespace and the identity changes, so one CVE in one package sourced from two feeds is two rows inside a single scan, before a second scanner is involved. Deduplicate on the CVE and the package at the version present, per asset, and keep the losing row: which tools saw a finding is a question somebody asks later.
So the register carries two severity columns. One transcribes what each tool reported, vector and scanner name attached; the other holds what survives asset criticality, reachability and observed exploitation, with a third column stating why they differ. Where nothing in your inputs says whether the vulnerable code is even called, reading it out of the codebase is the input, and a downgrade that changes the architecture earns its own decision record. Hand River the export nobody has opened, or start from the blank documents and registers.
What's in the pack
Finding Register
One row per finding, deduplicated across tools, carrying the severity each scanner reported beside the one your environment gives it and the reason they differ. Scanner output only: a human-authored assessment is a different input with different failure modes, and it has its own response pack.
Remediation Tracker
One row per piece of work rather than per finding, because a single dependency upgrade closes eleven rows, and a configuration change closes one no rescan can confirm.
Exception Register
Every accepted risk with its compensating control, its approver, its renewal count and the date it stops being valid. Expired is a queue, not an archive.
Triage Procedure
The ten questions a team answers once: what is in scope, the severity vocabulary, when the clock starts, and what evidence justifies a downgrade.
Reading a Reported Severity
Why an export is mostly Criticals, read off the specification's own defaults, and what confirmed exploitation, predicted exploitation and reachability each do to the order.
Remediation Plan
The plan the register produces: work items with owners and dates, grouped so one upgrade appears once, with capacity stated rather than assumed.
Risk Acceptance Format
What an acceptance has to say to be worth filing, including who is allowed to sign it, what the control is, and when it expires.
Worked Finding CVE-2021-44228
One finding taken end to end with real published values: three scanners, two numbers, three assets, one downgrade, and the follow-up CVE that arrived seventeen months later.
How to use it
- 1
Open in River, or take it blank
Install the pack in River and point it at your scanner exports, or take the documents and registers and work through them yourself.
- 2
Answer the procedure first
The severity vocabulary, the clock and what counts as reachability evidence. Until those three are settled the register has nothing to reconcile against.
- 3
Send every export you have
Snyk, Dependabot, Trivy, Nessus, a pentest findings table, or all of them over the same estate. Overlap is the point rather than a problem.
- 4
Work the short queue
What is due, ordered by evidence of exploitation rather than by score. The weekly sweep re-checks every open finding and reports what changed.
Frequently asked questions
Is this template free?
Yes, and free means free: no account, no card, no email gate on the download. Edit with AI is the half you opt into, where the agent takes the exports you already have, collapses the rows describing one vulnerability and fills the register. The rest of the template library works the same way.
What format are the downloaded files?
Five .docx documents and three .csv registers in one zip. Every register column is plain text, so a scanner export pastes in beside the illustrative rows with no import step, and the whole thing opens in Excel, Numbers, Google Sheets, Word or Pages.
Our scanner says Critical. Why would the register say low?
Because a published score assumes the worst case about your environment, and it says so. The working group behind the standard states that base scores are not risk and should not be used alone for patch prioritisation. A downgrade still has to carry its evidence, which is the one rule this space enforces.
Two scanners gave us different severities for one CVE. Which is right?
Both, usually. Trivy's own source records that the distribution rates CVE-2015-2328 unimportant for one package and low for another, while the national database holds only a version 2 score of 7.5 for it. The register keeps every reported severity with the tool that reported it.
Can it tell us what is actually due this week?
Yes, ordered by confirmed exploitation rather than by score, which moves rows a long way. Of the vulnerabilities on the exploited catalog, 135 are rated Medium and three are rated Low, so a queue sorted by severity buries them under hundreds of Highs nobody has attacked.
What happens to the findings we are never going to fix?
They get a row in the Exception Register with a compensating control, a named approver and an expiry date, so the decision resurfaces instead of ageing quietly. If one is later exploited, the incident postmortem has the acceptance and its reasoning already written down. It is also the row a customer's security questionnaire makes you defend.
Our scan output cannot leave our network. Can we still use this?
Yes. A private AI workspace installs this pack inside your own tenancy, so asset names, exploit paths and reachability evidence never cross a boundary your security review has not already approved. Nothing about the registers or the weekly sweep changes. The secure code review checklist installs the same private way, for findings a reviewer catches before code ships at all.
Find out which findings are actually work
Download the documents and registers and fill them in yourself, or open the pack in River and point it at the export nobody wants to read.
Edit with AI