There is a simple test that tells you how mature an organization's software supply chain security really is. Ask it about the last release it shipped: can you prove, cryptographically, that the artifact being deployed is byte-for-byte identical to the artifact that was built, reviewed, and approved? For most organizations, the honest answer is no. The artifact could have been modified anywhere between the build and the deploy — by a compromised registry, a poisoned cache, a misconfigured artifact server, or a malicious insider — and nothing would notice.
Code signing is the answer to that question. It has existed for decades. The mathematics are mature, the tooling is mature, and the failure modes are well documented. And yet signing remains the exception rather than the rule in most pipelines. The question is not whether signing works. The question is why it keeps losing to convenience.
What a Signature Actually Buys You
A signature over an artifact provides two things, and it is worth being precise about both:
- Integrity. The artifact has not been modified since it was signed. Any change breaks the signature, and the breakage is provable by anyone with the public key.
- Provenance. The artifact was signed by whoever holds the private key. Combined with a trust decision about that keyholder, this tells you who to hold responsible for the artifact.
Signatures do not make artifacts safe. They make artifacts accountable. A signed artifact can still contain a vulnerability or a backdoor — but it cannot be silently replaced, and its origin cannot be disputed. That property is the difference between "we deployed a thing" and "we deployed the thing we decided to deploy."
The Failure That Signing Prevents
Thought experiment — the artifact that changed on the way
An organization builds a release, tests it, and approves it. The artifact is uploaded to an internal artifact store and later pulled by a deployment pipeline that runs it across a fleet of servers.
Between upload and deployment, a small compromise at the artifact store — a weak credential, an internal tool with too much access — replaces the approved artifact with a nearly identical build. The replacement is tested in a way that looks normal. The team deploys it, confident it is running the artifact that passed review.
With signing, the replacement is detected the moment the deployment verifies the signature against the recorded public key: the signature fails, the deploy halts, and an incident begins with an artifact that cannot be disputed. Without signing, the team deploys a binary that never passed review and discovers the discrepancy weeks later — if it discovers it at all. The same attack, two different outcomes, separated only by a signature check that runs in milliseconds.
Why It Keeps Losing to Convenience
The excuses are as consistent as they are reasonable-sounding, and each one is a symptom of treating signing as an add-on rather than a default:
- "It adds friction to the pipeline." Signing requires a key management decision, a signing step, and a verification step. Friction is real, but it is measured in minutes per release — and it is exactly the friction that forces the question "who is allowed to release?" to have a real answer.
- "Keys are hard to manage." The private key is the crown jewel of the whole arrangement, and protecting it is genuinely difficult. The answer is not to avoid keys but to make key management a first-class engineering problem: hardware-backed keys, short-lived signing certificates, and automated rotation.
- "Nobody verifies anyway." This is the truest objection and the most damning. Signing without verification is decoration. The pipeline that signs but never checks downstream has spent the effort and kept the vulnerability.
- "We trust our internal systems." Every major supply chain incident in the last decade was a failure of trusting an internal system — a registry, a cache, an artifact store, a build runner. Trust is exactly what a signature is for: it replaces unexamined trust with checkable evidence.
The Verification Half of the Equation
Signing is only half the control. The half that actually protects you is verification at the point of consumption. The pipeline should sign; the deployment should verify; and the verification failure should be a hard stop, not a warning. The asymmetry is the point: signing every artifact is easy to get wrong in a hundred places, but verifying every artifact is a single, centralized decision at the door.
| Step | Sign | Verify |
|---|---|---|
| Source code | Commit signing with a hardware-backed key | Repository-side signature validation on merge |
| Build output | Build job signs every artifact, container, and SBOM | Artifact store rejects unsigned artifacts |
| Deployment | Release process records the artifact digest and signature | Deploy verifies signature and digest before running anything |
| Downstream consumers | Published packages sign their releases | Consumers pin and verify publisher signatures |
The Special Case of Containers
Containers made signing both more important and more confusing. An image is not a single file; it is a stack of layers, a manifest, and a configuration object, and all of it is routinely pulled from registries that have no memory of who pushed what. A base image signed by its publisher, a layer signed at build time, and a final image signed at release can each carry their own signature — and the trust decision at deployment has to understand all three.
The common failure is subtle: signing the final image while leaving the layers unverified. Because image resolution trusts the manifest, an attacker who can modify a layer reference in the manifest changes what actually runs without touching the signature on the manifest. The fix is to sign at the content level — over the digests of the layers — so that the signature commits to the bits that will actually execute. Container signing, done right, is the same discipline as artifact signing anywhere else: the signature must bind to the exact content being deployed, and the verification must happen at the moment of deployment, not at the moment of publishing.
What Signing Does Not Do
It is worth being blunt about the limits, because overselling a control is how it gets quietly abandoned. Signing does not prevent vulnerabilities; it prevents substitution. It does not protect you from a maintainer whose key is stolen and used to sign a malicious release; it transfers the trust decision to the key, and the key may be wrong. It does not tell you whether the code is good; it tells you whether the code is the code you decided to deploy. Those limits are real, and they are also the point. Signing narrows the problem to "who is allowed to release and are they trustworthy" — which is a question organizations can actually answer, instead of the unbounded question of whether an artifact is safe.
Making Signing the Default
The practices that turn signing from a project into a default are boring in exactly the way good security is boring:
- Sign everything, from the start. Commit signatures, artifact signatures, container signatures, SBOM signatures. The cost is lowest at the beginning of a project's life and rises with every release that ships unsigned.
- Use short-lived keys. A key that expires quickly and rotates often limits the damage of a leak and the lifetime of a compromise. The industry trend toward ephemeral signing keys exists for a reason.
- Protect keys in hardware. Signing keys belong in hardware security modules or secure enclaves, not in a CI variable or a developer's keychain.
- Make verification a hard gate. Anything that deploys, publishes, or consumes artifacts must fail closed when a signature does not verify. Warnings become incidents.
- Attach identity to the key. A signature is only as meaningful as the trust decision around the key — who owns it, what they are allowed to sign, and how that permission is audited.
- Audit the audit trail. Signing is evidence. Evidence you never review is indistinguishable from no evidence at all. Verify on a schedule, not just at deploy time.
Key Takeaways
- A signature provides integrity and provenance: the artifact is unchanged and the signer is accountable.
- Signing is the difference between deploying the thing you approved and deploying a thing you never saw.
- The hard half of the control is verification at the point of consumption, with failures treated as hard stops.
- Friction, key management, and the "nobody verifies anyway" objection are solvable — they are not reasons to skip the control.
- Sign everything, verify everything, and make unsigned a release that cannot ship.
Artifact integrity has never lost to cryptography. It has lost to convenience — to the belief that the extra step is not worth it, that internal systems can be trusted, that the signing ceremony can wait until next quarter. Every major supply chain breach in recent memory was a reminder that the thing you deploy and the thing you approved are not the same thing unless you make them the same thing. Signing is how you make them the same thing. It has been ready for decades. The pipeline is what has been waiting.