<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <docs>https://blogs.law.harvard.edu/tech/rss</docs>
    <title>Zot on Fuchsbau</title>
    <link>https://this-is-fine.io/tags/zot/</link>
    <description>Recent content in Zot on Fuchsbau</description>
    <image>
      <title>Zot on Fuchsbau</title>
      <link>https://this-is-fine.io/tags/zot/</link>
      <url>https://source.unsplash.com/2000x1322/?fox</url>
    </image>
    <ttl>1440</ttl>
    <generator>Hugo 0.125.4</generator>
    <language>de-DE</language>
    <lastBuildDate>Wed, 20 May 2026 22:26:12 UT</lastBuildDate>
    <atom:link href="https://this-is-fine.io/tags/zot/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Pocket ID as the Lab OIDC Provider (Zot Example)</title>
      <link>https://this-is-fine.io/posts/20251122-pocket-id-oidc-zot/</link>
      <pubDate>Sat, 22 Nov 2025 11:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251122-pocket-id-oidc-zot/</guid>
      <description>Pocket ID is a small OpenID Connect provider — enough for a homelab without Keycloak. The lab runs it at https://auth.this-is-fine.io with Flux and an HTTPRoute on Envoy Gateway. Below is how Zot uses native OpenID against that issuer.
If you already run a homelab IdP, the interesting part is how little application code must change when the app speaks OIDC natively. Zot is a clear example: configure issuer URL, client ID, and redirect URIs, mount a secret, and the registry UI handles login without an OAuth sidecar in front of it.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <content:encoded><![CDATA[Pocket ID is a small OpenID Connect provider — enough for a homelab without Keycloak. The lab runs it at https://auth.this-is-fine.io with Flux and an HTTPRoute on Envoy Gateway. Below is how Zot uses native OpenID against that issuer.
If you already run a homelab IdP, the interesting part is how little application code must change when the app speaks OIDC natively. Zot is a clear example: configure issuer URL, client ID, and redirect URIs, mount a secret, and the registry UI handles login without an OAuth sidecar in front of it.
Software map Piece Link Role Pocket ID pocket-id.org Users, OAuth clients, consent UI OIDC primer OpenID Connect Issuer, client_id, redirect URIs Zot OpenID Zot auth Registry login Pocket ID on the cluster browser -&amp;gt; auth.this-is-fine.io -&amp;gt; Pocket ID (PVC-backed) -&amp;gt; /.well-known/openid-configuration Public route on shared-gateway-external; TRUST_PROXY=true behind Cloudflare. Optional VolSync backup for the PVC. Encryption key and client credentials via SOPS, same as other apps. Register each OAuth client in Pocket ID (redirect URL and scopes) before switching the app on. A mismatch on redirect URI is the most common first-login failure; fix it in Pocket ID, not in Zot’s logs alone.
Zot: native OpenID Zot at oci.this-is-fine.io reads OpenID from zot.json — no Envoy OIDC shim for the registry UI.
&amp;#34;openid&amp;#34;: { &amp;#34;providers&amp;#34;: { &amp;#34;oidc&amp;#34;: { &amp;#34;issuer&amp;#34;: &amp;#34;https://auth.this-is-fine.io&amp;#34;, &amp;#34;scopes&amp;#34;: [&amp;#34;openid&amp;#34;, &amp;#34;profile&amp;#34;, &amp;#34;email&amp;#34;] } } } A Kubernetes Secret mounts the client credentials file. htpasswd stays for robots (buildbot, CI); people use SSO. RBAC maps OIDC groups (admins, users) to registry roles.
human -&amp;gt; oci.this-is-fine.io -&amp;gt; redirect -&amp;gt; auth.this-is-fine.io &amp;lt;- authorization code / token automation -&amp;gt; htpasswd or robot account (unchanged) People through Pocket ID; automation through scoped local accounts — a useful split elsewhere too.
Headscale OIDC is on the backlog (Envoy post notes the TODO): the chart already has placeholder environment variables; enabling them means registering another client in Pocket ID and trusting the same issuer URL.
Related Zot vs Harbor Cosign enforcement Lab GitOps Pocket ID: installation, OIDC clients.
]]></content:encoded>
    </item>
    <item>
      <title>From Harbor to Zot on ARM64</title>
      <link>https://this-is-fine.io/posts/20251122-zot-instead-of-harbor/</link>
      <pubDate>Sat, 22 Nov 2025 10:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251122-zot-instead-of-harbor/</guid>
      <description>Harbor is a full registry product: scanning, replication, projects, and several backing services. On aarch64 it is also heavy, and it was a poor fit for four RK1 boards (ARM support is still catching up). After moving Talos from x86-64 to ARM64, Harbor stayed disabled in Git; Zot serves oci.this-is-fine.io instead.
Harbor shines when you want built-in scanning UI, replication policies, and a large operations surface. The lab mainly needed push, pull, sign, and admit — a smaller registry that speaks OCI and runs comfortably on ARM boards was the better fit.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <content:encoded><![CDATA[Harbor is a full registry product: scanning, replication, projects, and several backing services. On aarch64 it is also heavy, and it was a poor fit for four RK1 boards (ARM support is still catching up). After moving Talos from x86-64 to ARM64, Harbor stayed disabled in Git; Zot serves oci.this-is-fine.io instead.
Harbor shines when you want built-in scanning UI, replication policies, and a large operations surface. The lab mainly needed push, pull, sign, and admit — a smaller registry that speaks OCI and runs comfortably on ARM boards was the better fit.
Harbor vs Zot Harbor (planned) Zot (running) Footprint Many pods (core, jobs, DB, Redis, &amp;hellip;) One registry process &#43; PVC ARM64 Not deployed here Fits the lab boards API Harbor-specific OCI — crane, skopeo, cosign GitOps Large Helm stack Slim release &#43; zot.json Hostname hub.this-is-fine.io (unused) oci.this-is-fine.io Harbor manifests remain in the repo for reference; the apps overlay does not enable them.
What Zot provides OCI-native push and pull (CI uses skopeo, not docker push — see Cosign &#43; Kyverno). Cosign signature storage and trust configuration. Optional Trivy search for CVE metadata. OpenID through Pocket ID for humans; htpasswd and robot users for automation. forge CI -&amp;gt; skopeo push oci.this-is-fine.io/zeroclaw/... -&amp;gt; cosign sign -&amp;gt; Kyverno verifyImages on pull Ingress is an HTTPRoute on shared-gateway-external. Large layer uploads use a long-timeout Envoy BackendTrafficPolicy.
CI robots authenticate with htpasswd while humans use OIDC (Pocket ID). That separation matters when Kyverno enforces signatures on pull: machines and people use different paths, but the same registry hostname.
What carried over Harbor projects and replication rules do not migrate literally, but OCI tags and cosign signatures do. The lab cared about:
Images built for the same architecture as the nodes (arm64 in .build.yml). Kyverno enforcing signatures on oci.this-is-fine.io/*. Lower RAM on a cluster that also runs Ceph, Mastodon, and monitoring. Related Envoy Gateway Pocket ID &#43; Zot ZeroClaw Docs: Zot configuration, why Zot.
]]></content:encoded>
    </item>
    <item>
      <title>Cosign and Kyverno for ZeroClaw Container Images</title>
      <link>https://this-is-fine.io/posts/20251121-cosign-kyverno-zeroclaw/</link>
      <pubDate>Fri, 21 Nov 2025 12:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251121-cosign-kyverno-zeroclaw/</guid>
      <description>For images you build yourself, a practical supply-chain loop is: build in CI, sign the digest, verify at admission. The lab uses Cosign (Sigstore), a private Zot registry at oci.this-is-fine.io, and Kyverno verifyImages so unsigned ZeroClaw pods do not start.
CI holds the private signing key; the cluster policy carries the matching public key.
Signing answers a simple question: did this image come from your build pipeline? Scanning for CVEs is still worth doing, but signature verification stops casual image substitution even when a tag name looks familiar.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <category domain="https://this-is-fine.io/categories/security">Security</category>
      <content:encoded><![CDATA[For images you build yourself, a practical supply-chain loop is: build in CI, sign the digest, verify at admission. The lab uses Cosign (Sigstore), a private Zot registry at oci.this-is-fine.io, and Kyverno verifyImages so unsigned ZeroClaw pods do not start.
CI holds the private signing key; the cluster policy carries the matching public key.
Signing answers a simple question: did this image come from your build pipeline? Scanning for CVEs is still worth doing, but signature verification stops casual image substitution even when a tag name looks familiar.
Concepts Tool What you learn Cosign Sign OCI digests; signatures stay with the image Zot OCI registry that stores signature artifacts Kyverno Admission policy; verifyImages runs Cosign verify Keyless (Flux) Sigstore OIDC — separate rule for Flux controller images CI pipeline git push -&amp;gt; build image -&amp;gt; push to oci.this-is-fine.io/zeroclaw/... -&amp;gt; cosign sign digest (sha256:...) Sign the digest, not only a moving tag. Tags like :latest can be repointed; a signature on sha256:… stays tied to the bits you tested in CI.
Forge CI builds multi-arch images when needed, pushes with skopeo, then signs. Zot stores the signature artifact next to the image so cosign verify works from a laptop or from Kyverno inside the cluster.
Admission Pod CREATE -&amp;gt; Kyverno checks oci.this-is-fine.io/* -&amp;gt; cosign verify (public key in ClusterPolicy) -&amp;gt; reject OR pull and start Two policies in practice: a static key for images you build (ZeroClaw, workspace, and anything else on Zot); keyless verification for upstream Flux controllers. Do not mix the rules.
When verification fails, the Pod never starts. kubectl describe on the ReplicaSet usually points at Kyverno; PolicyReport resources summarize which rule blocked the image. Fixing it means either signing the image you meant to run or adjusting the policy — not disabling admission quietly.
Rotation means a new key pair, updated CI secret, updated policy PEM, and re-signed digests you still deploy. References: Cosign keys, Kyverno verifyImages.
]]></content:encoded>
    </item>
  </channel>
</rss>
