Skip to content
Go to platform

Understand job and cache SBOM completeness

Use CRACI SBOM completeness to decide whether a job’s dependency view accounts for every package that could have entered the build. CRACI evaluates the job’s own package evidence and the evidence attached to every GitHub Actions cache it restores.

CRACI carries known dependencies forward when a later job restores a cache. This keeps the later job’s dependency view accurate even when a package comes from the cache instead of being downloaded again. If a cache SBOM is incomplete, packages missing from that cache may also be missing from the restoring job’s SBOM.

A job has a complete CRACI SBOM only when:

  • CRACI observed complete dependency evidence for the job itself;
  • the job did not allow unmatched, unmonitored traffic; and
  • every cache restored by the job has a complete CRACI SBOM.

These requirements make completeness transitive. If a job restores an incomplete cache, its SBOM is incomplete too. If that job produces another cache, the new cache carries the incomplete status forward.

CRACI displays one of these results:

ResultMeaningComplete
CompleteCRACI observed complete job evidence, and every restored cache was complete.Yes
Complete with connectionsThe requirements passed, but the job used one or more custom network connections.Yes
IncompleteCRACI identified a condition that could leave dependencies out of the SBOM.No
UnavailableCRACI could not finish evaluating the evidence.No
Not recordedThe job predates completeness reporting.No

A cache has a complete CRACI SBOM only when all of these conditions are true:

  • One cache per producing job

    When a job creates multiple caches, CRACI cannot reliably determine which cache contains each observed package.

  • Complete producing-job evidence

    The producing job must have a complete SBOM, including complete evidence from caches that it restored.

CRACI follows the producing job’s known dependencies, including dependencies from caches that job restored. It does not inspect package manifests inside the cache archive. A legacy cache created before this information was recorded therefore has unavailable evidence, even if its producing job used monitored traffic.

  • Derive cache keys from dependency lockfiles. Include a lockfile hash, such as ${{ hashFiles('package-lock.json') }}, in the cache key. A dependency change then produces a new cache instead of restoring stale packages selected by an older lockfile.
  • Use custom connections only when you understand the trust boundary. CRACI does not monitor connections for package downloads. Prefer a built-in preset or custom source for package registries. If you need a connection, restrict its destinations and ports, and verify that it cannot supply packages or build tools.

Produce a cache with complete dependency information

Section titled “Produce a cache with complete dependency information”

Create a runner template under Settings → Runner templates and select Monitored for its network policy. Select that template in each job that produces a cache:

- uses: cracicorp/setup@v1
with:
template: monitored-build

Alternatively, configure the job’s network policy directly. Set default: deny to block traffic that matches no preset, source, or connection:

- uses: cracicorp/setup@v1
with:
network: |
default: deny

In both cases, have the producing job create only one cache. See Control network access from jobs for package sources, custom connections, and network policy examples.