How we grade

Every grade on ce.rodeo decomposes to arithmetic from inputs you can verify. This page is the formula. Rubric version cerodeo-v1.

The Scout grade (per image)

We call it the Scout grade because that's the vocabulary operators have for "security health of a container image." Docker's own A–F surface was retired from Docker Hub on 2026-07-01; we compute our own grade from the same raw inputs (CVE counts, policy results, supply-chain signals) using the open rubric below.

The formula

score = 100
      − 25 × critical CVEs with an available fix
      − 10 × high CVEs with an available fix
      −  3 × medium CVEs with an available fix
      −  8 × critical CVEs that have no fix available
      −  3 × high CVEs that have no fix available
      + 10 if image rebuilt within last 90 days
      + 10 if default user is not root
      +  5 if image is cosign-signed
      +  5 if a SLSA provenance attestation is attached
      +  5 if the provenance's subject SHA256 matches the image manifest SHA256
      +  3 if HEALTHCHECK is defined in the image config
      +  3 if the OCI standard labels are populated (title, description, source, version, revision)
      +  3 if the image ships 3+ architectures (+2 for 2 arches)
      +  3 if the image tag matches an upstream GitHub release
      +  3 if the SBOM is attested (not just derivable via syft)
      +  2 if the Docker Hub README has a usable example (docker run or compose snippet)

score = max(0, min(100, score))
grade = A ≥ 85, B ≥ 70, C ≥ 55, D ≥ 40, F < 40

Where every input comes from

InputSource
CVE lists by severity and fixabilityGrype matching our cached syft SBOM against the Grype vuln DB (consults GHSA, NVD, Red Hat, Debian, Ubuntu, Alpine, PyPA, npm advisory DBs)
Non-root default userconfig.User field in the OCI image config
Rebuild freshnessCreated timestamp from the image manifest
cosign signaturesigstore registry lookup via cosign triangulate
SLSA provenance + SHA256 matchcosign download attestation --predicate-type=https://slsa.dev/provenance/v1, DSSE envelope parsing, subject[].digest.sha256 compared to the image manifest digest
HEALTHCHECK, OCI labelsOCI image config blob
Architecture countmanifest list from the registry
Upstream GitHub release matchGET /repos/:owner/:repo/releases/tags/:tag (we have the owner/repo mapping for most tracked projects)
SBOM attestationcosign download attestation --predicate-type=https://spdx.dev/Document
README exampleDocker Hub /v2/repositories/:ns/:repo full_description, regex for docker run or compose block

Scan cadence

Every image is re-matched against the latest Grype DB hourly. The Grype DB itself refreshes every 4 hours from Anchore, which pulls from GHSA + distro feeds. Daily, we HEAD each image's manifest and re-pull if the digest changed. Weekly, we do a sanity sweep that re-pulls every image from scratch. For common OSS CVEs, worst-case latency from publication to appearance on ce.rodeo is ~2–7 hours.

What this is not

The Pulse grade (per project)

Pulse answers "will this still be alive in 12 months?" independently from Scout's "is it secure right now?". Three signals, percentile-ranked across the scored set, equal-weighted:

  1. GitHub 90-day commit volume (from /stats/participation)
  2. GitHub stars, log-dampened to tame long-tail outliers
  3. HN story count last 90 days via the free Algolia search API

Archived GitHub repos cap at D regardless. Mature stable projects (apache-httpd, memcached) currently underscore because the v0 formula over-rewards attention — a known limitation. Counterweight signals (release cadence, CVE-fix latency, long-term committer count) are on the roadmap.

Changelog

cerodeo-v1
Initial rubric. Published alongside the first scored snapshot in October 2026.

Think the rubric should weigh something differently? Open an issue: github.com/c0inz/cerodeo/issues.