Code Signing in CI/CD Pipelines
Key Takeaways
- Code signing in CI/CD automates signature creation so every release artifact is signed without manual steps
- The signing key must never exist as a plaintext file in the pipeline — use HSMs, cloud KMS, or vault-based signing services
- Signing should happen on a dedicated, hardened signing server — not on the same build agent that compiles code
- A compromised CI/CD pipeline with signing access is equivalent to a compromised signing key — secure the pipeline as critical infrastructure
Code signing in CI/CD integrates digital signature creation into your automated build and release pipeline. Instead of a developer manually signing artifacts on their workstation, the pipeline signs every build artifact (executables, containers, packages, firmware) as part of the release process. This ensures consistency (every release is signed), eliminates human error (no forgotten signatures), and enables verification at every downstream stage (deployment, distribution, installation).
Why it matters
- Consistency — every artifact that leaves the pipeline is signed. No unsigned releases slip through because someone forgot or was unavailable.
- Speed — signing happens automatically in seconds as part of the build. No waiting for a human to sign and upload.
- Audit trail — the pipeline logs exactly what was signed, when, by which key, and which commit/build produced it. Complete provenance chain.
- Security boundary — the signing key is accessed only by the pipeline, not by individual developers. Reduces the number of people who can sign (and therefore the attack surface).
- Supply chain integrity — consumers of your software can verify that artifacts came from your official pipeline, not from a compromised developer machine or rogue build.
How it works
- Build stage — pipeline compiles code, runs tests, produces final artifact (binary, container image, package)
- Signing request — pipeline sends the artifact (or its hash) to a signing service or invokes the signing tool with HSM/KMS credentials
- Key access — the signing key is accessed from secure storage (HSM via PKCS#11, cloud KMS API, or HashiCorp Vault). The key never exists as a file in the pipeline.
- Signature creation — the signing service computes the hash and signs it with the private key. Timestamp is applied from a TSA.
- Signature attachment — the signature is embedded in or attached to the artifact
- Verification — pipeline verifies the signature immediately after creation (catches signing failures before release)
- Publication — signed artifact is published to the distribution channel (registry, CDN, package repository)
In real systems
GitHub Actions with cloud KMS signing:
jobs:
build-and-sign:
runs-on: ubuntu-latest
permissions:
id-token: write # For OIDC authentication to KMS
steps:
- uses: actions/checkout@v4
- run: make build # Produce artifact
- name: Sign with Google Cloud KMS
run: |
gcloud auth login --cred-file="${{ secrets.GCP_CREDENTIALS }}"
gcloud kms asymmetric-sign \
--location=us-east1 \
--keyring=code-signing \
--key=release-key \
--version=1 \
--digest-algorithm=sha256 \
--input-file=build/myapp \
--signature-file=build/myapp.sig
Container image signing with cosign:
- name: Sign container image
run: |
cosign sign --key gcpkms://projects/myproj/locations/us/keyRings/signing/cryptoKeys/cosign \
ghcr.io/myorg/myapp:${{ github.sha }}
Windows Authenticode in Azure DevOps:
- task: DotNetCoreCLI@2
inputs:
command: 'build'
- task: AzureKeyVault@2
inputs:
azureSubscription: 'production'
KeyVaultName: 'code-signing-vault'
- script: |
AzureSignTool sign -kvu "$(SigningVaultURL)" \
-kvi "$(SigningClientId)" -kvs "$(SigningClientSecret)" \
-kvc "$(SigningCertName)" -tr http://timestamp.digicert.com \
-td sha256 "build/MyApp.exe"
Dedicated signing server pattern:
Build Agent → produces unsigned artifact → uploads to signing queue
Signing Server (hardened, HSM-attached) → picks up artifact → signs → returns
Build Agent → downloads signed artifact → publishes
# Signing server:
# - No internet access (except timestamp server)
# - No developer access
# - HSM-attached (PKCS#11)
# - Audit logging of all signing operations
# - Rate limiting (detect anomalous signing volume)
Where it breaks
Signing key as pipeline secret — the signing private key is stored as a CI/CD secret (environment variable or secret file). Any pipeline job can access it. A compromised dependency, malicious PR, or misconfigured workflow can exfiltrate the key. The key should never be extractable — use HSM/KMS where the pipeline can request signatures but never access the raw key material.
Pipeline compromise = signing compromise — an attacker gains access to the CI/CD system (stolen credentials, supply chain attack on a build dependency, compromised runner). If the pipeline has signing permissions, the attacker can sign malicious artifacts. Mitigations: require approval gates before signing, limit which branches can trigger signing, monitor signing volume for anomalies, and use short-lived credentials (OIDC) instead of long-lived secrets.
Signing before final artifact — the pipeline signs the binary, then a subsequent step modifies it (strips debug symbols, adds version metadata, repackages into an installer). The signature is now invalid. Signing must be the absolute last transformation. If post-processing is needed, sign the final output — not an intermediate artifact.
Operational insight
The most secure CI/CD signing architecture separates the signing operation from the build environment entirely. The build pipeline produces an unsigned artifact and submits it to a signing service (separate infrastructure, separate access controls, separate audit). The signing service validates the request (is this from an authorized pipeline? Is the artifact from a protected branch? Does the signing volume look normal?), signs it, and returns the signed artifact. This way, compromising the build pipeline doesn’t automatically grant signing access — the attacker must also compromise the signing service’s authorization checks. This is the pattern used by Microsoft, Google, and Apple for their own software releases.
Related topics
Ready to Secure Your Enterprise?
Experience how our cryptographic solutions simplify, centralize, and automate identity management for your entire organization.