Delivery
CI/CD & the supply chain
Status: partial — the pipeline builds, signs, and scans end-to-end. Digest pinning is blocked (run 36876895467) and Kyverno remains Audit, not Enforce.
Inside this chapter
Start here
The jobs this chain does for you
This is the journey your code takes — from a commit on your machine to a running pod on the floor, built, signed, and scanned on the way. Pick the step you came for.
Concepts
How the chain works, and why
How it ships today
-
Push to Git
Every change starts as a commit on the app repo.
-
GitHub Actions — self-hosted runner
The org runner on pro builds, signs, and scans the image (2026-11-01, lab-monorepo#102).
-
Argo CD syncs to CRC
OpenShift GitOps reconciles the app namespace from the IAC repo (current refs — signed digest pin is blocked).
Live · rhels/team#107
-
Harbor registry
Enterprise image registry on the tooling plane — the single place images live.
rhels/team#107
-
Cosign signing
Keyless signing via GitHub OIDC — every image carries a verifiable signature.
rhels/team#107 · run 36876895467 succeeded
-
Trivy scanning
Vulnerability scans gate promotion, not just report it.
rhels/team#107 · run 36876895467 succeeded
-
Kyverno verifyImages
ClusterPolicy require-signed-images in app* namespaces is Audit, not Enforce. Unsigned images are reported, not rejected.
GitOps c5d749f · validationFailureAction: Audit
Design principle
The design principle: nothing should reach the workload cluster unsigned. The digest in the IaC repo is not enough
on its own — the image must also be signed (Cosign), scanned (Trivy), and admitted
(Kyverno verifyImages) before a pod starts in
any app* namespace. Kyverno audits today and enforces next;
digest pinning is the other half of the #107 final mile (blocked on Actions
run 36876895467; ClusterPolicy require-signed-images is
Audit, not Enforce — unsigned images are not rejected).
Reference
The flow, as data
The chain as recorded in the inventory — every status below carries its evidence (a run, a commit), and the blocked steps are printed, not hidden.
End-to-end flow
-
git push
source
-
GitHub Actions (self-hosted mini-k8s)
build
-
build + push to Harbor
registry
-
Cosign sign (keyless, GitHub OIDC)
sign
-
Trivy scan
scan
-
digest written to IAC repo
pin
blocked
-
Argo CD syncs to CRC
deploy
-
Kyverno verifyImages in app* namespaces
admit
audit
- rhels/team#107
- rhels/local-k8s-gitops Actions run 36876895467 (headSha c5d749f586d43640a61591f0bcdb94ac04d98e0d) — failed at Pin digest in IAC repo after build/push, Cosign, and Trivy succeeded
- GitOps main c5d749f586d43640a61591f0bcdb94ac04d98e0d clusters/crc/security/require-signed-images-policy.yaml — validationFailureAction: Audit (not Enforce)
- blocked — digest written to IAC repo : failed at Pin digest in IAC repo — rhels/local-k8s-gitops Actions run 36876895467
- audit — Kyverno verifyImages in app* namespaces : validationFailureAction: Audit (not Enforce) — GitOps c5d749f586d43640a61591f0bcdb94ac04d98e0d require-signed-images-policy.yaml
Next chapter
4. Observability
Shipping is only half the story. Next, the watchtower: how the lab sees what it ships.
Read Chapter 4: Observability →