Skip to content

The vulnerability database across the air gap

An isolated zone cannot reach the upstream vulnerability database, and a side channel to update it would defeat the point of a tool whose job is to be the channel (ADR-0008). So the database — and, on a Linux or Windows host, the scanner binary itself — travel as ordinary ingredients of a signed recipe, tobby-system, through the same synchronization, the same medium and the same verification as everything else (FR-032).

The site’s qualification chain cooks and signs it, like any other recipe — the destination’s trust roots ignore any key but the site’s:

apiVersion: recipe.tobby.dev/v1alpha1
kind: Recipe
metadata:
name: tobby-system
version: 2026.11.11 # one version per database refresh
spec:
ingredients:
- name: trivy-db # the vulnerability database, schema 2
kind: OCIArtifact
ref: ghcr.io/aquasecurity/trivy-db
version: "2"
digest: sha256:… # pinned at cooking time
artifactType: application/vnd.aquasec.trivy.config.v1+json
- name: trivy # the scanner, for Linux and Windows hosts
kind: FileSet
ref: ghcr.io/aquasecurity/trivy
version: "0.76.2"
digest: sha256:… # the multi-platform index

The container image already bundles the pinned scanner, so an instance deployed from it only needs the database. A Windows host needs a FileSet holding trivy.exe at its root (packed with tobby fileset pack from the upstream release archive, checked against its checksum) referenced through scan.trivy.ref: upstream publishes no Windows image. macOS takes trivy from the PATH and needs only the database.

Only this recipe delivers: the one named tobby-system, admitted with its signature verified. The scanner and its database decide what else crosses, so a recipe admitted under a relaxed trust scope — even one named tobby-system — or any other recipe never supplies them, whatever repository it names; and the repository is matched exactly (the relocated ref under the base prefix of the instance that wrote the record), never by its ending. Such a recipe still synchronizes like any other; the scanner simply does not see it, and stays in the degraded mode until the signed one is recorded.

  1. Connected zone. List tobby-system first in the Retriever: once it is recorded, the scanner re-reads its deliveries, so the recipes after it are scanned in the same run. Before that, every image is reported not scanned — and refused under a blocking policy.
  2. Synchronize (mirror: tobby sync --wait). Check the Retriever screen’s scanning indicator, or the metrics: tobby_scan_scanner_available 1, tobby_scan_db_present 1, tobby_scan_db_age_seconds a few hours.
  3. Carry the medium and import it on the isolated side. Media verification and import (FR-052, FR-054) do not need the database: a destination instance without one still verifies and pushes a medium.
  4. Inside the zone, every instance that retrieves from the zone registry lists tobby-system first in its own Retriever, and finds the very database that crossed — same digest, same build timestamp, its age in every report.

Until a database is present, the degraded mode is stated on every surface (TBY-SCN-003): banner, startup log, tobby_scan_db_present 0.

The database is only as good as its last transfer. Its age is measured from the build timestamp it records, not from the transfer, and scan.maxDbAge (default 168 h) bounds it: beyond, warn reports staleness on the report, the UI and tobby_scan_db_stale, while block refuses items scanned with it (TBY-SCN-004). Cook a new tobby-system version on the cadence the bound implies — weekly by default — and let it ride the next medium.

A database whose recorded build time lies in the future of this instance’s clock — beyond one hour of tolerated skew — has no age that can be stated: it is treated as stale, with its own code (TBY-SCN-008), on the report, the banner and tobby_scan_db_stale, and refused under block. Check the host’s clock.

Tobby keeps only the current database unpacked, in its state directory (<state.root>/scanner, never on the transportable store); a new delivery replaces it at the next synchronization. That directory must be the instance’s own: owned by the user Tobby runs as and writable by nobody else, or the scanner refuses it and stays in the degraded mode (TBY-SCN-001 names why). An instance without a state directory unpacks into a fresh private directory under the temporary directory, removed at shutdown.