diff --git a/content/manuals/scout/policy/local.md b/content/manuals/scout/policy/local.md index 4dc10533bd79..1a14ab68a480 100644 --- a/content/manuals/scout/policy/local.md +++ b/content/manuals/scout/policy/local.md @@ -118,6 +118,74 @@ $ docker scout policy myorg/app:latest --only-policy "No copyleft licenses" $ docker scout policy myorg/app:latest --output report.txt ``` +## Health score + +`docker scout policy`, `docker scout quickview`, and `docker scout compare` also +report a health score alongside the policy results: a numeric percentage and an +A-F letter grade, computed entirely from the local policy evaluation. No data is +sent to the Scout service to compute it. + +```console +$ docker scout policy myorg/app:latest +... +Health score B (83%) +``` + +`docker scout compare` shows the score for both images: + +```console +Health score Analyzed B (83%) Comparison C (65%) +``` + +### How the score is calculated + +The score is a weighted pass ratio: + +- Each policy contributes a weight to the total, taken from its `custom.weight` + metadata annotation (see [Metadata annotations](#metadata-annotations)) or a + `weight` override in the policy-config file. Policies without a declared + weight default to `10`. +- A policy that passes (reports zero violations) contributes its full weight to + the scored points. +- A policy that fails still counts its weight toward the total, but contributes + nothing to the scored points, which lowers the score. +- A policy with no data to evaluate (unknown) also counts toward the total + without contributing to the scored points. +- A policy with a weight of `0` is excluded from the score entirely. + +The percentage is `scored / total * 100`, mapped to a letter grade using strict +greater-than thresholds: + +| Score | Grade | +| --- | --- | +| > 90% | A | +| > 70% | B | +| > 50% | C | +| > 30% | D | +| > 10% | E | +| <= 10% | F | + +Thresholds are exclusive of their lower bound, so an exact boundary value +grades down: a score of exactly 90% is a B, not an A; exactly 70% is a C, and +so on. + +If every policy is excluded from the score (for example, all policies are +configured with `weight: 0`), no health score is shown at all. + +To change a policy's contribution to the score, set `custom.weight` in the +policy's Rego metadata, or override it per policy in the policy-config file: + +```json +{ + "policies": [ + { + "name": "no-copyleft-licenses", + "weight": 0 + } + ] +} +``` + ## Built-in policies The following policies are available by default: @@ -157,6 +225,10 @@ Pass it with `--policy-config`. - `policies[].name`: the policy's stable ID (see the following table). - `policies[].enabled`: set to `false` to skip the policy. Policies not listed are enabled by default. +- `policies[].weight`: overrides the policy's `custom.weight` metadata annotation, + which determines its contribution to the [health score](#health-score). A + weight of `0` excludes the policy from the score. When omitted, the policy's + own annotation is used, or `10` if it has none. - `policies[].config`: an object passed to the policy as `data.config`. ### Configuration reference @@ -293,7 +365,7 @@ to render results. Place them in a `# METADATA` block immediately above the | `description` | Longer explanation | | `custom.name` | Stable ID used to match `--policy-config` entries. Defaults to the package path if omitted | | `custom.result_type` | How violations are rendered: `vulnerability`, `license`, `boolean`, or `generic` (default) | -| `custom.weight` | Higher weights sort first in the report | +| `custom.weight` | Scoring weight and display sort order. Higher weights sort first in the report and contribute more to the [health score](#health-score). Defaults to `10` when omitted; a weight of `0` excludes the policy from the score | | `custom.not_compliant_title` | Status label shown when the policy fails | | `custom.details_order` | Ordered list of `detail` keys to display as columns | diff --git a/content/manuals/scout/release-notes/platform.md b/content/manuals/scout/release-notes/platform.md index 748462c3ccdb..e2d9e856b5b4 100644 --- a/content/manuals/scout/release-notes/platform.md +++ b/content/manuals/scout/release-notes/platform.md @@ -23,7 +23,10 @@ The following Docker Scout features were retired: - Health scores and Scout Everywhere: Docker Hub and Docker Desktop no longer display health scores or the always-on Scout experience. Use - `docker scout quickview` for a quick vulnerability and policy summary. + `docker scout quickview` for a quick vulnerability and policy summary. This is + unrelated to the health score reported locally by `docker scout policy`, + `docker scout quickview`, and `docker scout compare`. See + [Health score](../policy/local.md#health-score). - Sysdig integration: The Sysdig runtime environment integration has been removed. - GitHub source code management integration: Migrate to GitHub Dependabot for base-image updates and build with `--provenance=mode=max` for