# Container Registry and Software Supply Chain Platform

**Solution Architecture v1.0 · Data & AI Global Practice · 2026-09 · 33 views · open-source, on-premises**

One trusted path from a source commit to a running workload, and machine-checkable evidence that the path was followed. The requirement named AWS as its target; this set answers it with an open-source stack the team runs on its own hardware — Harbor and MinIO for artifacts, Sigstore (Fulcio, Rekor, Cosign) for signing and transparency, Tekton Chains for provenance, Syft for SBOMs, Trivy and Grype for scanning, OSV and distro feeds reconciled into one advisory record, OPA for policy, Kafka for evidence distribution, ClickHouse for the component index, PostgreSQL for registry metadata, Vault with a PKCS#11 HSM for key custody, SPIRE and Keycloak for identity.

One decision carries the whole design: **the registry stores evidence, never a verdict; the verdict is computed at the enforcement point, at admission, from the evidence current at that moment.** Every alternative collapses into a stored boolean that was true when it was written and decays silently afterwards. Making the verdict computed rather than stored is what forces the edge caching, the degraded modes, the append-only evidence store and revocation-instead-of-deletion that the rest of the set spends its pages on.

---

## What is here

| Path | Contents |
|---|---|
| `diagrams/index.html` | The view index — 33 views grouped into six acts, every format linked |
| `diagrams/*.html` | One self-contained page per view: the inlined diagram plus the reasoning it deliberately omits, with copy / PNG / PDF export |
| `diagrams/svg/*.svg` | The same 33 views as SVG with the diagram XML embedded — re-opens in diagrams.net fully editable |
| `diagrams/drawio/*.drawio` | draw.io native source |
| `specs/views.json` | Diagram specifications — the source of truth for every view (assembled from `part-a..f.json`) |
| `specs/manifest.json` | Acts, page titles, subtitles and the decision / assumption / risk cards (assembled from `manifest-a..b.json`) |
| `scripts/build.sh` | Rebuilds every deliverable from the specs |
| `scripts/pin-icons.mjs` | Pins one mark per component so the same box carries the same icon on every page |
| `ask.md` | The original requirement |

536 icons are embedded in the files, so the deliverable renders identically anywhere with no network request. Each view page links to its own SVG and draw.io source, back to the index, and to the previous and next view.

To rebuild after editing a spec:

```bash
node scripts/pin-icons.mjs     # only after adding new component labels
bash scripts/build.sh          # Node 20+ and nothing else
```

Edit `specs/part-a.json` … `part-f.json` and `specs/manifest-a.json` / `manifest-b.json`; the build script assembles `views.json` and `manifest.json` from them and fails if the two lists disagree.

---

## The six acts

| Act | What it lands | Views |
|---|---|---|
| 1 · Context and scope | The boundary, the producers and consumers, and the plane separation that governs everything after it | 01–03 |
| 2 · Structure | The layering rule, the deployable units, every interface, the OCI artifact model, and how policy becomes reviewed data | 04–09 |
| 3 · Data | Which store is authoritative, what is rebuildable, the model a decision reads, and how it moves across regions | 10–14 |
| 4 · Runtime | Build and attest, scan, admit, reconcile advisories, re-evaluate, verify offline, promote, and expire an exception | 15–22 |
| 5 · Operations | Where it runs, how it ships itself, how a pull storm is absorbed, what is watched, and the operator's loop | 23–27 |
| 6 · Assurance | Trust zones, credential issue, key custody, revocation, tenant isolation, and every named failure mode | 28–33 |

---

## The 33 views

| # | View | Layout | What it answers |
|---|---|---|---|
| 01 | System Context | context | Who produces artifacts, who consumes them, what the platform never owns |
| 02 | High-Level Architecture | flow | The path from a commit to an admitted pod, and every AWS service replaced by an open-source one |
| 03 | The Four Planes | nested | Why the artifact/evidence boundary is the load-bearing seam of the whole system |
| 04 | Layered Architecture | bands | What depends on what, and why evidence reaches the edge by subscription rather than an upward call |
| 05 | Container and Component Architecture | nested | Every deployable unit, its technology and its replica count |
| 06 | Integration and Interface Catalogue | hub | Every way something enters or leaves, with protocol and cadence |
| 07 | OCI Artifact Model | nested | How tag, digest and referrers relate, and why only the digest is an identity |
| 08 | Evidence Plane Pipeline | flow | What happens to evidence between arriving and being usable at an enforcement point |
| 09 | Policy Bundle Lifecycle | cycle | How a rule change reaches every enforcement point without becoming an outage |
| 10 | Data Architecture and Storage Zones | nested | Which store is the system of record and what backup actually has to cover |
| 11 | Evidence Data Model | er | The entities a decision reads, and the two columns that cannot be null |
| 12 | Supply Chain Data Flow | flow | Where each kind of data comes from, what it becomes, and how long it is kept |
| 13 | Component Index | grid | How "which images contain X" stays bounded, and where reachability is and is not available |
| 14 | Multi-Region Topology | nested | What replicates, what caches, and what an artifact does when its evidence has not arrived |
| 15 | Build to Attested Push | sequence | How an image acquires provenance, an SBOM, a signature and an inclusion proof |
| 16 | Scan Pipeline | flow | Ten-minute verdicts at 2,500 builds a day without scanning the same base layer 2,500 times |
| 17 | Admission Decision | sequence | The one flow that must be fast, correct and available — and what it does when it cannot be all three |
| 18 | Advisory Ingest and Reconciliation | swimlane | Two feeds, one advisory record, and what happens when they disagree |
| 19 | Advisory-Driven Re-Evaluation | flow | What happens when the world's knowledge changes and the image does not |
| 20 | Air-Gapped Verification | sequence | Deciding with only the artifact, its evidence, the inclusion proof and the trust roots |
| 21 | Promotion, Demotion and Retention | flow | Moving between environments without a rebuild, a re-tag, or a stored "approved" flag |
| 22 | Exceptions and Suppressions | cycle | Saying yes without creating a permanent hole |
| 23 | Deployment and Infrastructure | nested | What runs where, on hardware the team owns, and which failure domains that creates |
| 24 | Delivery of the Platform Itself | flow | The platform as its own first customer, and the bootstrap rule that makes that safe |
| 25 | Pull Path and Storm Absorption | nested | 250,000 pulls an hour for the same digest, and the one case caching does not solve |
| 26 | Observability and Operations | grid | Which signals exist, where they go, and which of them wake somebody up |
| 27 | The Operator Loop | cycle | Turning a violation count into a fixed image, and base-image lineage as composition |
| 28 | Security Trust Zones | zones | Where the boundaries are and where an attacker actually arrives |
| 29 | Workload Identity and Credentials | sequence | How a build proves what it is, and how short-lived every credential it gets is |
| 30 | Key Management and Trust Roots | nested | Which keys exist, who holds them, and what rotation does to signatures already made |
| 31 | Revocation Propagation | flow | Stopping trust in a compromised builder in minutes, without deleting anything |
| 32 | Tenant Isolation | nested | Four layers, and the one place content addressing leaks an existence oracle |
| 33 | Failure Modes and Degraded Operation | grid | Every named failure class, its detection, its handling, and what risk is left |

---

## The seven core architecture questions, answered

| # | Question | Answer, and where it is argued |
|---|---|---|
| 1 | Where is the enforcement point, and what does it do when blind? | Cluster admission webhook on Pod create, so controller-created workloads cannot route around it. Beyond 30 minutes of cache staleness the environment's stated posture applies — fail-closed in production. **View 17** |
| 2 | Verdict computed at admission, or precomputed? | Computed at admission. What is precomputed and pushed to the edge is the *evidence*, compacted, never the verdict. **View 08** |
| 3 | Keyless certificates or long-lived keys? | Both, deliberately. Fulcio keyless for the normal path; HSM-held long-lived keys for the air-gapped and base-image release paths. **Views 15, 20, 30** |
| 4 | How is the corpus re-evaluated when the feed moves? | Index-driven matching, fanning out only to affected digests — roughly 120 of 40,000 per advisory. **Views 13, 19** |
| 5 | Who resolves tag to digest, and when? | CI resolves and pins; production admission denies a tag-only reference outright. **View 07** |
| 6 | Replicate, cache, or centralise across regions? | Blobs cache, evidence replicates ordered per subject, metadata stays regional with one write region per repository. **View 14** |
| 7 | Base-image lineage: composition or flat SBOM? | Composition, indexed by layer digest, which is what makes remediation a single fact rather than a ticket per image. **Views 13, 27** |

---

## Stated assumptions

Everything below is an assumption chosen to be defensible and arguable rather than absent, and should be revised against real telemetry before build.

- 1,200 repositories, 40,000 retained artifact versions, 14 TB of blobs, ~90 MB/day of new evidence.
- 900 builds/day steady, 2,500 on release days; 25,000 pulls/hour steady, 250,000/hour for 10 minutes on a regional scale-out; 400 admission reviews/second per cluster, 2,000/second burst.
- Two data centres, one write region per repository, plus air-gapped edge sites reached by signed transport.
- GitLab, Keycloak and SPIRE already exist in the estate and are not built here.
- 7-year retention for attestations and audit records is audit-driven, not engineering-driven, and has not been confirmed against the actual obligation.
- Tenant classes are coarse (internal, regulated, third-party) rather than per-team, to bound the cost of scoping layer deduplication.

## What still needs a decision from the business

1. Whether development environments really tolerate a fail-open posture, or whether that is convenience arguing with the threat model.
2. Whether a changed verdict should evict running workloads, and who owns the disruption budget if it does. Drawn as a risk in views 19 and 31; deferred to phase 3.
3. Whether 7-year retention is what audit requires.
4. Whether base-image ownership is a real organisational role. View 27's remediation fan-out assumes it is; if it is not, the loop does not close.
