Dependency security clearance
The nightly dependency lane records one normalized, content-bound evidence document for the root Bun graph, Desktop Bun graph, APIGen npm graph, and Go graph. The report is generated by the repository-native tool:
go run ./internal/app/tools/dependencyreport report \
--output dependency-security-report.json
go run ./internal/app/tools/dependencyreport check \
--input dependency-security-report.json
The equivalent task security:report and task security:report:check tasks
may be used in CI. Generation requires a clean checkout and all four scanners,
Node, and Task. A missing tool, scanner error, malformed result, missing lock
graph, edited graph, commit mismatch, or expired waiver fails closed. Scanner
errors and vulnerable graphs replace any older report with explicit uncleared
diagnostics while still returning non-zero. When a failure occurs before
complete evidence can be assembled, generation removes an older report rather
than leaving stale clearance.
The --allow-dirty flag is reserved for diagnostics and still cannot produce
cleared evidence.
Each report includes its schema version and UTC generation time, source commit
and dirty state, Node and Task versions, scanner/runtime versions and exact
normalized commands, the Go vulnerability database timestamp when supplied by
govulncheck, scanner environment controls, SHA-256 digests of all required
module lock/manifests, the presence and SHA-256 digest of the repository waiver
policy, normalized results, and severity/package counts. The Go
scanner uses a 4 GiB soft memory limit so the full source analysis remains
viable on standard CI runners. check recomputes the digests, toolchain, scans,
summaries, and clearance before accepting the artifact.
For Go, module-only and import-only advisories are retained as non-reachable notices, deduplicated by advisory and module. They do not satisfy the scanner's definition of affected code and therefore do not require a waiver. A finding with a symbol-level call trace is recorded as reachable and blocks clearance.
Runtime OS packages
The production server image combines a digest-pinned Debian base with the dated sources in deploy/container/debian-bookworm.sources. Both the Debian and Debian security suites use one immutable snapshot timestamp. APT binds each source to the Debian archive keyring, verifies signed repository metadata and package hashes, and therefore resolves direct and transitive packages from a frozen package universe on both release architectures. The bootstrap CA bundle comes from the separately digest-pinned Go builder before APT connects to the HTTPS snapshot.
The distroless public-site runtime installs no OS packages. The authoring qualification image derives from the server runtime and inherits its frozen sources. The malicious-browser proof image is test-only, and the Ubuntu host bootstrap is an installation-time patching boundary: it intentionally consumes the current signed Ubuntu 24.04 repositories and enables unattended upgrades rather than becoming part of the immutable application image.
To refresh runtime packages, choose a reviewed snapshot containing the intended security updates, update the snapshot timestamp and the pinned runtime base digest together, build both linux/amd64 and linux/arm64, inspect the installed package inventory, and rerun container vulnerability and provenance checks. Do not point a release build back at a moving mirror.
Waivers
Waivers are optional JSON in security/dependency-waivers.json. Reports bind
the exact repository policy, including its absence; alternate or report-only
waiver sources are rejected. Every waiver
must match an observed advisory and dependency and must include an owner,
reachability assessment, compensating control, creation time, and a future
expiry. Unused, malformed, future-dated, or expired waivers are rejected.
[
{
"advisory": "GHSA-example",
"dependency": "example-package",
"owner": "security@example.com",
"reachability": "The vulnerable code path is not shipped.",
"compensating_control": "Pinned transitive version and regression test.",
"created": "2026-08-01T00:00:00Z",
"expiry": "2026-09-01T00:00:00Z"
}
]
The report is cleared only when every scan passes or every observed finding is
covered by a valid waiver. Do not hand-edit a report; check compares its
normalized scan results with a fresh scan of the same checkout.
Verification
Run the report and then its check from the same clean commit. Both commands
must exit successfully, and the JSON must contain "clearance": {"cleared": true}. Review the uploaded artifact's commit and lockfile digests before
retaining it as release evidence. If a scan, digest, commit, graph, or waiver
check fails, fix the dependency or waiver and regenerate the artifact; do not
reuse a previous report.