<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Alek&#x27;s Blog - container-registry</title>
      <link>https://blog.none.at</link>
      <description>My Blog to share my knowledge</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://blog.none.at/tags/container-registry/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Mon, 06 Jul 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Which Tool Mirrors a Cosign-Signed Image into a Private Registry?</title>
          <pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate>
          <author>aleks</author>
          <link>https://blog.none.at/blog/2026/2026-07-06-mirroring-signed-images-private-registry/</link>
          <guid>https://blog.none.at/blog/2026/2026-07-06-mirroring-signed-images-private-registry/</guid>
          <description xml:base="https://blog.none.at/blog/2026/2026-07-06-mirroring-signed-images-private-registry/">&lt;h2 id=&quot;tl-dr&quot;&gt;TL;DR&lt;a class=&quot;zola-anchor&quot; href=&quot;#tl-dr&quot; aria-label=&quot;Anchor link for: tl-dr&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;regctl&lt;&#x2F;code&gt; is the most complete option — it exposes the legacy tag-based signature scheme and the
modern OCI 1.1 referrers API as two separate, explicit flags. &lt;code&gt;oras cp -r&lt;&#x2F;code&gt; is the second choice,
and the tool cosign’s own project points to now that &lt;code&gt;cosign copy&lt;&#x2F;code&gt; is deprecated. &lt;code&gt;oc-mirror v2&lt;&#x2F;code&gt;
looks like it should be on this list but actually solves a different, unrelated signature problem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-problem&quot; aria-label=&quot;Anchor link for: the-problem&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Verifying a signature only works if the signature actually travels with the image. Anyone mirroring
a Cosign-signed image into a private or air-gapped registry needs the copy step itself to carry the
signature along, not just the layers — and that is not automatic. Some tools drop it silently, some
need a config flag turned on first, and one widely-used tool solves a related but entirely different
problem. &lt;a href=&quot;https:&#x2F;&#x2F;blog.none.at&#x2F;blog&#x2F;2026&#x2F;2026-07-06-k8s-scale-app-rs&#x2F;&quot;&gt;k8s-scale-app-rs&lt;&#x2F;a&gt; is the worked example
throughout this post — its own container images are signed keylessly with cosign, carry an SBOM and
SLSA build provenance, and its &lt;a href=&quot;https:&#x2F;&#x2F;blog.none.at&#x2F;blog&#x2F;2026&#x2F;2026-07-06-k8s-scale-app-rs&#x2F;#verifying-a-published-image&quot;&gt;“Verifying a published image”&lt;&#x2F;a&gt;
section shows what verification actually checks. This post is about what happens &lt;em&gt;before&lt;&#x2F;em&gt;
verification: getting the signature into the registry the verifier will actually query.&lt;&#x2F;p&gt;
&lt;p&gt;A short, sourced comparison, checked directly against each project’s docs&#x2F;source (as of July 2026):&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-naming-trap-worth-knowing-first&quot;&gt;A naming trap worth knowing first&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-naming-trap-worth-knowing-first&quot; aria-label=&quot;Anchor link for: a-naming-trap-worth-knowing-first&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Red Hat’s &lt;code&gt;oc-mirror v2&lt;&#x2F;code&gt; — the tool for mirroring into disconnected OpenShift installs — has its
own &lt;code&gt;--secure-policy&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;--remove-signatures&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;--registries.d&lt;&#x2F;code&gt; flags, but they implement Red Hat’s
older “simple signing” scheme: a &lt;code&gt;policy.json&lt;&#x2F;code&gt; plus GPG keys plus an external &lt;code&gt;sigstore:&lt;&#x2F;code&gt; URL (e.g.
&lt;code&gt;mirror.openshift.com&#x2F;pub&#x2F;openshift-v4&#x2F;signatures&lt;&#x2F;code&gt; for OpenShift release images). That predates,
and has nothing to do with, the CNCF Sigstore project this post’s cosign workflow uses — same word,
unrelated mechanism. &lt;code&gt;oc-mirror v2&lt;&#x2F;code&gt; went GA in OpenShift 4.18 (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.redhat.com&#x2F;en&#x2F;documentation&#x2F;openshift_container_platform&#x2F;4.18&#x2F;html&#x2F;release_notes&#x2F;ocp-4-18-release-notes&quot;&gt;release
notes&lt;&#x2F;a&gt;),
but its &lt;code&gt;ImageSetConfiguration&lt;&#x2F;code&gt; API is still &lt;code&gt;v2alpha1&lt;&#x2F;code&gt;, and none of Red Hat’s own walkthroughs for
it touch Cosign-style signatures at all.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tool-comparison&quot;&gt;Tool comparison&lt;a class=&quot;zola-anchor&quot; href=&quot;#tool-comparison&quot; aria-label=&quot;Anchor link for: tool-comparison&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Tool&lt;&#x2F;th&gt;&lt;th&gt;Legacy tag-based signature (&lt;code&gt;sha256-&amp;lt;digest&amp;gt;.sig&lt;&#x2F;code&gt;)&lt;&#x2F;th&gt;&lt;th&gt;OCI 1.1 referrers (modern Cosign&#x2F;SBOM&#x2F;attestations)&lt;&#x2F;th&gt;&lt;th&gt;Note&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;regctl.regclient.org&#x2F;cli&#x2F;regctl&#x2F;image&#x2F;copy&#x2F;&quot;&gt;&lt;code&gt;regctl image copy&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;--digest-tags&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;--referrers&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;only tool here with separate, explicit flags for both schemes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;oras.land&#x2F;docs&#x2F;commands&#x2F;oras_cp&quot;&gt;&lt;code&gt;oras cp -r&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;via &lt;code&gt;-r&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;-r&lt;&#x2F;code&gt; (marked “Preview”)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;--from&#x2F;to-distribution-spec&lt;&#x2F;code&gt; handles referrers-tag vs. referrers-API mismatches between registries&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;skopeo copy&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;opt-in&lt;&#x2F;td&gt;&lt;td&gt;not supported&lt;&#x2F;td&gt;&lt;td&gt;needs &lt;code&gt;use-sigstore-attachments: true&lt;&#x2F;code&gt; under the &lt;code&gt;default-docker&lt;&#x2F;code&gt; key in &lt;code&gt;registries.d&lt;&#x2F;code&gt;, on both source and destination&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Zot registry &lt;code&gt;sync&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;syncLegacyCosignTags&lt;&#x2F;code&gt; (default &lt;code&gt;true&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;only with &lt;code&gt;preserveDigest: true&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;without &lt;code&gt;preserveDigest&lt;&#x2F;code&gt;, Zot re-encodes Docker-format images to OCI on sync, which changes the digest and detaches the signature&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cosign copy&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;yes&lt;&#x2F;td&gt;&lt;td&gt;no&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;deprecated&lt;&#x2F;strong&gt; as of &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sigstore&#x2F;cosign&#x2F;pull&#x2F;4681&quot;&gt;sigstore&#x2F;cosign#4681&lt;&#x2F;a&gt; (merged 2026-02-04) — the tool itself now points to &lt;code&gt;oras copy -r&lt;&#x2F;code&gt; instead&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;crane copy&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;only incidentally, via &lt;code&gt;--all-tags&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;no&lt;&#x2F;td&gt;&lt;td&gt;plain manifest&#x2F;layer copier, no signature awareness at all&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Harbor replication&lt;&#x2F;td&gt;&lt;td&gt;per Harbor’s own docs, yes&lt;&#x2F;td&gt;&lt;td&gt;open gap (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;goharbor&#x2F;harbor&#x2F;issues&#x2F;23210&quot;&gt;goharbor&#x2F;harbor#23210&lt;&#x2F;a&gt;)&lt;&#x2F;td&gt;&lt;td&gt;works for the legacy scheme; OCI 1.1 referrers replication is not yet reliable&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;code&gt;regctl&lt;&#x2F;code&gt; is the only tool in this comparison that exposes both signature schemes as distinct,
intentional flags rather than as a side effect of copying “everything.” For a registry pair that
already speaks the OCI 1.1 referrers API end to end, &lt;code&gt;oras cp -r&lt;&#x2F;code&gt; is the other option worth
checking — it’s what the cosign project’s own deprecation notice for &lt;code&gt;cosign copy&lt;&#x2F;code&gt; points to.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-mirroring-with-regctl&quot;&gt;Example: mirroring with regctl&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-mirroring-with-regctl&quot; aria-label=&quot;Anchor link for: example-mirroring-with-regctl&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Here is an example command to mirror &lt;code&gt;k8s-scale-app-rs&lt;&#x2F;code&gt; itself, signature included, using &lt;code&gt;regctl&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;regctl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; image&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;-digest-tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;-referrers&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  ghcr.io&#x2F;git001&#x2F;k8s-scale-app-rs:v1.0.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  my-private-registry.example.com&#x2F;k8s-scale-app-rs:v1.0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sigstore&#x2F;cosign&#x2F;pull&#x2F;4681&quot;&gt;sigstore&#x2F;cosign PR #4681 — “Deprecate cosign copy”&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sigstore&#x2F;cosign&#x2F;issues&#x2F;4335&quot;&gt;sigstore&#x2F;cosign#4335 — Complete OCI 1.1 Referrers API Support Across All Cosign Commands&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sigstore&#x2F;cosign&#x2F;issues&#x2F;4564&quot;&gt;sigstore&#x2F;cosign#4564 — cosign verify fails after cosign copy (JFrog Artifactory)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;podman-container-tools&#x2F;skopeo&#x2F;issues&#x2F;2061&quot;&gt;podman-container-tools&#x2F;skopeo#2061 — sigstore signature copying and &lt;code&gt;use-sigstore-attachments&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;regctl.regclient.org&#x2F;cli&#x2F;regctl&#x2F;image&#x2F;copy&#x2F;&quot;&gt;regctl &lt;code&gt;image copy&lt;&#x2F;code&gt; reference&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;oras.land&#x2F;docs&#x2F;commands&#x2F;oras_cp&quot;&gt;oras &lt;code&gt;cp&lt;&#x2F;code&gt; command reference&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;goharbor&#x2F;harbor&#x2F;issues&#x2F;23210&quot;&gt;goharbor&#x2F;harbor#23210 — OCI 1.1 referrers not replicated&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zotregistry.dev&#x2F;v2.1.14&#x2F;articles&#x2F;mirroring&#x2F;&quot;&gt;Zot registry: mirroring&#x2F;sync documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.redhat.com&#x2F;en&#x2F;documentation&#x2F;openshift_container_platform&#x2F;4.18&#x2F;html&#x2F;release_notes&#x2F;ocp-4-18-release-notes&quot;&gt;OpenShift Container Platform 4.18 release notes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openshift&#x2F;oc-mirror&#x2F;blob&#x2F;main&#x2F;docs&#x2F;features&#x2F;signature-verification.md&quot;&gt;openshift&#x2F;oc-mirror — signature-verification.md&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
    </channel>
</rss>
