The first time a team turns on a container scanner across all its repositories, the result is usually a dashboard with several thousand findings, a few hundred marked critical. Two weeks later, the dashboard is ignored. The problem is not the scanner; it is the lack of a process that turns findings into a short, ordered list of work with clear owners and deadlines.
This post describes the vulnerability management lifecycle I set up at companies with one or two people responsible for security and a few dozen engineers. It is continuous, it is honest about priorities, and it measures what matters: how long exploitable weaknesses stay open.
What vulnerability management is
Vulnerability management is the continuous process of identifying, evaluating, prioritising, remediating and verifying security weaknesses across systems, applications and networks. The word "continuous" is the important one. New vulnerabilities are published every day, and your systems change every day; a quarterly scan is a snapshot, not a programme.
The lifecycle has six stages:
Discover -> Scan -> Prioritise -> Remediate -> Verify -> Report
^ |
+----------------------------------------------------+
Stage 1: discover your assets
You can only find vulnerabilities in assets you know about. Build an inventory that covers:
- cloud accounts and the resources in them: instances, containers, functions, databases, buckets;
- internet-facing hosts, domains and subdomains;
- source repositories and the dependencies they declare;
- container images in registries, and what is actually running;
- laptops and servers, from the MDM and EDR consoles;
- SaaS applications that hold company data.
For each asset, record an owner (a team, not a person who may leave), its exposure (internet facing, internal, isolated) and the sensitivity of the data it handles. These three attributes drive prioritisation later.
Automate discovery where possible: cloud provider inventories, DNS zone exports and registry listings can be pulled on a schedule, and new assets without an owner raise a ticket.
Stage 2: scan
Different asset types need different scanners:
| Asset | Scanner type | Example tools |
|---|---|---|
| Application dependencies | Software composition analysis | Dependabot, Renovate with advisories, Trivy, OSV-Scanner |
| Container images | Image scanning | Trivy, Grype, registry-native scanning |
| Hosts and VMs | Agent or network vulnerability scanning | Cloud provider inspectors, OpenVAS |
| Infrastructure as code | Misconfiguration scanning | Trivy config, Checkov |
| Cloud accounts | Posture management | Provider security hubs and config rules |
| Web applications | Dynamic testing | OWASP ZAP in CI, periodic manual tests |
Scan on change (in CI for code and images) and on schedule (daily for running assets), because a vulnerability published today affects an image that was clean when it was built.
Stage 3: prioritise
This is where most programmes fail. Sorting by CVSS severity alone produces a list where hundreds of items are "critical" and nothing distinguishes the one that is being exploited right now.
I use four inputs:
- Known exploitation: is the CVE in the CISA Known Exploited Vulnerabilities (KEV) catalog?
- Likelihood of exploitation: what is its EPSS score, the estimated probability of exploitation in the next 30 days?
- Exposure: is the affected asset reachable from the internet, internal only, or isolated?
- Severity and impact: the CVSS score, adjusted by the sensitivity of the asset's data.
From these, a simple decision table:
| Priority | Rule | Remediation SLA |
|---|---|---|
| P1 | In KEV, or EPSS above 0.5, and internet-facing | 48 hours |
| P2 | In KEV or EPSS above 0.1 on internal assets, or CVSS 9+ internet-facing | 7 days |
| P3 | CVSS 7-8.9, or CVSS 9+ on internal assets with no exploitation signal | 30 days |
| P4 | Everything else | 90 days or next planned upgrade |
The thresholds are a starting point; tune them to your volume. What matters is that the rule is written down, applied automatically, and that P1 really means "drop other work".
Reachability cuts the noise further
Many dependency findings are in code paths the application never calls, or in packages only used at build time. Some tools can analyse reachability or distinguish runtime from development dependencies. Use it to lower priority, not to ignore findings entirely; unreachable code has a way of becoming reachable after a refactor.
A worked example
Three findings arrive on the same morning:
- A remote code execution CVE in an image library, CVSS 9.8, listed in KEV, used by the public upload service. That is P1: patch or disable the feature within 48 hours.
- The same CVSS 9.8 CVE in a batch job that only processes files generated internally, with no network exposure. That is P3: fix in the next 30 days.
- A CVSS 7.5 denial of service issue in a web framework, EPSS 0.02, on an internet-facing API behind a CDN with rate limiting. That is P3 as well.
Without the rule, the two 9.8 findings would look identical and the team would argue. With it, the decision takes a minute and is the same whoever makes it.
Stage 4: remediate
Remediation options, from best to least preferred:
- Patch or upgrade the affected component.
- Remove it if it is not needed. Unused packages, base image tools and old services are free wins.
- Mitigate with a configuration change, a WAF rule or a network restriction while a fix is pending.
- Accept the risk, in writing, with an owner and an expiry date.
Make remediation cheap so it happens:
- Automated dependency update pull requests, grouped and with tests, merged regularly rather than in a yearly big-bang upgrade.
- Base images rebuilt weekly from updated upstream images, so OS-level fixes flow in without anyone touching them.
- Findings routed to the owning team's normal backlog, not a separate security tool they never open.
Stage 5: verify
A ticket closed as "fixed" is not proof. Verify by re-scanning the asset after the change and confirming the finding disappeared from the running system, not just from the repository. A common gap: the dependency was updated in the main branch, but the service in production still runs an image built a month ago.
# Example: confirm the running image no longer has the CVE
trivy image --severity HIGH,CRITICAL registry.example.com/billing-api@sha256:3f1c... \
| grep CVE-2026-12345 || echo "not present"
Stage 6: report and improve
Report a few metrics monthly, to engineering leadership as well as security:
- Mean time to remediate by priority, compared with the SLA.
- SLA compliance: share of P1 and P2 findings fixed within their deadline.
- Open exploitable findings: count of KEV or high-EPSS findings on exposed assets. This is the most honest single number of your exposure.
- Coverage: share of assets scanned in the last seven days.
- Risk acceptances open and expiring.
Avoid reporting the total number of findings as a headline. It mostly measures how many scanners you run.
Common mistakes
| Mistake | Why it hurts | Do this instead |
|---|---|---|
| Prioritising by CVSS alone | Hundreds of "criticals", real threats buried | Combine KEV, EPSS, exposure and data sensitivity |
| Scanning only repositories | Running systems drift from code | Scan registries and running workloads too |
| Separate security backlog | Engineers never see it | Route findings to team backlogs with SLAs |
| Closing tickets without re-scanning | Fixes that never deployed | Verify on the running asset |
| Permanent exceptions | Risk accumulates silently | Acceptances expire and are re-reviewed |
Key takeaways
- Vulnerability management is a continuous lifecycle, starting with knowing your assets and owners.
- Scan code, images, hosts, infrastructure and cloud configuration, on change and on schedule.
- Prioritise with exploitation signals (KEV, EPSS) and exposure, not severity alone, and write the rule down.
- Make remediation cheap with automated updates and regular image rebuilds.
- Verify fixes on running systems and report time-to-remediate and exploitable exposure.
References
- NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning: https://csrc.nist.gov/pubs/sp/800/40/r4/final
- CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- FIRST, Exploit Prediction Scoring System: https://www.first.org/epss/
- FIRST, CVSS v4.0 Specification: https://www.first.org/cvss/v4.0/specification-document
- Trivy documentation: https://trivy.dev/latest/docs/
Comments
0No comments yet. Be the first to comment!
Sign In to post a comment.