Key insight
Image signing is not new and is not exotic. What is new is that it is now free, keyless, and tied to your build pipeline’s identity. You no longer manage private keys; you no longer have signing-key rotation drills; you no longer face the “who has access to the signing key” question in audit. The pipeline’s OIDC identity is the signing identity, and the signature is recorded in a public transparency log.
The promise of a signed-image appliance
From the customer’s perspective, the appliance pattern collapses the entire question of “is this safe to install?” into a single verifiable claim: this image digest was produced by a build pipeline running in a specific source repository, on a specific tagged commit, and the signature has been recorded in a public transparency log. If any of those things are false, the verification command fails. If all of them are true, the customer can install the image with the same confidence they would install a signed package from their operating-system vendor.
From the operator’s perspective, the appliance pattern frees you from three perpetual headaches: managing customers’ access to your source repository, recovering when a customer’s ZIP upload diverges from your tree, and explaining provenance every time a new customer’s audit team asks. Signing happens once at build time; verification happens once at install time; everything else is unchanged.
OIDC-keyless signing, explained without the cryptography
Traditional code signing required somebody to hold a long-lived private key. Whoever held the key could sign anything. Key rotation was an event. Key compromise was a disaster. Audit asked, repeatedly, “who can sign?” and the answer was always uncomfortable.
Keyless signing replaces the long-lived key with a short-lived certificate, issued at the moment of signing, bound to an OIDC identity (typically the identity of the CI job that is running). The certificate is valid for ten minutes; the private key existed for the duration of the signing operation and was discarded. There is nothing to rotate, nothing to compromise, and nothing to revoke.
The verification side does not need access to the certificate. It needs to know which OIDC identity to expect — for example, “a job named release.yml in the repository vendor/agent on a tag matching v*” — and the transparency log handles the rest.
The transparency log
The transparency log is a public, append-only, cryptographically verifiable record of every signing event. The signing operation writes a small entry into the log. The verification operation re-reads the log to confirm the entry exists. Anyone in the world can audit the log to check that no signing event has been retroactively altered.
For a customer’s audit team, the transparency log answers the question “was this signature actually issued?” without depending on the vendor’s word. For the vendor, the log makes “a fake release was published” into a detectable event, because the fake would leave a log entry under an identity that does not match the legitimate build pipeline.
The largest production deployment of this model is the Sigstore project, which runs the transparency log under the name Rekor. The pattern is now standard across the major language ecosystems — container images, Python wheels, npm packages, and increasingly source-code releases on the major platforms all use the same mechanics.
Anatomy of a signed-image release
A single signed release produces four artefacts in the registry:
- The image itself, addressable by digest (
sha256:…) under one or more human-readable tags (v1.2.3,latest). - The signature, a small companion artefact attached to the image digest. The signature includes the short-lived certificate and the transparency-log entry pointer.
- The build-provenance attestation, a signed JSON document describing how the image was built — the source revision, the build steps, the inputs, the builder identity.
- The Software Bill of Materials, an inventory of every dependency in the image, signed and addressable separately.
All four artefacts live alongside the image in the same registry. None of them require a separate distribution channel. A registry that complies with the OCI distribution specification handles all of them as ordinary OCI artefacts.
What the customer verifies, in practice
Verification is a single command. The arguments it takes are the image digest, the expected signing identity, and the expected OIDC issuer. The command resolves the signature, contacts the transparency log to confirm the entry exists, verifies the certificate chain back to the public root, and prints either a green “verified” or a red error.
The signing-identity argument is the only thing the vendor must publish ahead of time. It is a single line of text — typically a regular expression that matches the URL of the build pipeline in the source repository — and it appears in the pin file (chapter 4) that ships with every release. The customer’s install script reads it from the pin file and passes it to the verification command. If a future release is published under a different identity, verification fails closed; the customer is not surprised by a quiet substitution.
For the customer’s audit team, the verification command is the audit. There is nothing else to inspect.
SLSA build provenance
The Supply-chain Levels for Software Artifacts framework formalises what “provenance” means at four levels of rigour. Level 1 is “the build process is documented”; level 4 is “the build is hermetic, two-party reviewed, and the builder is hardened against tampering”. The level meaningful for most tenant-deployed agents is level 2 or 3.
At level 2, provenance is generated automatically by a hosted build service, signed, and attached to the artefact. The customer can verify that the provenance was generated by the expected builder identity, that the source revision named in the provenance matches the one named in the version endpoint, and that the dependency list matches the SBOM.
At level 3, the build platform itself is hardened — isolated workers, ephemeral environments, an isolated network. Most managed CI platforms (the major code-hosting services) operate at level 2 by default and can be configured for level 3.
The SLSA framework is not a product. It is a specification, freely available, and the major build platforms publish guides for how to meet each level.
The signing-identity contract
The single most important configuration choice is the signing-identity expression. The wrong expression makes verification trivially bypassable; the right expression locks the signature to a specific source repository, a specific workflow file, and a specific tag pattern. The shape of the expression is similar across signing tools: an OIDC issuer URL plus a regular-expression match against the subject of the certificate.
For a build pipeline hosted on the major code-hosting services, the certificate subject is the workflow URL. A correct identity expression matches the full URL, anchored to ^ at the start and $ at the end, including the tag prefix. The two common mistakes are (a) leaving the regex un-anchored, which lets any repository name that contains your name match, and (b) using a wildcard that includes the branch ref, which lets a development branch sign as if it were a release.
The signing-identity expression belongs in the pin file (chapter 4). It is published with every release and reviewed once per release. Once set correctly, it changes only when the source repository moves or the workflow file is renamed.
What can still go wrong
Signing is not a complete supply-chain solution and the chapter would be dishonest if it pretended otherwise. Signing proves that this build pipeline produced this image; it does not prove that the source the pipeline was given was the source you intended to ship. A compromised commit on the source repository, signed in good faith by the pipeline, will verify cleanly. The mitigation is branch protection on the source repository — required reviews, required status checks, and a small set of authorised committers. Signing assumes the source is trustworthy; branch protection earns that assumption.
Signing also does not prove the absence of a malicious dependency. The image is verified to match a build pipeline that pulled a specific set of dependencies; whether those dependencies themselves are safe is the SBOM’s problem, not the signature’s. The two are complementary controls.
Finally, signing does not prevent rollback to a known-bad version. A customer running an old, signed image is still running an old, signed image. Operational controls — minimum-version checks in the install script, deprecation policies, end-of-life timestamps — carry that load.
Adoption sequence
- Configure the build pipeline to sign images on every tag push. The major hosted CI platforms include this as a built-in step now; the cost is roughly fifteen lines of YAML.
- Configure the pipeline to generate and attach SLSA build provenance on every signed release. This is a second built-in step, fewer than ten lines.
- Configure the pipeline to generate, sign, and attach an SBOM. Either CycloneDX or SPDX; pick one and stay with it.
- Publish the signing-identity expression in the pin file (chapter 4).
- Update the install script in the bootstrap repository to run the verification command before pulling the image.
- Verify the chain end-to-end from a clean workstation that has never seen your signatures. If verification works without any cached keys, the pattern is correctly wired.
References & further reading
- Sigstore project (the reference implementation of keyless OIDC signing and the Rekor transparency log). sigstore.dev
- SLSA build provenance, all levels. slsa.dev/spec
- in-toto attestation framework. in-toto.io
- OCI Image Specification — how signatures and attestations are stored alongside images. opencontainers/image-spec
- NIST Secure Software Development Framework (SP 800-218), “Protect the Software” family of practices. csrc.nist.gov/Projects/ssdf
- OWASP Top 10 for LLM Applications, LLM03 Supply Chain. genai.owasp.org