Posture Score (Pro)

Note: the Posture Score ships with the DefectDojo Pro Command Center (beta). See Command Center for enabling it.

Most security scores are opaque: a number with no published scale, no published weights, and no way to check it. DefectDojo’s posture score makes the opposite commitment. The formula below is the formula; the same descriptor is served machine-readable at GET /api/v2/dashboards/widget_data/posture_formula/; every input is stored in the daily snapshot ledger, so any historical score can be recomputed and audited; and formula changes are versioned events drawn on the trend line, never silent rewrites of history.

The scale

0 to 1000, higher is better. Bands: strong at 800 and above, needs attention at 600 to 799, at risk below 600. A score is computed over the viewer’s authorized assets, so two users with different access correctly see different scores; instance-wide scores require a global view permission.

The formula (version 1)

The score is the weighted sum of five components. Each component is normalized to a 0 to 1 value by a monotone function of raw inputs, then multiplied by its weight. Weights sum to exactly 1000.

ComponentWeightNormalized value
Open severity burden3001 / (1 + density / 25) where density is severity-weighted open findings (Critical 10, High 5, Medium 2, Low 1, Info 0) divided by assessed assets
SLA posture2001 - (breached / SLA-tracked open); neutral 1.0 when nothing is SLA-tracked, flagged as such
Coverage confidence200assets scanned in the last 90 days / all assets
Exploit pressure1500.5 ^ (open KEV findings / 4), multiplied by 1 - 0.5 x EPSS p90 of the open backlog
Automation health150rule actions / (rule actions + manual closures) over the window; neutral 0.5 when there was no triage activity, flagged as such

Design commitments, stated so they can be challenged:

  • Ratios, not raw counts, wherever growth would otherwise punish scope: burden is a per-assessed-asset density, SLA and coverage are shares. Growing your inventory without scanning it lowers the score through coverage, which is the honest direction.
  • KEV is deliberately absolute. A known-exploited vulnerability open anywhere is an emergency regardless of estate size, so it is an exponential penalty, not a ratio. It saturates, so it cannot zero the score alone.
  • Priority bands are excluded from the score because their thresholds are per-instance configuration; a published formula must not change meaning when an admin edits a threshold.
  • Neutral rules are visible. Where a component has nothing to measure (no SLA tracking, no triage activity, no EPSS data), the why panel says so instead of hiding a default.

The why panel and the counterfactual

The score widget’s why panel decomposes the number into the five components (weight, value, contribution, and a plain sentence each), shows the raw stored inputs (the receipt), and ranks the levers: exact counterfactuals computed by substituting one input and re-running the same formula. “Fix the 12 known-exploited findings: at least +84 points.” Deltas are lower bounds where levers overlap in reality, which is why every lever says “at least”.

Versioning

Formula versions are immutable once shipped. Changing a weight or a normalization means publishing a new version; the daily snapshot records both the score as published that day and the full input vector, so trends can be rendered two ways: recomputed under the current formula (the default, so a formula release never masquerades as a posture change) or as published at the time, with version-change markers on the chart. The version history is part of the formula endpoint’s response.