Chapter 11 — Supply-Chain Controls

11.1 Current State and Scope

As-built supply-chain posture is minimal but deliberately clean so far: everything installed to date (Docker, Compose, Prometheus, nginx, certbot) came from Ubuntu official repos or the official Grafana apt repo — no curl-pipe-bash installs, no third-party PPAs, no unpinned container images yet, because no application containers exist yet. This chapter sets the controls before the application build starts pulling npm/crates/PyPI dependencies and publishing images — retrofitting provenance onto an already-polluted dependency tree is an order of magnitude harder than starting gated. Scope: container images, OS packages, language dependencies (Node/pnpm, Rust/Cargo, Python), the artifact registry, and the build pipeline that connects them. Controlling SEC-001 requirement: INF-03 (repository controls) plus the supply-chain family imported into KO-001; AI-02 intersects where MCP tool containers are concerned (§6.4).

11.2 Registry Policy

GitHub Container Registry (GHCR) under the SBS GitHub organization is the sole artifact registry:

11.3 Image Provenance
11.4 Dependency Pinning

Per-ecosystem, all enforced in CI (a lockfile that isn't verified is documentation, not control):

Ecosystem Pinning mechanism CI enforcement
Node / pnpm pnpm-lock.yaml committed; packageManager field + corepack pins pnpm itself pnpm install --frozen-lockfile — any drift fails the build; pnpm audit report attached
Rust / Cargo Cargo.lock committed (binaries); rust-toolchain.toml pins the compiler cargo build --locked; cargo audit (RustSec)
Python requirements.txt with --hash=sha256:… per package (pip-compile generated) pip install --require-hashes; pip-audit
OS packages Versions asserted in the Ansible base role for security-relevant packages Drift surfaces in the nightly --check run (§10.5)

Dependency updates are PRs like any other change (Renovate bot, grouped weekly, auto-PR but never auto-merge) — the update path goes through the same review + CI gauntlet, so a poisoned upstream release sits in a diff a human looks at, not in a silent nightly pull. New top-level dependencies require a one-line justification in the PR body; transitive bloat is reviewed via the lockfile diff.

11.5 Artifact Signing and Verification
11.6 Pipeline Integrity and Scanning

The build pipeline is itself supply chain:

11.7 Verification

Gates (LH-SBS-INST-001): base-image allowlist file exists, all Dockerfiles resolve FROM digests within it (lint); :latest absent from every compose/Dockerfile (grep gate); frozen-lockfile builds pass and a deliberately drifted lockfile fails (negative test); cosign verify passes on a pipeline image and fails on a manually-pushed unsigned test image (negative test); deploy refuses the unsigned image end-to-end; SBOM attestation present for every deployed digest; Trivy CI gate demonstrated on a seeded-CVE test image; language registries unreachable from prod runtime (egress probe, §3.4); Actions digests pinned (workflow lint); prod running-set digests ⊆ registry signed-set (drift cross-check with §10.5).


Revision #1
Created 2026-07-18 11:49:21 UTC by SBS Admin
Updated 2026-07-18 11:51:35 UTC by SBS Admin