ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
85
docs/spec/mirrored-image-spec.md
Normal file
85
docs/spec/mirrored-image-spec.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# 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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
- [MirroredImage.tla](mirrored-image/MirroredImage.tla)
|
||||
- [RetentionTags.tla](mirrored-image/RetentionTags.tla)
|
||||
- [TagExpiry.tla](mirrored-image/TagExpiry.tla)
|
||||
|
||||
## 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 |
|
||||
|
||||
```math
|
||||
\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}
|
||||
```
|
||||
Loading…
Reference in a new issue