Supply chain¶
Portal v1 ships a single Go binary in a distroless container. This page documents what's in place today and what's deliberately deferred to v2.
What's in place today (v1)¶
Distroless base image¶
The image uses Google's gcr.io/distroless/static-debian12:nonroot (or equivalent). No shell, no package manager, no userspace utilities — just the Portal binary and the trust bundle. The container runs as a non-root user.
Implications:
- Reduced attack surface — no
/bin/sh, nokubectl, nocurl. - Smaller image (~20 MB).
- Forensics need a debug sidecar or
kubectl debug --image=...if you want a shell.
Reproducible builds¶
The go build invocation pins the Go version (1.22+ per go.mod) and uses -trimpath so the binary doesn't embed local paths. Combined with GOFLAGS=-mod=readonly, the same source tree produces the same binary byte-for-byte across builders.
go.sum integrity¶
Every dependency is pinned by content hash in go.sum. CI rejects PRs that modify go.sum without a corresponding go.mod change. The Go toolchain enforces the hash on every go build / go test.
Vulnerability scanning hooks¶
The CI workflow (see .github/workflows/ci.yml) runs go vet and go test -race. Adding govulncheck is straightforward and is a v1 task once the GH org is ready to take the signal — left as a TODO so this doc doesn't lie about what's there.
What is not in place (v2 candidates)¶
SBOM generation — TODO¶
There is no make sbom target today. The plan:
- Adopt
syftto emit CycloneDX or SPDX from the built image. - Publish the SBOM alongside each tagged release as a release asset.
- Sign the SBOM with the same key used for image signing.
Tracking issue: v2-candidates/supply-chain-sbom.
Image signing — TODO¶
There is no cosign signature on Portal images today. The plan:
- Sign every released image with
cosign sign --keylessusing GitHub's OIDC identity. - Publish the signature alongside the image in the GHCR registry.
- Document a Kyverno or sigstore-policy-controller manifest in
docs/cookbook/that operators can use to enforce signature presence at admission.
Tracking issue: v2-candidates/supply-chain-signing.
Container image attestation — TODO¶
provenance attestation (SLSA build provenance, also via cosign) is on the same v2 track as signing. See the same tracking issue.
What you should still do at the consumer end¶
Until v2 closes the gaps above:
- Mirror Portal images to your own registry rather than pulling directly from upstream. Pin by digest (
@sha256:...), not by tag. - Run your own scanner against the mirrored image (Trivy, Grype). Distroless is small, so scans are quick.
- Compare
go.modagainst your dependency policy if you ship internal-software-only. Portal pulls fromk8s.io,prometheus,expr-lang,sigs.k8s.io— well-known upstream. - Track the v2 supply-chain milestone — when image signing lands, integrate it into your sigstore/Kyverno policy.
For threat-model context see threat-model.md; for responsible disclosure see responsible-disclosure.md.