Code Signing, Provenance & Software Integrity Verification: What’s Already Here

Home >> TECHNOLOGY >> Code Signing, Provenance & Software Integrity Verification: What’s Already Here
Share

Why Software Trust Has a Real Problem

Shipping software in the recent past used to involve coding, developing of the code and taking the code live. The discussion on security mostly ended at encrypting it over the air. Then SolarWinds happened. Then Codecov. Then a product of supply-chain brokenings that came and wrote the new rules unobtrusively.

The unpleasant fact that the said attacks revealed: a signed binary is not the same as a safe binary. Attackers with control of a build environment are capable of generating artifacts that validate all conventional tests – matching signature, passing hash, acceptable antivirus scan – but offer something that is malicious.

Code signing, provenance and software integrity validation are a combination of the solutions built to this problem. They provide answers to three questions that any securityminded team should be asking themselves before they can trust any artifact: Who made this? Has it been changed? Is it possible that we can answer the question, how it was constructed?

This paper brings the entire panorama of what is, what is actively evolving, and which way Software Supply Chain Security is running together, it is addressed to developers, DevSecOps engineers, and security professionals who are neither in the land of we sign our containers nor the land of we enable provenance with admission.

Digital Signatures for Binary Verification: The Layer Everything Else Builds On

Code Signing Provenance & Software Integrity Verification

What Signing Actually Proves

Asymmetric cryptography is employed by digital signatures. The artifact is of course signed by a private key; and verified by the corresponding public key by the consumer. Verification fails in case, after signing, a bit is changed in the artifact. That’s the guarantee.

This has been used as the operating systems over the years. Gates loading of Microsoft Authenticode. In the Developer ID notarization, Apple blocks unrecognized macOS apps. The APK signing scheme by Android identifies packages with developer identities. they are not features but provide trust mechanisms that are enforced throughout the platform that billions of devices rely on in their daily work.

In the case of server-side and container workloads, it is no different: artifact should be signed and verified first. Distribution package ecosystems such as Linux have checksums published with the packages to enable consumers to verify they received what they published. It is simple, it works and it is really helpful.

What a Signature Doesn’t Tell You

This is the fault that brings down teams. The use of a digital signature establishes two facts: that the item came out of whoever had used the private key, and that it is not the same as it was at the time the key touched it. That’s the entire guarantee.

It does not say in any way whether the build environment has already been weakened by the time of the signing. It does not tell whether it was in the dependency stage where malicious code was introduced, three phases prior to assembly of the binary. It does not establish that the signing key was indeed under controllable control, which stolen signing keys are an openly known and repeated issue. The case with Nvidia certificate breach revealed that after the attacker possesses a legitimate cert he/she may sign in malware that appears to be indistinguishable with a bona fide vendor release.

This is how provenance and integrity checking is an upper layer to signing, and not a substitute of the former. Signing is the one dealing with who and unchanged. Provenance deals with the question how it got here.

Cosign and Container Image Signing: Where the Industry Is Actually Moving

The Key Management Problem Nobody Loves

The conventional signing of codes relies on the permanency of the personal keys. Theoretically, such keys are stored in cloud vaults or HSMs, which have highly restrictive access controls. Practically, I have signed keys in a number of container pipelines and the business reality is not so clean in practice, however the state of keys is represented as a CI environment variable, a rotation window lowers its head and schedule, certificates are kept in an inventory that no single person borders, and audit logs are there but not read.

That does not make it peculiar to a team. It is a structural issue with long lived credentials at scale. The length of a key is equal to the length of a compromise window. The greater access of signing infrastructure there is among teams, the more difficult access control will be.

Sigstore’s Keyless Approach

Cosign, a component of the Sigstore project, operates under a very different conception of this problem. In the place of dealing with long-lived private keys, developers are authenticated by OIDC – GitHub Actions, Google, or some other identity provider. Fulcio, certificate authority of Sigstore, is a short-term certificate that is issued by that particular identity.

The signing event has been documented forever in Rekor, which is the public transparency log ofie The outcome: perfectly private crypto keys have never existed, there is cryptographically verifiable data of all depositions of “signings” and identity is identified with a real-world workflow or human being rather than an abstract key.

# Keyless image signing via GitHub Actions OIDC
cosign sign \
--oidc-issuer=https://token.actions.githubusercontent.com \
ghcr.io/yourorg/yourimage:latest

Verifying Signed Images


It is the signature coupled to a particular workflow identity:

cosign verify \
--certificate-identity=https://github.com/yourorg/repo/.github/workflows/release.yml@refs/heads/main \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
ghcr.io/yourorg/yourimage:latest

My experience showed that the certificate identity string must be identical to the precise workflow path – otherwise verification will fail, without necessarily throwing up an error notification. Value testing in small scale before imposing it in the production policy gates. There is nothing wrong with Cosign; it is merely such a fact as saves a hour of debugging down the line.

The first teams to consider this type of workflow have noted that the keyless signing can eliminate the most difficult part of the working load. The certificate does not have to be rotated, there are no vaults where access has to be administered, and any signing operation is publicly recorded and verifiable without extra tooling.

Artifact Provenance and the SLSA Framework: Proving the Entire Build Chain

Code Signing Provenance & Software Integrity Verification

What Provenance Actually Is

Provenance A signed document containing a description on how an object was built, e.g. what source repository it was built out of, what commit it was built with, what build system it was built with, what parameters it was built with, and what environment it was built with. It is not a sign that the artifact bears. It is a verifiable history of the whole history of the artifact.

A signed container image without provenance establishes the fact that the container image originated with a legitimate key. Using provenance, it can show that it was created by this exact GitHub Actions workflow on this date with these dependencies on this committed contents. A better basic assertion of trust.

SLSA Levels Explained

The SLSA provenance model called Supply chain Levels for Software Artifacts, which is also known as salsa, classifies four stages of supply chain hardening:

SLSA LevelCore Requirement
Level 1Provenance exists and documents the build
Level 2Provenance is signed by the build service itself
Level 3Build runs in an isolated, auditable environment with verified source

The provenance of SLSA is presented in the form of an in-toto attestation, that is, a signed envelope containing structured metadata in the form of a lone overweight uses.

In-toto model implements one more step forward, as per the model, each stage of a pipeline will be signed, hence in case some necessary stage is skipped such as a SAST scan or dependency screen, it will be caught during verification. It is not merely “is the artifact received? It is whether it came the right way or not.

I observed that Level 1 and Level 2 can be realized after a few sprints with the provenance generation provided by GitHub Actions with the use of native SLSA. Level 3 is more architectural commitment, hermetic constructions, stricter policy gates, but the way there has been written and the machinery available.

Attaching SBOMs as Signed Attestations

A Software Bill of Materials – SBOM – contains a list of all of the components that an artifact contains, with transitive dependencies. Generating an SBOM is useful. By signing it as an attestation to a container image it is attached to, it is incorporated into a verifiable trust chain as opposed to a document that may be replaced.

Cosign works in this specific direction, and SBOM generation has become easy with tools such as Trivy:

# Generate SBOM in CycloneDX format
trivy image --format cyclonedx --output sbom.json yourimage:latest

# Attach as a signed attestation
cosign attest \
  --predicate sbom.json \
  --type cyclonedx \
  ghcr.io/yourorg/yourimage:latest
```

Anyone pulling that image can now verify both its signature and its SBOM attestation — and confirm neither was tampered with after the build completed.

---

## VCS to Production: Tracking Trust Boundaries Across Every Stage `<h2>`

### Where the Attack Surface Actually Lives `<h3>`

The path from a `git push` to a running container crosses multiple distinct trust boundaries. Each one is a potential injection point:
```
Developer Workstation → Source Repository (VCS) → CI Build System
       → Artifact Registry → Staging → Production Cluster

The simplicity of the question at each phase can be, can we assure ourselves that what came here is what came out of the last step? In the absence of provenance attestations between each step, the response of most teams is we assume so. Assumptions are used by attackers.

A build system which generates an image with valid signature does not necessarily state the commit to the source was clean. A registry that holds a signed image does not also indicate that CI system was inappropriate between commit and build. Those dots are joined by provenance. It generates a verifiable sequence of ownership of the work of the initial line of code of the running workload to the running workload.

Enforcing Trust at the Cluster Boundary

The method that is a true deviation in this area is an engine policy Kyverno, OPA/Gatekeeper to implement signature and provenance requirements during admission to Kubernetes. No smart property will be produced without a legitimate signature and effectively forming provenance attestation.

A simple Kyverno policy implementing Cosign-signed image signature:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-image-signature
spec:
  rules:
    - name: check-image-signature
      match:
        resources:
          kinds: [Pod]
      verifyImages:
        - imageReferences: ["ghcr.io/yourorg/*"]
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/yourorg/*"
                    issuer: "https://token.actions.githubusercontent.com"

I have deployed Kyverno in the following setup in staging environments and the advice is similar: they should be used in audit mode at least one week before being swapped to enforce. Violations reported by audit mode do not block a deployment, but expose edge cases, base images are pulled directly off of unofficial registries, the legacy tooling to act does not sign, which do not result in an incident.

Challenges That Haven’t Been Fully Solved Yet

Code Signing Provenance & Software Integrity Verification

Developer Adoption Friction

The tooling is solid. The records have become a lot better. Still, there is still an uneven adoption across teams and the disparity between we have Cosign available and we enforce signatures everywhere is not as narrow as it needs to be.

Paper-based signing processes which are not incorporated in CI pipelines are skipped. Living certificate inventory contained in a spreadsheet is not maintained. Policy gates which are never tested in staging are bypassed using exceptions which are turned into permanent ones. They are not tool problems but rather problems in processes which are prevalent.

Integration on the CI level is the way to go hence the situation with the signing that is automatic and non-negotiable, which cannot be forgotten by the developers.

Verification at Scale

The easy part of the problem is to produce signatures and attestations. Making them verifiably secure against hundreds of services with policy logic, revocation and caching is actually difficult engineering. Mixed registry teams Up until now verification latency and cache invalidation becomes operational in large-scale Kubernetes clusters containing images with different provenance quality.

Regulatory Expectations Are Tightening

Both the US Executive Order 14028 and the EU Cyber Resilience act are driving software suppliers towards the verifiable provenance, signed SBOMs and SLSA-like attestations. It is no longer a theoretical thing. Auditors are beginning to demand evidence of the construction of software- not what version was shipped or whether a vulnerability scanner was run.

Inconsistent or missing provenance is ceasing to be a compliance shortfall with merely nominal impact: audit flunks, contract fulfilment and, in the case of high assurance industries, ineligibility to hold some contracts altogether.

Where This Is All Heading

What the Next Few Years Actually Look Like

It is moving in the right direction despite an unclear timeline, npm and PyPI are already adding Sigstore-supported provenance on published packages. Signature-enforcing kubernetes admission controllers are shifting toward advanced configuration to recommended baseline. SBOM itself is becoming more automated as opposed to manual compliance artifact.

The desired end state being constructed to: unsigned artifacts and unprovable provenance will be operationally and regulatorily unacceptable on anything which touches production. The tools already exist. The standards are written. The next thing that is lagging behind is the widespread and active implementation into the wider ecosystem.

Final Take

Code signing, provenance, and software integrity verification are not three independent practices to potentially attach at the various stages of a roadmap. They are multi-tiered layers in which one layer reinforces the other. Identity and integrity are handled in signatures.

Build chain Provenance demonstrates the build chain. The enforcement of policies makes them both hard gates as opposed to optional checks that are passed in an audit and fail in incidences.

To the teams that are starting on this work: make Cosign keyless signing work on container images. Create Trivy SBOMs and provide them as attested signatures. Add a Kyverno audit policy. When correctly taken those three steps place a team far above most of the industry- and set the stage of all which is more advanced coming on afterwards.

The investment is real. So is the cost of skipping it.

Leave a Reply

Your email address will not be published. Required fields are marked *