Registry
How do I publish a Katalog to the registry?
Create a pattern directory with a katalog.yaml and push it:
ork push postgres:v14 ./patterns/postgres/
The minimal directory is just katalog.yaml. In practice, include a simulate.yaml and e2e.yaml — they gate the push automatically and bake a quality signal into the artifact that consumers can see before importing.
postgres/
katalog.yaml # required
crd.yaml # recommended — CRD manifest for consumers who don't have it
cr.yaml # recommended — sample CR
simulate.yaml # runs before e2e, blocks push if assertions fail
e2e.yaml # runs against a real kind cluster, blocks push if expectations fail
README.md # shown in registry UI
→ Katalog patterns in the registry
How do I publish a Motif?
Same command — Motifs push to ORK_MOTIFS_REGISTRY instead of ORK_REGISTRY:
ork push security-baseline:v1 ./motifs/security-baseline/
If a pattern directory contains both a katalog.yaml and a motif.yaml, one push publishes both — the Katalog to the Katalog registry and the Motif to the Motif registry.
→ Motif patterns in the registry
How do simulate and e2e gate publication?
When simulate.yaml and e2e.yaml are present in a pattern directory, ork push runs them automatically — simulate first, then e2e — and blocks publication if either fails.
ork push postgres:v14 ./patterns/postgres/
→ simulate runs (< 1s, no cluster)
→ e2e runs (kind cluster, 2–5 min)
→ artifact pushed with quality annotations
The gates are ordered deliberately. Simulate is instant — it catches template errors, wrong resource names, and wrong cycle order without spinning up a cluster. E2E runs after because there is no point provisioning a cluster when the reconciler is already broken.
The result is baked into the OCI artifact:
io.orkestra.simulate.status passed | no-assertion | skipped
io.orkestra.e2e.status passed | skipped | forced
ork patterns shows an E2E column. ork inspect shows both simulate and e2e status. Consumers can see what quality guarantees a pattern carries before they import it.
To skip individual gates:
ork push postgres:v14 ./patterns/postgres/ --no-simulate # skip simulate only
ork push postgres:v14 ./patterns/postgres/ --no-e2e # skip e2e only
ork push postgres:v14 ./patterns/postgres/ --force # skip both
Skipping is recorded in the annotations — consumers can see it.
→ How simulate gates publication
→ How e2e gates publication
Can I use a private registry?
Yes — point Orkestra at any OCI-compatible registry:
export ORK_REGISTRY=oci://ghcr.io/myorg/katalogs
export ORK_MOTIFS_REGISTRY=oci://ghcr.io/myorg/motifs
Push and pull work identically. Credentials come from ~/.docker/config.json — run docker login before pushing.
How do I sign a pattern?
Push first, then sign:
ork push postgres:v14 ./patterns/postgres/
ork pattern sign postgres:v14
Or in one step:
ork push postgres:v14 ./patterns/postgres/ --sign
Signing uses Cosign keyless — no keys, no secrets. The ambient OIDC token in CI is the credential. In GitHub Actions this is the workflow identity; locally it opens a browser-based OIDC flow.
After signing, ork inspect shows the signer on the Signed: row without any
extra flags.
How do I test signing without a real registry?
Use --sign-local or ork pattern sign --local. This pushes to
ttl.sh — a free ephemeral OCI registry — signs it, and prints
the exact verify and inspect commands:
# From push
ork push postgres:v14 ./ --sign-local --ttl 24h
# Or directly
ork pattern sign postgres:v14 --local --dir ./patterns/postgres/ --ttl 24h
✓ Pushed oci://ttl.sh/ork-a3f9c2/postgres:24h
✓ Signed
Expires in 24h
Verify: ork pattern verify oci://ttl.sh/ork-a3f9c2/postgres:24h --no-tlog
Inspect: ork inspect oci://ttl.sh/ork-a3f9c2/postgres:24h
Use --no-tlog when verifying ephemeral artifacts — the Rekor transparency log
is not useful for a short-lived test artifact.
How do I require consumers to verify the signature?
Add a publish: block to katalog.yaml:
publish:
signing:
verify: true
expectedIdentities:
- github.com/myorg/postgres/.github/workflows/release.yaml@refs/heads/main
With verify: true, consumers who run ork pull --verify are blocked unless a
valid signature from one of the listed identities is present.
How do I mark a pattern as deprecated?
Set lifecycle.maturity: deprecated and fill in lifecycle.deprecation:
lifecycle:
maturity: deprecated
deprecation:
migratedTo: ghcr.io/myorg/katalogs/webapp@v2.0.0
message: "Migrate to v2.0.0 before 2027-01-01."
timeline:
from: "2026-01-01"
to: "2027-01-01"
Then push normally — ork push creates a new artifact with the deprecation metadata baked in. The previous version is not modified.
What does maturity: alpha mean for consumers?
ork validate prints a non-fatal warning when a Katalog or an imported pattern carries maturity: alpha or maturity: beta. The warning does not block validation — it is informational.
To acknowledge the warning on a Komposer, list the pattern in lifecycle.accept.patterns:
lifecycle:
accept:
patterns:
- name: cache-operator
author: myorg
How do I suppress lifecycle warnings in ork validate?
Warnings for deprecated or pre-stable imports are suppressed by declaring acceptance on the Komposer — not by a flag, and not on the Katalog itself.
lifecycle:
accept:
patterns:
- name: webapp-operator
author: myorg
Each patterns entry covers all lifecycle concerns for that import — deprecated, alpha, beta.
Further reading
- Orkestra Registry — full publishing and pulling reference
- simulate gates — how simulate quality signals work
- e2e gates — how e2e quality signals work
- Artifact Signing — keyless signing, CI setup, local testing
- Lifecycle — maturity, deprecation, compatibility, and acceptance