**RESOLVED 2026-07-12 (w6 follow-ups).** Opt-in tenant-image signing landed in the build Job (lego/operator/internal/build/build.go): with BEX_TENANT_SIGNING_KEY_SECRET set, build+push moves to an initContainer and a cosign container signs the pushed image as the main container (k8s runs init→main sequentially). Off by default (existing builds byte-identical). Admission-time verification remains the open half.

# Sign CNB tenant images in-cluster — from w6/m6/t002 (supply chain)

w6/m6 added cosign keyless signing + SPDX SBOM to the **platform** images
(operator, dashboard) in `.github/workflows/deploy.yml`. The **tenant** images —
built in-cluster via BuildKit/CNB and pushed to the internal Zot registry
(`bex-registry`, `docs/deployment.md`) — are still unsigned.

Why deferred (not done in-milestone):

- **No OIDC identity.** Keyless signing needs a verifiable identity (GitHub
  Actions OIDC for the platform images). The in-cluster BuildKit build Job has
  no such identity — Zot is an internal registry, not a public one with a
  trust root.
- **Admission verification is out of scope.** Signing tenant images only helps
  if a deploy/admission controller verifies the signature; that's explicitly
  out of scope for t002 (`docs/ADR028-security-review.md` §2 Out of scope).

**Path to close it:** inject a cosign signing key (out-of-band, in a Secret) into
the build Job in `lego/operator/internal/build/build.go` and `cosign sign` the
pushed tenant image; then add admission-time verification (a policy controller /
ValidatingAdmissionPolicy) before rolling tenant pods. Both are real work — file
as a milestone when tenant-image provenance becomes a requirement.

Source: w6/m6/t002 supply-chain task, 2026-07-11.
