A stolen code signing key lets an attacker's malware arrive with your name on it, and operating systems, allowlists and customers will trust it. Signing keys are among the most valuable machine credentials an organisation holds, yet they are still found as PFX files on build servers, in CI variables and on laptops. This guide covers how code signing works across Windows, macOS, Linux and containers, the CA/Browser Forum rules for key custody, signing services with approvals and timestamping, verification at install time, and response to key theft. It is written for build and release engineers, PKI owners and the security teams who govern signing.
Key takeaways
- A signature proves who signed, not that the code is safe. Attackers either steal keys or get their code into a pipeline that signs automatically, so protect both the key and what can reach it.
- Hardware custody is mandatory for public certificates. Since 1 June 2023 the CA/Browser Forum requires code signing private keys to be generated, stored and used in a hardware crypto module.
- Centralise signing behind a service. Builds request signatures through an authenticated, logged service with approval rules; nobody holds the key and no pipeline can sign an arbitrary file.
- Always timestamp. Without an RFC 3161 timestamp Windows treats a binary as unsigned once its certificate expires, and timestamps are what make a targeted revocation possible.
- Verification is the control that matters. Signing only helps where something checks it: App Control for Business, Gatekeeper, package manager checks and container admission policies.
Why code signing keys are high-value targets
Code signing binds a publisher identity to a file hash, and operating systems, endpoint products and allowlists use that identity to decide what runs. MITRE ATT&CK tracks the abuse as T1553.002 Code Signing (now under Defense Impairment, TA0112) and T1588.003 Obtain Capabilities: Code Signing Certificates, with examples including APT41, BlackTech, Kimsuky and OilRig using stolen certificates. ATT&CK notes the technique "cannot be easily mitigated with preventive controls", so custody and verification carry the weight.
NVIDIA's code signing certificates, leaked by Lapsus$ in 2022, were used to sign malware. The MSI signing keys leak in 2023 exposed firmware and Intel Boot Guard keys that cannot simply be rotated on devices already sold. AnyDesk revoked its code signing certificate after a production compromise in 2024, and the GitHub code signing certificate theft in 2022 began with a machine account's token exposing the GitHub Desktop and Atom signing keys.
| How signatures get subverted | What it looks like | Primary control |
|---|---|---|
| Key theft | PFX file or key copied from a build server, laptop or CI secret | Non-exportable keys in an HSM or cloud KMS |
| Abuse of a legitimate pipeline | Attacker code enters the build and is signed automatically, as with SUNBURST in the SolarWinds compromise | Sign only artefacts with verified build provenance; release approvals |
| Misrepresentation | A certificate obtained for a lookalike or shell company | Pin specific publishers, not "any signed file" |
| Improper validation | Verifier skips chain, revocation or timestamp checks | Enforced verification policy |
| Key recreation | Weak key generation or deprecated algorithms allow forgery | SHA-256 or stronger digests; keys generated in certified hardware |
| Policy modification | Local trust changed, such as an added root certificate or test signing enabled | Locked trust stores and boot configuration; alert on change |
Signing ecosystems at a glance
| Ecosystem | Mechanism | Verified by | Key points |
|---|---|---|---|
| Windows applications | Authenticode; signtool sign /fd SHA256 /tr <url> /td SHA256 | Windows, SmartScreen, App Control for Business, EDR | Certificates issued from 1 March 2026 limited to 460 days; Microsoft recommends SHA-256 |
| Windows kernel drivers | Microsoft hardware dev portal (attestation or HLK-tested signing) | Windows code integrity | From Windows 10 version 1607 new kernel drivers must be portal-signed; an EV code signing certificate is needed for the account |
| macOS | Developer ID with Hardened Runtime and secure timestamp, then notarisation | Gatekeeper, using the stapled or online ticket | Developer ID software built after 1 June 2019 must be notarised (macOS 10.15+) |
| Linux packages | OpenPGP signatures on repository metadata (apt) or packages (RPM) | apt signed-by keyrings; dnf gpgcheck=1 | Each repository key is a root of trust |
| Java | jarsigner with -tsa timestamping | Java runtime and tooling | Same custody rules as Authenticode |
| Containers and OCI artefacts | Sigstore cosign or Notary Project Notation | Admission control with cosign verify or notation verify | Signatures stored in the registry beside the image |
Key custody: hardware, cloud KMS and the CA/Browser Forum rules
The CA/Browser Forum Baseline Requirements for Code Signing Certificates (version 3.11.0 at the time of writing) require, from 1 June 2023, that the subscriber's private key be "generated, stored, and used in a suitable Hardware Crypto Module", and that signing services protect keys in a FIPS 140-2 Level 2 (or equivalent) module. Timestamp authority root keys must be held in offline hardware from 15 April 2025, and revocation for key compromise and suspect code was tightened from 15 April 2024. CAs typically ask for evidence, such as an HSM or KMS key attestation, before issuing.
| Custody option | Strengths | Weaknesses | Best fit |
|---|---|---|---|
| USB token | Cheap, meets the hardware rule | Tied to one machine; hard to automate; PINs end up in scripts | Very small publishers |
| Network HSM | Strong isolation, full control | Cost, skills, availability design | Large and firmware vendors, regulated sectors |
| Cloud KMS or HSM | Non-exportable keys, IAM control, audit logs | Cloud IAM becomes the key's boundary | Most cloud-native organisations |
| Managed signing service | Provider runs HSM and certificate | Provider dependency; policy depth varies | Teams without PKI staff |
| Keyless (Sigstore) | No long-lived key; transparency log | Not in Windows or macOS trust stores; verifiers must pin identities | Containers, open source, internal artefacts |
Decision guidance: a small team with one product can use a managed signing service and own no hardware. Mid-size organisations are usually best served by cloud KMS keys behind their own signing service, so CI authenticates with workload identity and never sees a key. Firmware vendors need HSMs and key ceremonies, because keys burned into devices cannot be rotated quickly. Use keyless signing for containers and internal artefacts, and publicly trusted certificates for what Windows, macOS and customers verify. See the Cryptographic Key Management Guide.
Building a signing service with approvals
NIST's Security Considerations for Code Signing recommends keys in an HSM "with minimal functionality (e.g., signing)", separating administration of the signing system from authorised submitters, and to "Consider requiring two people to approve code for signing and/or the use of multi-factor authentication." It also says organisations should "review and vet code to ensure it is trustworthy" before signing.
- Digest signing: the build sends a hash and receives a signature. SignTool supports this with
/dlib, which calls anAuthenticodeDigestSignimplementation, so the key never leaves the HSM or KMS. - Authenticated callers: pipelines authenticate with short-lived workload identity (OIDC federation), not shared passwords or API keys. See the CI/CD Pipeline Identity Security Guide.
- Policy before signing: sign only artefacts from protected branches and known workflows, ideally with SLSA provenance, and never builds from developer machines. See the SLSA and Build Provenance Guide.
- Separate keys by risk: different keys for production, drivers, internal tools and test builds; test certificates never chain to a public root or get trusted in production.
- Two-person approval: automatic signing for internal builds, human approval for production and driver releases.
Timestamping and revocation
Microsoft's guidance is blunt: "Always time-stamp your Authenticode signatures. Without a time stamp, the signature becomes invalid when the signing certificate expires, and Windows will treat the binary as unsigned." Use RFC 3161 (/tr with /td SHA256) rather than the legacy /t protocol. Apple notarisation requires a secure timestamp, and NIST notes a timestamp lets a verifier accept a signature if the key was valid when the code was signed.
- Timestamp services: allow outbound access to the timestamp authority from the signing service only, and alert on timestamp failures, because SignTool only warns.
- Revocation with a date: when a key is compromised, agree the revocation date with the CA. Signatures timestamped before it can stay valid while anything signed later fails, so you do not break every release you shipped.
- Verifiers must check: NIST says a verifier should "be able to check revocation or have a secure mechanism for updating the trust anchors"; offline systems need a route for revocation data.
- GPG keys: publish a revocation and the new fingerprint through a channel users already trust, as HashiCorp did.
Verification at install and run time
- Windows App Control for Business (WDAC): prefer FilePublisher or SignedVersion rules, which combine the issuing CA, the leaf certificate's common name and a minimum version, over PcaCertificate rules that trust everything a CA issues. Option 20 Enabled:Revoked Expired As Unsigned treats revoked-certificate binaries as unsigned, option 2 Required:WHQL requires WHQL-signed drivers, and option 3 Enabled:Audit Mode is the starting point. Signer rules support RSA keys only, up to 4096 bits. See the Application Allowlisting Guide.
- macOS Gatekeeper: checks Developer ID signatures and notarisation tickets on first launch. Apple notes notarisation "also protects your users if your Developer ID signing key is exposed", because Apple can revoke tickets for unauthorised versions. Test releases with
codesign --verifyandspctl --assess. - Linux: keep
gpgcheck=1and use per-repositorysigned-bykeyrings, so one third-party key cannot vouch for another repository. - Containers: verify in admission control with an identity pin;
cosign verifytakes--certificate-identityand--certificate-oidc-issuerso signatures from any other workflow are rejected. - Your own releases: run
signtool verify /pa /allor the platform equivalent and fail a release that is unsigned, untimestamped or signed by the wrong certificate.
Keyless signing and identity-bound certificates
Sigstore keyless signing "associates identities, rather than keys, with an artifact signature". The signer authenticates with OpenID Connect, Fulcio "issues short-lived certificates binding an ephemeral key to an OpenID Connect identity", the key is discarded, and the event is recorded in the Rekor transparency log. There is no long-lived key to steal; the risk moves to whoever can run the trusted workflow or obtain its OIDC token. Restrict who can modify signing workflows, pin verification to the exact identity and issuer, and monitor Rekor for your identities. The Notary Project's Notation is a key-based alternative for OCI artefacts, with trust policies, timestamping and plugins for external key stores.
Where identity fits: signing keys as privileged machine identities
- Inventory and ownership: record every signing certificate, key location, CA account, expiry and accountable owner, including GPG release keys and Apple Developer ID certificates. See the Machine Identity, PKI and Certificate Lifecycle Guide.
- Identities that reach the key are the key: grant CI service accounts and KMS roles sign-only permissions, deny export and key administration, and require phishing-resistant MFA on CA and Apple developer accounts.
- Secrets hygiene: search repositories, CI variables and build images for
.pfx,.p12and private keys, and treat any find as a compromise. The HashiCorp GPG key exposure happened because the release key sat in a CI environment the compromised Codecov uploader could read. See the Secrets Management Guide.
Implementing a code signing programme
- Discover: list certificates from CA accounts, scan build infrastructure and repositories for key files, and inventory what you sign.
- Design custody: choose HSM, cloud KMS or managed service per key class and generate new non-exportable keys with attestation.
- Stand up the service: digest signing, workload identity, provenance checks, approvals and logging; pilot one product alongside the old process.
- Migrate and retire: move each product, then revoke old certificates once timestamps are confirmed and destroy legacy key files.
- Enforce verification: App Control publisher rules in audit mode on a pilot ring, review event 3076 audit entries, then enforce ring by ring; same pattern for container admission.
- Rehearse and roll back: tabletop a stolen key (CA contact, revocation date, re-signing, customer notice), keep previous policy versions ready to redeploy, and never destroy an old key until every product has shipped a release signed with the new one.
Detection and measurement
- Signing logs: caller identity, artefact hash, build reference and approver for every request; alert on signing outside release windows or for artefacts without provenance.
- Key access: KMS and HSM audit events for policy changes, new principals and export attempts.
- Endpoint signals: ATT&CK DET0230 analytics cover binaries signed with unusual, recently issued, revoked or unknown certificates, and Gatekeeper and
spctlevents. Watch for files carrying your certificate that your service never signed.
Metrics
- Keys outside hardware: signing keys found as files or in exportable stores (target zero).
- Service coverage: share of production signatures issued by the central service.
- Timestamp coverage: share of shipped binaries with a valid RFC 3161 timestamp (target 100%).
- Provenance-gated signing: share of signatures where build provenance was verified first.
- Time to revoke: hours from confirmed compromise to revocation and a re-signed release.
Common failure patterns
- Keys in CI variables: one compromised build tool reads every secret in the environment, as in the HashiCorp case.
- Signing whatever the build produces: without provenance checks a service signs an attacker's binary as readily as yours, which is how SolarWinds customers received a signed backdoor.
- Allowlists that trust a whole CA: PcaCertificate rules or "any signed file" policies let stolen and fraudulently obtained certificates through.
- No timestamps: revocation then invalidates every past release, making teams reluctant to revoke, yet revocation can be forced at short notice, as AnyDesk's 2024 incident showed.
- Firmware keys without a rotation plan: the MSI leak exposed keys embedded in shipped devices.
- Machine accounts near signing material: the GitHub theft started from a machine account token, not a person.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | T1553.002 (TA0112), T1588.003 (TA0042) | Code signing abuse; stolen or purchased signing certificates |
| CA/Browser Forum | Code Signing BRs 6.2.7.4, 6.3.2, 4.9.1 | Hardware key protection, 460-day validity, revocation |
| NIST SP 800-53 Rev. 5 | CM-14, SI-7(15), SC-12, SR-11 | Signed components, code authentication, key management, component authenticity |
| NIST CSF 2.0 | ID.RA-09 | Software authenticity and integrity assessed before use |
| CIS Controls v8.1 | 2.5, 2.6, 2.7 | Allowlist authorised software, libraries and scripts |
| ISO/IEC 27001:2022 | A.8.24, A.8.25, A.8.19 | Cryptography; secure development life cycle; software installation |
Practitioner checklist
- Inventory every signing certificate and key with owner, location, CA account and expiry.
- Move all signing keys into non-exportable HSM or cloud KMS storage and destroy legacy key files.
- Route production signing through a central service with digest signing, workload identity and logging.
- Sign only artefacts with verified provenance, with two-person approval for release and driver signing.
- Timestamp every signature with RFC 3161 and fail releases that are unsigned or untimestamped.
- Enforce verification: App Control publisher rules, Gatekeeper, gpgcheck and signed-by, identity-pinned admission.
- Require phishing-resistant MFA on CA portals and Apple developer accounts.
- Keep a tested key compromise runbook covering revocation date, re-signing and customer notice.
Standards and references
- CA/Browser Forum: Baseline Requirements for Code Signing Certificates
- NIST: Security Considerations for Code Signing
- MITRE ATT&CK: T1553.002 Subvert Trust Controls: Code Signing
- Microsoft Learn: Time stamping Authenticode signatures
- Microsoft Learn: App Control for Business policy and file rules
- Apple Developer: Notarizing macOS software before distribution
- Sigstore: Signing overview
- HashiCorp: HCSEC-2021-12 Codecov Security Event and GPG Key Exposure
Related NHI Mgmt Group resources: Machine Identity, PKI and Certificate Lifecycle Guide · Cryptographic Key Management Guide · SLSA and Build Provenance Guide · Application Allowlisting Guide · CI/CD Pipeline Identity Security Guide