EPSS score explained for Kubernetes operators
What an EPSS score actually measures, how to read the percentile, which threshold to act on, and a worked example from a real cluster showing why EPSS reorders the CVSS list so drastically.
StackRadar Team
· 9 min read
If you run Kubernetes, you have a vulnerability list, and it is sorted by CVSS. Sorting by CVSS is how a team ends up patching a never-exploited 9.8 in an image-processing library while the 7.5 in the ingress controller that has a public exploit waits in the second screen. EPSS exists to fix that ordering. It is free, daily, covers every CVE, and most scanners already show it — but the number is widely misread. This post says what it measures, how to read it, which threshold to act on, and shows what it does to a real cluster's list.
What the number measures
EPSS — the Exploit Prediction Scoring System, run by FIRST.org — publishes, for every CVE, the probability that it will be exploited in the wild in the next 30 days. It is a model output, trained on observed exploitation activity (from honeypots, IDS telemetry and vendor feeds) against a large set of features: the CVE's age, the affected vendor, whether exploit code is public, whether it is in the CISA KEV catalogue, references, CWE, CVSS vector components, and so on. The model is refit periodically — the current major version, EPSS v4, shipped in March 2025 — and the scores are recomputed every day.
Three things follow from that definition that are easy to miss:
- It is a probability, not a rating. 0.05 means five in a hundred. The median CVE is below 0.01. A "high" EPSS is anything over about 0.1.
- It is about the CVE, not about you. EPSS says nothing about whether the vulnerable package is in your images, whether the vulnerable code path is reachable, or whether the pod is exposed. It is one input to prioritisation, not a verdict.
- It changes. A CVE with EPSS 0.004 on the day it is published can be at 0.6 a week later once an exploit is public. Whatever you do with the score has to be re-evaluated daily or it is wrong.
Score versus percentile
Every EPSS record carries two numbers, and they are for different jobs:
{
"cve": "CVE-2021-44228",
"epss": "0.97",
"percentile": "0.99",
"date": "2026-08-27"
}The score is the probability. The percentile is the share of all scored CVEs with a lower score — here, 97.5% of CVEs are less likely to be exploited. The percentile is the number to read when a score looks small: 0.03 sounds negligible and is around the 90th percentile, because the distribution is so skewed. It is also the number never to compute with. Percentile is uniform by construction, so a formula that multiplies by it asserts that the median CVE has a 50% chance of exploitation, which is off by two orders of magnitude.
Which threshold to act on
FIRST deliberately publishes no threshold, and the honest answer is that the right one depends on how much you can fix. Two reference points are in wide use:
| EPSS | Roughly | Common use |
|---|---|---|
| ≥ 0.5 | Top ~1% of CVEs | Treat like KEV: this week |
| ≥ 0.1 | Top ~5–10% | "Patch this cycle"; the usual SLA trigger |
| ≥ 0.01 | Top ~25–30% | Scheduled maintenance |
| < 0.01 | The majority | Fix by base-image rebuilds, not individually |
The exact percentiles drift as the model is refit, so read them as bands rather than constants. A workable policy for a platform team is: everything in CISA KEV first, regardless of score; then EPSS ≥ 0.1, sorted by CVSS; then everything else, fixed in bulk by moving to newer base images. That is roughly a third of the findings on most clusters, and it is the third that matters.
A worked example
Take five findings that turn up in almost every Debian-based image — the kind of list any cluster with an ingress controller and a few Python or Node images produces. Sorted by CVSS they look like this. The KEV column is a fact; the EPSS values are rounded from a recent day and will have moved by the time you read this, which is rather the point:
| # | CVE | Package | CVSS | EPSS | KEV |
|---|---|---|---|---|---|
| 1 | CVE-2023-45853 | zlib (minizip) | 9.8 | 0.004 | — |
| 2 | CVE-2024-45491 | expat | 9.8 | 0.002 | — |
| 3 | CVE-2024-45492 | expat | 9.8 | 0.002 | — |
| 4 | CVE-2023-4863 | libwebp | 8.8 | ~0.6 | Yes |
| 5 | CVE-2024-6387 | openssh (regreSSHion) | 8.1 | ~0.4 | — |
The three 9.8s are real vulnerabilities in real packages, and they are in almost every Debian-based image on the planet. They are also, per EPSS, less likely to be exploited than 90% of CVEs — the minizip one is in a component most binaries never link. Number four is the libwebp bug that was used in the wild against browsers and is in the KEV catalogue; number five is the OpenSSH regression that had a public exploit within days. Sorted by the Radar Score contribution — CVSS weighted by exploitation, with KEV as certainty — the same five come out as:
| # | CVE | CVSS | Exploitability | Contribution |
|---|---|---|---|---|
| 1 | CVE-2023-4863 (KEV) | 8.8 | 1.00 | 88 |
| 2 | CVE-2024-6387 | 8.1 | ∛0.4 ≈ 0.74 | 60 |
| 3 | CVE-2023-45853 | 9.8 | ∛0.004 = 0.16 | 16 |
| 4 | CVE-2024-45491 | 9.8 | ∛0.002 = 0.13 | 12 |
| 5 | CVE-2024-45492 | 9.8 | ∛0.002 = 0.13 | 12 |
Across a whole cluster the effect is larger than five rows suggest. Because the EPSS distribution is so skewed, the KEV-or-EPSS-≥-0.1 set is typically one to two percent of a cluster's findings, concentrated in a handful of images — and those images are usually fixed by a chart bump or a base-image update rather than by touching a package. The remaining findings are not ignored; they are closed in bulk by the same base-image rebuilds. Nobody has to read them one at a time.
Where EPSS is weak
- No CVE, no score. GHSA and PYSEC advisories without a CVE alias, and every
MAL-malware record, are unscored. A scanner has to pick a rule for them; "treat as zero" buries real findings and "treat as one" floods the top. StackRadar treats them as typical and showsEPSS —. - It lags on brand-new CVEs. The model has few signals on day one. A CVE with a working exploit on GitHub can sit at 0.01 for a day or two before the score catches up. KEV and vendor advisories are the day-one signal.
- It knows nothing about reachability. A high-EPSS CVE in a library your binary never calls is still a high-EPSS CVE on the list. VEX statements are the tool for that, and they are a separate, slower conversation.
Using it tomorrow
If your scanner shows EPSS, sort by it once and look at what moves. If it does not, the API takes a comma-separated list of CVE IDs and the daily CSV is a single file. In StackRadar every finding carries its EPSS score and percentile, both re-synced daily, and the ranking above is the default sort — the point is that nobody should have to do the join by hand.
Frequently asked questions
What is an EPSS score?
An EPSS score is a probability, between 0 and 1, that a given CVE will be exploited in the wild within the next 30 days. It is published daily by FIRST.org’s Exploit Prediction Scoring System for every CVE, and comes with a percentile that says where the CVE ranks against all other scored CVEs. A score of 0.05 means a 5% chance; the median CVE sits well below 0.01.
How is EPSS different from CVSS?
CVSS measures severity — how bad exploitation would be, from the vulnerability’s technical characteristics — and does not change. EPSS measures likelihood — how probable exploitation is in the near term, from observed exploitation activity and dozens of other signals — and changes daily. A CVE can be CVSS 9.8 and EPSS 0.002 at the same time, and most critical CVEs are.
What is a good EPSS threshold to act on?
There is no official cut-off. Two reference points are widely used: 0.1 (10%), which captures roughly the top 5–10% of CVEs and is a common "patch this cycle" trigger, and the top 1% of scores, which sit above roughly 0.5. Many teams use "KEV first, then EPSS ≥ 0.1 sorted by CVSS, then the rest" — which is close to what the StackRadar Radar Score computes automatically.
What does the EPSS percentile mean?
The percentile is the fraction of all scored CVEs with a lower EPSS score. A percentile of 0.95 means the CVE is more likely to be exploited than 95% of all CVEs. It is useful for reading a score in context — 0.03 sounds low but is around the 90th percentile — and useless for combining with other numbers, because it is uniform by construction.
Where do I get EPSS scores?
FIRST publishes a full CSV every day at epss.cyentia.com and a free JSON API at api.first.org/data/v1/epss, queryable by CVE ID. Most scanners and vulnerability platforms, including StackRadar, sync the daily CSV and show the score and percentile beside each finding.
Does EPSS cover vulnerabilities without a CVE?
No. EPSS scores CVE IDs only. A GHSA or PYSEC advisory with no CVE alias, and every malware (MAL-) record, has no EPSS score and never will. A scanner has to decide how to rank those; StackRadar treats them as having typical exploitation likelihood so they rank on CVSS alone, and shows "EPSS —" rather than a fabricated number.