Blog Article

Code Signing After SolarWinds: 5 Controls That Would Have Stopped It

June 3, 2026
16 min read

Published on

June 3, 2026

The SolarWinds Anatomy in Three Minutes

On December 13, 2020, FireEye disclosed that a trojanized update of SolarWinds Orion, distributed between March and June 2020, had compromised at least eighteen thousand customer environments and a confirmed subset of roughly one hundred high-value targets including the US Treasury, Commerce, State, Energy, and Justice departments. The malware, tracked as SUNBURST (UNC2452, later attributed to APT29), did not exploit a cryptographic weakness. It exploited the build pipeline.

The Orion DLL SolarWinds.Orion.Core.BusinessLayer.dll shipped to customers carried a valid Authenticode signature chained to the SolarWinds code-signing certificate issued by Symantec. Every Windows host running Orion validated that signature and accepted the binary because, by every cryptographic measure available to the verifier, it was authentic.

The attackers, present in the SolarWinds network since at least September 2019, modified the build environment rather than the source repository. A purpose-built implant called SUNSPOT monitored running MsBuild.exe processes for the Orion solution, swapped InventoryManager.cs for a malicious version during compilation, then restored the original file after the build finished so source control showed no diff. The compiled artifact was signed by the legitimate build server using the production code signing certificate as part of the normal release workflow.

There was no certificate theft. There was no key extraction. The signing key did exactly what it was designed to do: sign whatever the build server presented to it.

This is the pattern that matters for everything that follows. The cryptography worked. The verifiers worked. Trust was placed in the wrong layer — the build step — while every downstream control assumed that a valid signature meant a valid artifact.

The same pattern repeated in March 2023 when 3CX’s DesktopApp shipped a trojanized installer (CVE-2023-29059) signed with a valid 3CX certificate after attackers compromised the build environment via a poisoned ffmpeg dependency, an attack Mandiant attributed to UNC4736.

It repeated in April 2021 when the Codecov Bash Uploader was modified by attackers who exploited a Docker image creation flaw to extract credentials and tamper with the script that thousands of CI pipelines downloaded and trusted.

It repeated again in May 2023 when Cl0p exploited CVE-2023-34362 in MOVEit Transfer to compromise more than two thousand organizations, distributing payloads that frequently rode on otherwise-legitimate update channels.

SolarWinds was not a freak event. It was the first widely publicized instance of a class of attack the industry has yet to take seriously enough.

The remediation cannot be “sign harder.” The remediation is to make the signing event itself an auditable, policy-enforced, anomaly-monitored operation, with the signing key physically incapable of producing rogue signatures on demand.

Five controls, applied together, would have raised the bar high enough to stop SUNBURST at multiple points in the kill chain. Each of them is now achievable with off-the-shelf technology, mandated by NIST SP 800-218 (Secure Software Development Framework), aligned with the CA/Browser Forum Code Signing Baseline Requirements, and increasingly required by the EU Cyber Resilience Act for products with digital elements placed on the European market after December 2027.

Control 1: HSM-Backed Signing Keys, with Provable Custody

The first control is structural. Production code-signing keys must live inside a FIPS 140-3 Level 3 (or higher) hardware security module, must never exist in cleartext outside that boundary, and must produce on-demand attestations proving where the signing operation occurred. The CA/Browser Forum Code Signing Baseline Requirements, in the version effective June 1, 2023, made HSM custody mandatory for all publicly trusted code-signing certificates including standard validation (previously OV) certificates.

The change was a direct response to a decade of stolen signing keys, from Adobe (2012) to ASUS (2019, Operation ShadowHammer) to Nvidia (2022, LAPSUS$).

An HSM matters here for one specific reason: it removes the option to exfiltrate the key. Every cryptographic operation happens inside a tamper-evident, tamper-responsive boundary that zeros its memory on intrusion. For a FIPS 140-3 Level 3 device, that boundary is validated against physical penetration, environmental failure, and side-channel leakage. The key is generated on the device, never leaves it, and is referenced by handle. A CI runner sending a sign request gets back a signature; it never gets back a key.

Read the HSM guide for the deeper architecture, and the public and private keys primer for why the asymmetry matters at this stage.

HSM custody alone does not stop SUNBURST, because SUNBURST never tried to steal the key. The build server was a legitimate signer. What HSM custody enables is the next layer: attestation.

Modern signing HSMs (Thales Luna 7, Entrust nShield 5, AWS CloudHSM, Azure Dedicated HSM, Google Cloud HSM) emit signed attestations that bind the signing event to the requesting identity, the artifact hash, the policy that authorized it, and a tamper-evident timestamp. When you can prove that a signature was produced by HSM serial 12345, slot 3, key handle 0xABCD, under policy prod-orion-release-v2, requested by workload identity build-runner-37 with mTLS client cert fingerprint 4F:9A:…, you have created the evidence trail SUNBURST tried to evade.

The attestation does not need to be trusted by the verifier — it needs to be ingested by the SIEM and matched against the next four controls.

Control 2: Reproducible Builds and Signed Attestations

SUNSPOT inserted malicious code at build time and erased the diff. A reproducible build defeats that class of attack at the source. Reproducibility means a given source tree, at a given commit, with a given toolchain, produces a bit-for-bit identical artifact every time, regardless of build host, build user, build timezone, or wall-clock time.

If two independent build farms produce the same SHA-256 of SolarWinds.Orion.Core.BusinessLayer.dll from commit abc123, an attacker who tampered with one farm produces a divergent hash, and the divergence is detectable before signing.

The framework for this is now standardized. SLSA v1.0 (Supply-chain Levels for Software Artifacts), published by the OpenSSF in April 2023, defines a four-level maturity model for build integrity. Level 1 requires automated build with provenance. Level 2 adds source and build provenance verified by the consumer. Level 3 adds hardened builds with isolated, ephemeral build environments and non-falsifiable provenance signed by the build platform. Level 4, deprecated and folded back into the model in v1.0, expressed the reproducibility and two-person review requirements.

In a Level 3 build, the SUNSPOT pattern is structurally impossible because the build environment is destroyed after each run, the provenance is signed by the platform key (not the project key), and the source-to-artifact mapping is cryptographically bound.

Take control of your PKI infrastructure

See how Evertrust simplifies certificate lifecycle management.

in-toto attestations, defined in the in-toto specification 1.0 and adopted by Sigstore, SLSA, and GitHub Artifact Attestations, are the wire format. Each step in the build pipeline (source checkout, dependency resolution, compile, package, scan, sign) emits a signed statement of what was consumed, what was produced, and which policy was applied.

The final artifact ships with a chain of attestations that a verifier can replay against policy — not just “is this signature valid” but “was this artifact built by the right pipeline, from the right commit, with the right reviewer approvals, using a non-tampered toolchain.” Sigstore’s Cosign and Rekor provide the public transparency log; private deployments use the same data model with private logs.

For a verifier to act on this, it needs the kind of policy enforcement that already exists for automated certificate management: declarative rules describing which provenances are acceptable for which artifact classes. Kyverno, OPA Gatekeeper, and Sigstore Policy Controller cover the Kubernetes admission path; Windows AppLocker and macOS Notarization handle the endpoint. The point is not Sigstore versus Notary v2 versus internal tooling. The point is that the build step is no longer trusted by default — it has to prove itself.

Control 3: Quorum-Based Signing Approval

A signing key that signs whatever the CI runner sends is a key that signs whatever an attacker who reaches the CI runner sends. The third control breaks that one-to-one mapping. Any production signing operation must require M-of-N human approval, enforced at the HSM policy layer, with the approval workflow tied to a ticketing system and an out-of-band identity channel.

Three engineers with hardware security keys (FIDO2, smartcard, or YubiHSM Auth) must each authorize a release-candidate signature before the HSM unlocks the key for that single operation, and only for the specific artifact hash submitted to the approval workflow.

Quorum signing is a mature feature, not a research idea. Thales Luna supports m_of_n via the PED key set. Entrust nShield offers ACS (Administrator Card Set) and OCS (Operator Card Set) quorum. AWS CloudHSM and Azure Managed HSM expose quorum policies through their respective control planes. Google Cloud KMS supports quorum-based key access via two-factor approval.

The cryptographic primitive underneath is typically Shamir Secret Sharing or threshold signing (FROST for Schnorr, ECDSA threshold schemes for P-256), but for operational purposes the HSM exposes a simple policy: require_approvals: 3, from_group: release_engineering, ticket_required: true, max_artifacts: 1, expiry: 30m.

In a SolarWinds-shaped attack, quorum signing forces the attacker to either compromise three independent human identities with hardware tokens within a thirty-minute window, while a real release ticket is open, or to wait for a legitimate release and inject the malicious artifact in such a way that the artifact hash submitted to the approvers matches what is actually signed. The latter is non-trivial when the approval portal independently retrieves the artifact and displays its hash, signer identity, source commit, and build provenance from the SLSA attestation chain.

SUNSPOT could not have produced a clean approval flow without compromising the approval portal, the approvers’ tokens, and the SLSA verifier — three independent systems with three different administrative boundaries.

The ticketing audit trail matters as much as the cryptographic one. Every signing operation references a ticket; every ticket references an artifact hash, a source commit, a CI run ID, the SLSA provenance bundle, and the approver identities; every approval is logged in an append-only store.

When an auditor asks “who signed build 2026.4.17.1?”, the answer is six lines of evidence ending in three approver names and a ticket number. When forensics asks the same question after an incident, the same six lines tell you whether the approval was legitimate or whether the approvers were socially engineered. This is governance moving from a paper document to an enforced runtime control.

Control 4: Time-Stamped Verification and Workable Revocation Paths

The fourth control is about what happens after a signature is produced and, more importantly, after one is found to be malicious. RFC 3161 timestamp authorities bind a signature to a verifiable point in time. Without a timestamp, revoking a code-signing certificate breaks every binary it ever signed, because verifiers cannot tell whether the signature predates the compromise. With a timestamp, a verifier can ask “was this certificate valid at the timestamped moment of signing” rather than “is this certificate valid right now” — the only formulation that allows revocation without breaking legitimate, pre-compromise artifacts.

Microsoft Authenticode, Apple codesign, Java jarsigner, and Sigstore Rekor all support timestamped signatures; the operational discipline of always timestamping is what differs between mature and immature programs.

Revocation has to be a usable lever, not a paper one. The standard mechanisms — certificate revocation via Certificate Revocation Lists (CRL) and OCSP — were designed for web PKI and apply unevenly to code signing.

Microsoft introduced disallowedcert.sst and the Windows Defender Application Control (WDAC) revocation path specifically because OCSP soft-fail behavior made code-signing revocation unreliable. Apple uses the Notarization service as a revocation channel. Sigstore uses the Rekor transparency log so that signatures can be invalidated by reference even when the issuing key is not formally revoked.

Each of these has different latency: a CRL change may take twenty-four hours to propagate; WDAC revocation pushes faster but requires a Microsoft action; Sigstore policy changes are near-instant for systems that re-validate at runtime.

The structural fix that ties this together is short-lived signing certificates. If a code-signing certificate is valid for fifteen minutes instead of three years, revocation reduces to expiry. Sigstore’s Fulcio issues ten-minute certificates bound to OIDC identities; the signature persists because of the timestamp and the Rekor log entry, but the underlying signing certificate is already expired by the time anyone could think about stealing it.

The same model applies inside private PKI: an internal Fulcio-equivalent issues a short-lived signing cert for each release, scoped to one artifact hash, after the quorum approval workflow completes. Compromise the signing key and the attacker has fifteen minutes to do anything with it — and any signature they produce will fail policy because there is no matching ticket, no approval chain, and no SLSA provenance.

The reduction in blast radius is roughly six orders of magnitude over a three-year long-lived signing cert.

Want to master certificate management?

Browse our resources on PKI best practices.

Certificate Transparency closes the last gap. Every code-signing certificate issuance ends up in a public log (or a private log for internal PKI). When SolarWinds, Adobe, or 3CX renews its production signing cert, the issuance is publicly observable.

A rogue cert issued under your name, by your CA, to an impostor, is detected within hours instead of after the fact. CT logs are not a silver bullet — they detect issuance, not signing — but in combination with the previous three controls they give an organization a chance to notice it has been impersonated before customers do.

Control 5: Anomaly Detection on Signing Events

The fifth control treats signing as a security-relevant operational event, on par with privileged authentication or production database access. Every signing operation emits a structured log: timestamp, HSM identifier, key handle, requesting workload identity, source IP, ticket reference, artifact hash, artifact size, target deployment path, SLSA provenance hash, approver identities, policy applied. These events are forwarded in near real time to a SIEM (Splunk, Sentinel, Chronicle, Elastic) where baselines are computed and anomalies trigger out-of-band paging.

The baselines are concrete. Production releases happen on Wednesdays between 14:00 and 17:00 UTC, with an average of three signing operations per release, an average artifact size of forty megabytes, and an average build duration of twenty-two minutes from CI trigger to sign request.

A signing operation at 03:47 UTC on a Sunday, with an artifact size of fourteen megabytes (no embedded resources), originating from a CI runner whose hostname does not match the production build pool, requesting a key handle reserved for the next major release — that event should page on-call within sixty seconds.

SUNBURST’s injection happened on a real build server during a real build window, which is part of why it evaded detection; but the SLSA provenance hash mismatch, the unexpected DLL size, and the absence of a matching review ticket would have failed three correlation rules at signing time.

Reasonable SIEM rules to start with:

  • signing volume per hour outside the historical p99;
  • signing from a workload identity not seen in the last thirty days;
  • signing of an artifact whose hash is not present in the build attestation store;
  • signing operations not preceded by a closed approval ticket within ten minutes;
  • signing operations targeting a deployment path that does not match the project’s registered target list;
  • signing operations from a CI runner whose mTLS client certificate fingerprint changed in the last twenty-four hours.

Each rule is cheap. Each rule catches a different failure mode. None of them require new tooling that does not already exist in the modern SOC stack.

The reason this control is fifth and not first is that it depends on the other four. Without HSM-backed signing, there is no reliable event source. Without SLSA provenance, there is nothing to correlate against. Without quorum approval, there is no ticket to expect. Without timestamping and short-lived certs, there is no narrow window to bound. Anomaly detection is the layer that converts a structurally hardened pipeline into a detective control, and it is what turns “we trust the build” into “we verify the build, and we know within minutes when something is off.”

What ‘Good’ Looks Like in a 2026 SDLC

A reference architecture pulling the five controls together looks like this. Source is in a Git repository with signed commits (Sigstore gitsign, or GPG/SSH-signed commits with verified-committer policy) and branch protection requiring two-reviewer approval.

A merge to main triggers an ephemeral, hermetic build in an isolated runner (GitHub Actions with reusable workflows pinned by commit SHA, GitLab CI with hardened runners, Tekton Chains, Buildkite hosted, or self-hosted on Kata Containers). The runner has no inbound access, fetches dependencies through a verified-attestation proxy, and produces an artifact plus an unsigned in-toto/SLSA Level 3 provenance bundle.

The artifact and bundle are published to an immutable staging registry. A release ticket is opened in the workflow system (Jira, ServiceNow, Linear) with the artifact hash and provenance bundle attached.

The release manager hands the ticket to a quorum of three release engineers with FIDO2 tokens. Each independently verifies the artifact hash, source commit, and SLSA chain through the approval portal, then signs the approval.

The third approval triggers the HSM policy engine to issue a short-lived signing certificate (Fulcio or internal equivalent), valid for ten minutes, bound to the artifact hash, and signs the artifact with an RFC 3161 timestamp. The signing event, the provenance, and the resulting Authenticode/Cosign/Rekor entries are logged to the SIEM and to a transparency log.

Downstream verifiers — production Kubernetes admission controllers, Windows endpoints with WDAC, macOS notarization checks, package managers — do not just validate the signature. They validate that the signature has a matching transparency log entry, that the entry references a SLSA provenance bundle, that the provenance lists an approved builder, that the artifact hash matches, and that the timestamp falls within the certificate’s short validity window.

The whole pipeline, from commit to verifier, sits on top of an organizational PKI that issues short-lived workload identities, signing certificates, and HSM client credentials, with the lifecycle automated rather than ticketed.

None of these components are speculative. SLSA v1.0 is a published standard. Sigstore is generally available and has been adopted by Kubernetes, Python (PyPI), npm, and the Linux kernel. The CA/Browser Forum HSM requirement has been mandatory since 2023. RFC 3161 is twenty-five years old. FIPS 140-3 modules ship from every major HSM vendor.

The gap between a typical 2020-era signing pipeline and the 2026 reference architecture is engineering work and governance discipline, not invention. That is the encouraging part. The discouraging part is that most signing pipelines in production today look closer to SolarWinds 2020 than to SLSA Level 3 2026.

Where Evertrust Fits

The five controls share a common substrate: every one of them depends on a managed, automated, auditable certificate and key lifecycle. The HSM-backed signing key needs a CA to issue and rotate its certificate. The short-lived signing certs need an issuance API capable of producing thousands of ten-minute credentials per day. The quorum-signing tickets need certificate identities for every approver. The anomaly detection rules need a normalized event stream from every CA, HSM, and signing endpoint. The transparency requirement needs CT log integration as a default, not an afterthought.

Evertrust delivers that substrate. Stream the events from your signing HSMs and CAs, automate short-lived certificate issuance for build and release workloads, govern the policy that ties signing keys to approval workflows, and export the audit trail required by the CRA, NIS2, and forthcoming CSC subcommittee code-signing requirements.

The five controls above are how you stop the next SUNBURST. Continuous, automated, policy-driven certificate and key lifecycle management is what makes those controls operable at the scale of a modern engineering organization.

Explore Evertrust Certificate Lifecycle Management to see how the pieces fit.

Found this helpful?
Back to blog

Table of Contents

Stay Updated

Get the latest PKI insights delivered to your inbox.

By subscribing you accept to receive our communications.

Related Articles

Evertrust PQC

Are European enterprises ready for Post-Quantum Cryptography (PQC) migration? The gaps and the path forward

September 10, 2025
1 min

Explore why PQC adoption lags in Europe, the real blockers, and how to achieve quantum-safe security.

Read more
Evertrust PQC

NIST Releases New Post-Quantum Cryptography Standards

September 10, 2025
1 min

Discover NIST’s new Post-Quantum Cryptography standards (FIPS 203, 204, 205) and how Evertrust is preparing to integrate them for enhanced cybersecurity.

Read more
Evertrust ACME

ACME Clients on Linux

February 12, 2024
1 min

The ACME protocol is a network protocol designed to automate the process of domain validation, deliverance and renewal of X.509 certificates. The process is set up between an ACME server and an ACME client.

Read more

Ready to take control of your certificates?

Talk to our experts and discover how Evertrust can help you implement best practices in PKI and certificate lifecycle management.

Talk to an expert