<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Supplychain · XB Field Notes</title><link>https://hk.xbcatm.com/tags/supplychain/</link><description>Illustrated field notes on HTTP, DNS, TLS, Caddy, SSH, releases, and recovery.</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://hk.xbcatm.com/tags/supplychain/index.xml" rel="self" type="application/rss+xml"/><item><title>Image signatures bind a digest to a trusted signer</title><link>https://hk.xbcatm.com/posts/signed-images-prove-who-built-them/</link><pubDate>Thu, 21 Oct 2027 00:00:00 +0000</pubDate><guid>https://hk.xbcatm.com/posts/signed-images-prove-who-built-them/</guid><description>Verify the exact image digest and an authorized signer; build provenance and content safety require additional evidence.</description><content:encoded>&lt;p&gt;A container image tag is a mutable pointer; a digest identifies content. A valid signature binds a signed statement about that digest to a signing key. Whether that key represents an authorized person or workload is a trust-policy decision. Signing alone does not prove who built the image, that the build followed a claimed process, or that the resulting software is safe.&lt;/p&gt;
&lt;p&gt;The useful boundary is the verifier&amp;rsquo;s decision before deployment. It must check the content binding and the intended trust root, then apply the required identity and provenance policy. A registry location, a familiar tag, or the existence of a signature is insufficient.&lt;/p&gt;
&lt;h2 id="digests-are-the-identity-tags-are-pointers"&gt;Digests are the identity, tags are pointers&lt;/h2&gt;
&lt;p&gt;An OCI manifest digest hashes the manifest bytes. Descriptors in that manifest identify configuration and layers by their own digests; clients must check those bindings too. A changed manifest has a different digest under the collision-resistance assumption. Mutating a stored blob without updating its descriptor should cause a content-integrity failure, not silently redefine the image.&lt;/p&gt;
&lt;p&gt;Cosign&amp;rsquo;s normal image-signature payload contains the image digest, which verification checks against the requested image. Different tags can resolve to the same signed digest. If a tag moves, the previously verified digest says nothing about the newly resolved object. Resolve and verify the intended digest, then deploy that same digest; a later tag lookup leaves a race between checking and use.&lt;/p&gt;
&lt;h2 id="signing-a-tag-binds-nothing"&gt;A tag string does not bind image content&lt;/h2&gt;
&lt;p&gt;A signature over the literal string app:v2 authenticates that statement, not the changing object behind it. A signature can include other contextual claims, so inspect its actual format and verifier behavior. Do not disable digest-claim checks merely to make an unrelated payload pass.&lt;/p&gt;
&lt;p&gt;For key-based verification, policy must establish why the supplied public key is trusted. For keyless verification, check the expected certificate identity and OIDC issuer as well as the certificate chain and required transparency evidence. Fulcio certificates associate an identity with a key; they do not inspect a build or certify its output. A build claim requires suitable provenance, a trusted builder, and checks that the attested subject matches the artifact.&lt;/p&gt;
&lt;h2 id="verification-is-the-control-not-the-signature"&gt;Verification is the control, not the signature&lt;/h2&gt;
&lt;p&gt;Enforcement can happen at admission or before deployment, but only within the configured scope. Confirm which workloads and registries are covered and how verification failures are handled. Merely recording a digest does not establish authorization, and even a correctly verified signature does not detect every vulnerability or malicious behavior in signed software.&lt;/p&gt;
&lt;p&gt;Cryptographic signature validity and current policy acceptance are separate. Retiring a key requires changing the accepted trust policy; generating a replacement key alone does not update every verifier. Short-lived certificates and trusted signing-time evidence can support verification of historical signatures after certificate expiry. Transparency makes signing activity inspectable, but does not automatically revoke compromised identities or block malicious releases. Incident response must decide which identities, time windows, digests, and attestations remain acceptable.&lt;/p&gt;
&lt;h2 id="when-it-breaks"&gt;When it breaks&lt;/h2&gt;
&lt;p&gt;A deploy step verifies one digest and later pulls a mutable tag. Another push can change the deployed bytes after verification. Pin the verified digest through the handoff, including the intended manifest or multi-platform index, and check how the runtime selects the platform-specific image.&lt;/p&gt;
&lt;p&gt;Another failure accepts any cryptographically valid signer. Restrict trust to authorized keys or expected identity-and-issuer pairs, and test rejection of a wrong signer and an unapproved digest. A compromise requires investigation and an explicit policy change; it does not retroactively prove that every older artifact was malicious.&lt;/p&gt;
&lt;figure class="technical-diagram"&gt;
&lt;img loading="lazy" src="https://hk.xbcatm.com/visuals/posts-signed-images-prove-who-built-them.detail.en.svg" alt="Digest binding and signer authorization precede deployment of the same digest; build provenance, content safety, trust changes and discovery are separate checks." width="560" height="2201"&gt;
&lt;figcaption&gt;Image signature trust: mechanism and evidence boundaries.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="check-it-quickly"&gt;Check it quickly&lt;/h2&gt;
&lt;p&gt;The following commands are a template, not a runnable fixture: the registry is an example and the digest is abbreviated. Before any authorized registry check, supply an existing test image&amp;rsquo;s complete digest, its trusted public key, and installed Cosign and Skopeo versions. No signing, registry operation, or deployment was run for this source review.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cosign verify --key cosign.pub registry.example.com/app@sha256:9ab5a134...
cosign tree registry.example.com/app@sha256:9ab5a134...
skopeo inspect --format &amp;#39;{{.Digest}}&amp;#39; docker://registry.example.com/app:latest
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Expect successful verification of the specified digest under the selected key, not necessarily a printed human identity. &lt;code&gt;cosign tree&lt;/code&gt; discovers associated objects; listing them does not verify their claims. The Skopeo result can check the tag&amp;rsquo;s current resolution, but a mismatch only means it differs from the digest just checked; the other digest might have its own signatures. Even equality is a snapshot, not protection against the tag moving afterward.&lt;/p&gt;
&lt;h2 id="sources"&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.sigstore.dev/cosign/verifying/verify/"&gt;Sigstore: verifying signatures with cosign&lt;/a&gt;, key-based and keyless verification over a digest, checked 2026-09-16.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slsa.dev/spec/v1.0/"&gt;SLSA v1.0 specification&lt;/a&gt;, provenance, digests and what a signature is claimed to attest, checked 2026-09-16.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sigstore.dev/policy-controller/overview/"&gt;Sigstore policy-controller&lt;/a&gt;, enforcing signature and identity policy at admission, checked 2026-09-16.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://specs.opencontainers.org/image-spec/descriptor/"&gt;OCI image descriptor specification&lt;/a&gt;, digest binding to referenced content, checked 2026-10-18.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slsa.dev/spec/v1.0/verifying-artifacts"&gt;SLSA v1.0: verifying artifacts&lt;/a&gt;, trusted builder and provenance policy distinct from signature validity, checked 2026-10-18.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sigstore.dev/about/overview/"&gt;Sigstore overview&lt;/a&gt;, identity certificates and transparency boundaries, checked 2026-10-18.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sigstore.dev/cosign/verifying/timestamps/"&gt;Sigstore timestamps&lt;/a&gt;, trusted signing time and certificate validity, checked 2026-10-18.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sigstore.dev/cosign/signing/signing_with_containers/"&gt;Sigstore: signing containers&lt;/a&gt;, tree discovers associated signatures, checked 2026-10-18.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/containers/skopeo/blob/main/docs/skopeo-inspect.1.md"&gt;Skopeo inspect manual&lt;/a&gt;, top-level manifest digest and platform-specific fields, checked 2026-10-18.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>