Secure CI/CD Pipelines: SBOM, Image Signing, and Compliance Gates Explained
How to build secure CI/CD pipelines with SBOM generation, container image signing, and compliance gates - practical implementation guide for engineering teams.
Your CI/CD pipeline is not just a deployment mechanism. It is your primary security control plane. Every code change, every dependency update, every container image build passes through it. If security is not embedded here, it is not embedded anywhere.
Yet most pipelines we audit at devsecops.qa have the same gaps: no software bill of materials (SBOM) generation, unsigned container images, and compliance checks that run in “advisory mode” but never actually block a deployment. This article walks through how to build a secure CI/CD pipeline that generates provenance, enforces policy, and produces the compliance evidence your auditors need - without destroying developer velocity.
The Three Pillars of Pipeline Security
A mature secure pipeline rests on three pillars: knowing what you ship (SBOM), proving it has not been tampered with (signing), and enforcing organizational policy before it reaches production (compliance gates). Each pillar builds on the previous one.
Pillar 1: SBOM Generation
A software bill of materials is an inventory of every component in your software - direct dependencies, transitive dependencies, operating system packages in your container image, and their exact versions. Think of it as a nutrition label for software.
SBOMs became a regulatory requirement for US federal software suppliers under Executive Order 14028, and they are increasingly expected by enterprise buyers conducting vendor security assessments. But regulatory compliance is not the primary value. The primary value is operational: when the next Log4Shell happens, an SBOM tells you in minutes which of your services are affected. Without one, you spend days or weeks auditing repositories manually.
Implementation in practice:
For container-based applications, generate SBOMs at two points in the pipeline:
Source SBOM - generated from your dependency manifest files (package.json, go.sum, requirements.txt, pom.xml) during the build stage. Tools: Syft, CycloneDX CLI, or Trivy in SBOM mode. This captures your application dependencies.
Container SBOM - generated from the final built container image. This captures everything: your application dependencies plus the OS packages, system libraries, and runtime components in the base image. Syft handles both source and container SBOMs with a single tool.
# GitHub Actions example
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: ${{ env.IMAGE_TAG }}
format: spdx-json
output-file: sbom.spdx.json
- name: Upload SBOM to dependency tracking
run: |
curl -X POST "https://your-dependency-track.example.com/api/v1/bom" \
-H "X-API-Key: ${{ secrets.DTRACK_API_KEY }}" \
-F "[email protected]" \
-F "projectName=${{ github.repository }}" \
-F "projectVersion=${{ github.sha }}"
SBOM format choice: Use SPDX or CycloneDX - both are recognized standards. SPDX is the format specified by NTIA and preferred for US government compliance. CycloneDX has better tooling support in the vulnerability management ecosystem. Pick one and standardize across your organization.
SBOM storage and tracking: Generate SBOMs and then actually use them. Dependency-Track (open source) or Snyk (commercial) can ingest SBOMs and continuously monitor them against vulnerability databases. When a new CVE is published, Dependency-Track tells you which services and versions are affected - because it has the SBOM on file.
Pillar 2: Container Image Signing
An SBOM tells you what is in your software. Image signing proves that the software has not been modified since it was built. Without signing, an attacker who compromises your container registry can replace a legitimate image with a malicious one - and your production cluster will pull and run it without question.
Cosign (from the Sigstore project) is the standard tool for container image signing. It is open source, backed by the Linux Foundation, and integrates with every major container registry.
The signing workflow:
- Build the container image in your CI/CD pipeline
- Push it to your registry (ECR, GCR, ACR, Docker Hub)
- Sign it with Cosign using a key pair or keyless signing (via OIDC identity from your CI provider)
- Verify the signature before deployment using an admission controller
# Sign with Cosign (keyless - uses GitHub Actions OIDC)
- name: Sign container image
run: |
cosign sign --yes \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
Keyless signing is the recommended approach for CI/CD pipelines. Instead of managing long-lived signing keys (which become their own security problem), keyless signing uses your CI provider’s OIDC identity token as proof of who built the image. The signature includes the identity of the builder (e.g., “this image was built by the main branch of github.com/your-org/your-repo via GitHub Actions”). Sigstore’s transparency log (Rekor) records every signature for public auditability.
Verification at deployment: Signing is only half the equation. You need an admission controller in your Kubernetes cluster that verifies signatures before allowing images to run. Kyverno and OPA Gatekeeper with Cosign integration both support this. The policy is simple: reject any image that does not have a valid signature from your organization’s CI/CD pipeline.
# Kyverno policy - verify image signatures
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: check-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "your-registry.example.com/*"
attestors:
- entries:
- keyless:
issuer: "https://token.actions.githubusercontent.com"
subject: "https://github.com/your-org/*"
Pillar 3: Compliance Gates
Compliance gates are policy enforcement points in your pipeline that block deployments when security or compliance requirements are not met. They transform your pipeline from a delivery mechanism into a governance mechanism.
What compliance gates should check:
- Vulnerability severity thresholds: Block deployment if the container image contains any critical or high-severity vulnerabilities with a known exploit (check EPSS score and CISA KEV catalog, not just CVSS)
- SBOM completeness: Block deployment if SBOM generation failed or the SBOM is incomplete
- Image signature verification: Block deployment if the image is not signed by your CI pipeline
- License compliance: Block deployment if the SBOM contains dependencies with licenses that violate your organization’s policy (e.g., AGPL in a proprietary SaaS product)
- IaC policy violations: Block deployment if Terraform plans contain security misconfigurations (public S3 buckets, unencrypted databases, overly permissive security groups)
- Secret detection: Block deployment if secrets are detected in the codebase or container image layers
The critical design decision: hard gates vs. soft gates.
A hard gate blocks the pipeline. A soft gate logs a warning but allows the deployment to proceed. The right approach is to start soft and go hard:
- Week 1-2: Deploy all gates in soft mode (warn only). Measure the failure rate and false positive rate.
- Week 3-4: Tune the policies based on real data. Adjust severity thresholds, add exceptions for known false positives, align with your vulnerability SLAs.
- Week 5+: Enable hard enforcement for the gates with acceptable false positive rates. Keep gates with high false positive rates in soft mode until the tooling improves.
Policy-as-code with OPA or Kyverno is the enforcement mechanism. Define your compliance policies as code, version them alongside your application code, and apply them consistently across every pipeline and every cluster.
Generating Compliance Evidence Automatically
The most overlooked benefit of a secure pipeline is automated compliance evidence generation. Every pipeline run that passes through your compliance gates produces auditable records:
- SBOM artifacts stored in your registry or artifact store - evidence for NTIA/EO 14028 requirements
- Signing records in the Sigstore transparency log - evidence of build provenance and integrity
- Gate pass/fail records in your CI/CD system - evidence that policy was enforced
- Vulnerability scan results archived per build - evidence for SOC 2 CC7.1, ISO 27001 A.12.6
When your auditor asks “how do you ensure that vulnerable software is not deployed to production?”, you show them the pipeline configuration, the compliance gate policy, and the historical pass/fail records. The evidence generates itself with every deployment.
The Developer Experience Problem
The number one reason secure pipelines fail is developer pushback. If your compliance gates add 15 minutes to every build and produce 50 false positives per week, developers will find workarounds. They will push directly to the registry. They will add blanket exception rules. They will stop trusting the tooling.
How to avoid this:
- Speed: Run security scans in parallel, not sequentially. SAST, SCA, container scanning, and IaC scanning can all run simultaneously. A well-optimized security stage adds 2-3 minutes, not 15.
- Signal quality: Tune your tools aggressively. A vulnerability scanner that reports 200 findings with 150 false positives is worse than useless - it teaches developers to ignore all findings. Use exploitability analysis (EPSS, reachability analysis) to surface only the findings that matter.
- Fast feedback: Show security findings in the pull request, not just in the pipeline logs. GitHub Security tab, GitLab Security Dashboard, or PR comments from your scanning tools. Developers should see findings where they already work.
- Exception process: Provide a documented, fast process for legitimate exceptions. If a finding is a confirmed false positive or an accepted risk, developers should be able to suppress it with an auditable record - not by disabling the gate entirely.
Implementation Sequence
If you are starting from zero, here is the sequence that delivers the most value fastest:
Phase 1 (Week 1-2): SBOM and vulnerability scanning. Add Syft for SBOM generation and Trivy for vulnerability scanning to your pipeline. Run in advisory mode. Start collecting data.
Phase 2 (Week 3-4): Secrets detection and IaC scanning. Add Gitleaks for secrets detection and Checkov or tfsec for IaC scanning. Still advisory mode. Tune false positives.
Phase 3 (Week 5-6): Image signing. Implement Cosign keyless signing in your pipeline. Deploy Kyverno or Gatekeeper for signature verification in your staging cluster first.
Phase 4 (Week 7-8): Hard enforcement. Enable hard compliance gates for the checks with acceptable signal quality. Roll out signature verification to production.
Phase 5 (Ongoing): Continuous improvement. Monitor gate metrics (pass rate, false positive rate, mean time to remediation). Adjust policies quarterly.
What This Looks Like in Production
A mature secure pipeline runs in under 10 minutes and produces the following artifacts for every build:
- SBOM in SPDX or CycloneDX format, stored in your artifact registry
- Signed container image with keyless Cosign signature recorded in Rekor
- Vulnerability scan results with zero critical/high findings (or documented exceptions)
- Clean secrets scan and IaC policy check
- Compliance gate pass record with timestamp and policy version
This is not theoretical. It is what well-implemented DevSecOps looks like in practice. The devsecops.qa team delivers Secure CI/CD implementations in 4-12 weeks, covering SBOM generation, image signing, compliance gates, and the developer experience work that makes it sustainable. Contact us to discuss your pipeline security requirements.
Get Started for Free
Free 30-minute DevSecOps consultation - global, remote, actionable results in days.
Talk to an Expert