Security Engineering · Supply-Chain Security

Keyless Signing and Transparency Logs for Build Artifacts

Short-lived certificates bound to an OIDC identity remove long-lived keys from the signing path, and an append-only log makes a signature public evidence rather than a private promise.

Signing an artifact normally means owning a private key and keeping it for years. That arrangement has two persistent problems: the key is a target for the entire period of its validity, and a verifier who has never met the signer has no way to decide whether the key is the right one. Identity-based signing inverts both. The signer proves who they are to an identity provider, receives a certificate that is valid for minutes, signs, and discards the key. Verification then asks a different question, not “is this the project’s key” but “was this artifact signed by a workload holding this identity, at a time when that identity was valid, and is the signature public”.

From an OIDC identity to a ten-minute certificate

The flow begins with an identity token. A build platform, a source host, or a CI system that already authenticates its workloads can issue an OpenID Connect token asserting facts about the workload: which repository, which workflow, which branch, which commit, which environment. These tokens are JWT-format, signed by the issuer, and short-lived by construction.

The signer generates an ephemeral key pair in memory, then submits the public key and the identity token to a certificate authority. The CA verifies the token’s signature against the issuer’s published keys and validates the claims against the identity it is willing to certify, then issues an X.509 certificate whose validity window is measured in minutes — ten is the commonly used figure — with the workload identity encoded in a certificate extension that is logged but not part of the subject distinguished name in a way a conventional verifier would check. The private key never leaves the process, and it is discarded when the process ends.

The certificate’s short validity is the security argument, not an operational convenience. A stolen key is useful only within the certificate’s window, and the window is smaller than the interval between a typical compromise and its discovery. Rotation is not a process because there is nothing to rotate.

The identity claims are the part worth scrutinizing, because they define what a signature means. A signature made by a certificate naming a repository and a workflow is a statement by that workflow, on that platform, at that time. A certificate that names only an email address is a much weaker statement: it says a person who controls that address signed something, with no information about what code or process produced the artifact. The claims’ specificity is the entire security content of the identity.

The log entry, and why the log is not optional

Keyless signing without a log would be a device for producing signatures that nobody can validate after the certificate expires. The certificate expires in ten minutes; the artifact outlives it by years. Verification therefore needs two things: proof that the signature was made while the certificate was valid, and proof that the timestamp used for that judgment was not chosen by the signer.

A transparency log supplies both. The signer submits the signature, the certificate, and the artifact digest to a log server. The server appends an entry, returns a signed timestamp and evidence that the entry is included in the log’s Merkle tree, which the signer stores alongside the signature. Verification later checks the signature against the certificate, checks that the entry was logged before the certificate expired, and verifies the inclusion proof against a tree head the verifier trusts.

The log’s data structure is a Merkle tree of the kind defined for Certificate Transparency in RFC 6962: leaves are hashes of entries, internal nodes are hashes of their children’s hashes, and the tree head is a signed commitment to a specific size and root hash. The core defence is the consistency proof, which lets a client that has seen a tree head of size $n$ verify that a later tree head of size $m > n$ contains the earlier tree as a prefix. A log that removes or rewrites an entry cannot produce such a proof, and a monitor that continuously checks consistency will detect the attempt.

The deeper argument is about what the log makes possible for the verifier. A verifier who is handed a signature and an inclusion proof does not have to trust the log server’s honesty in the present: they verify a hash chain back to a tree head, and the tree head’s signature check requires only the log’s public key, which can be obtained out of band. The remaining trust is in the monitors that watch for consistency violations, which is why transparency systems are described as requiring a monitoring ecosystem rather than just a server.

# Sign an image digest with an ambient CI identity, then verify offline
# against an explicit identity policy instead of a key.
cosign sign --yes registry.example.invalid/app@sha256:9f2c...
cosign verify \
  --certificate-identity 'https://ci.example.invalid/workflows/release.yml@refs/heads/main' \
  --certificate-oidc-issuer 'https://token.actions.example.invalid' \
  registry.example.invalid/app@sha256:9f2c...
# The verifier pins identity and issuer, not a public key.

The verification command shows the pivot precisely. Every argument is an identity constraint or an issuer constraint, and none is a key. The verifier’s policy is a statement about which identities may produce artifacts for this repository and which issuer is entitled to certify them; the certificate chain and the log proof are what connect that policy to the bytes.

What an inclusion proof and an SCT buy

An entry in the log gives three distinct properties, and conflating them is a common source of misplaced confidence.

Authenticity of time. The log’s signature over the entry’s integrated time establishes an upper bound on when the entry existed. Because the certificate was valid at that moment, the signature is attributable. Without this, a signer holding an expired certificate could backdate a signature, or a verifier could be persuaded that an expired certificate was valid when it was used.

Public detectability. An entry is visible to anyone who queries the log. A signature made by a stolen identity is therefore visible to the identity’s owner, who can monitor the log for entries under their identity and treat unexpected ones as an incident. This is the property that converts a silent compromise into a detectable event, and it requires that someone actually monitors.

Non-equivocation. The log cannot show different views to different parties without breaking consistency, which is what makes the evidence durable across the certificate’s expiry.

The log does not provide confidentiality, and it does not provide meaningful revocation. An entry cannot be removed; the design forbids it. If a signature was made in error or by an attacker, the response is a new entry and a policy that ignores the old one, not deletion. Systems that expect revocation to work the way certificate revocation works will be disappointed; the log is a permanent record, and the remedy for a bad record is refutation, not erasure.

The trust assumptions that remain

Keyless signing moves trust rather than removing it, and the moved pieces deserve naming.

The identity provider decides which workload gets which identity. A forged OIDC token yields a valid certificate for the forged identity, and no amount of log verification catches it, because every step is legitimate from the log’s perspective. The issuer is therefore part of the trust boundary, and a verifier that pins an issuer is pinning that issuer’s authentication.

The certificate authority decides which claims it will certify. An issuer that accepts a token from any source without checking the audience, or that maps claims loosely, can be induced to certify an identity the workload should not have.

The log’s availability and the monitors. A log that is down blocks signing, which makes it a availability dependency in the release path. A log that is not monitored for consistency can fork undetected with respect to clients that never compare tree heads.

The verifier’s policy. An identity constraint written as a wildcard identity, or written against a generic issuer without narrowing the workflow, verifies signatures that carry no meaningful assurance. The most common real-world failure of keyless verification is not cryptographic: it is a policy that permits any identity from a large platform to sign artifacts attributed to a project.

There is also a structural limitation worth stating: a signature proves which identity signed the artifact, not which identity built it honestly. If the workflow that holds the release identity can be modified by anyone who can open a pull request, the signature attests to the workflow’s execution, and control over the workflow is the real control over the release. That is the point at which signed artifacts meet provenance and platform hardening; the statement format that records the build is described in provenance attestations and the digest they bind, and the platform-side controls in hermetic build isolation and two-party verification.

Why logs generalize beyond code signing

The log-and-witness pattern is not specific to artifacts. The same structure — append-only Merkle tree, signed tree heads, consistency proofs, independent monitors — is what makes a repository’s metadata auditable, and TUF’s design uses comparable reasoning at a smaller scale, as described in threshold roles and rollback protection in the Update Framework. The pattern’s cost is that it requires public infrastructure and monitoring; its benefit is that trust in a single operator becomes trust in a structure that misbehaviour cannot hide from anyone who looks.

References

  1. RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile — IETF
  2. RFC 6962: Certificate Transparency — IETF
  3. Rekor transparency log overview — Sigstore project documentation
  4. The Update Framework Specification — CNCF / TUF project