quorate/docs/spec/mirrored-image-spec.md

4.4 KiB

MirroredImage Specification

Boundary

Concern Requirement
Controller A dedicated controller Deployment and service account watch MirroredImage; the Project Delivery controller does not.
Isolation Mirrored Image and Project Delivery controller pods remain separate because their permissions and owned resources differ.
Reuse Generic Go libraries and the F# runner may be shared; controller state machines remain separate.
Intent One MirroredImage owns one upstream repository.
Destination The corresponding Quay repositories are candidates/<metadata.name> and mirror/<metadata.name>.
Credentials Two Zitadel-backed Quay personas isolate OAuth authority by organization; four assigned tokens isolate it by privilege.
New work The MirroredImage API, controller state machine, Argo Workflows, and tests are independent work.
Excluded input Smeltery specifications, implementation, workflows, and tests are not inputs.
Workload policy Workload image-reference policy is outside the controller; Kyverno governs workload declarations.

Declaration

kind: MirroredImage
metadata:
  name: ingress-nginx
spec:
  upstream: registry.k8s.io/ingress-nginx/controller
  policy:
    rejectAtOrAbove: High
  digests:
    - digest: sha256:...
      tag: v1.13.0
    - digest: sha256:...

Quay authorization

OAuth application scopes are privilege boundaries, not organization boundaries. Each token acts as its assigned persona, and each persona has Quay authority only within its corresponding organization.

Persona Quay resource boundary Token OAuth scope
mirror-bot mirror only mirror-reader repo:read
mirror-bot mirror only mirror-writer repo:create, repo:write
candidates-bot candidates only candidates-reader repo:read
candidates-bot candidates only candidates-writer repo:create, repo:write

The reader and writer tokens are distinct credentials despite being assigned to the same persona. Neither persona has Quay authority in quorate or in the other mirror organization.

Quay treats repo:write as including repo:read; each writer token therefore has create, read, and write authority inside its persona's organization.

Runtime Quay credentials
Controller candidates-reader, mirror-reader
Prepare Workflow candidates-writer
Promote Workflow candidates-reader, mirror-writer
Candidate GC candidates-writer
Mirror GC mirror-writer

Models

Workflow interface

Argo Workflow Stages
Prepare Prepare
Promotion Promote
Cleanup Candidate GC, Mirror GC
Field Type
retryOf Workflow-name reference
mirror.quorate.dev/retry Workflow-name reference
status.lastHandledRetry Workflow-name reference

Scan inputs

Image shape ClairInputs
Single manifest Candidate manifest
OCI index Child manifests
\mathrm{Safe} \iff \forall m \in \mathrm{ClairInputs}:\ \mathrm{ReportAvailable}(m) \land \forall v \in \mathrm{Findings}(m):\ \mathrm{severity}(v) < \mathrm{spec.policy.rejectAtOrAbove}