Skip to content
DevOpsifyHubCloud · DevSecOps
All resources

DevSecOps · Practical outline

How to Build a Secure CI/CD Pipeline

By Shahrooz Mehmood · · 9 min read

Your CI/CD system has write access to production. That makes it one of the most valuable targets in your infrastructure — and one of the best places to enforce security consistently. This outline walks through the controls worth putting in place, roughly in the order most teams should tackle them.

Secure CI/CD delivery pipeline

  • Source
  • Build
  • Security
  • Deploy
  • Observe
  1. 01Git repositoryBranch protection and pull-request review
  2. 02CI pipelineReusable workflow templates
  3. 03Automated testsUnit, integration and contract tests
  4. 04Security scansSAST, SCA, IaC and image scanning
  5. 05Container registryImmutable, versioned images
  6. 06DeployControlled promotion between environments
  7. 07Health & monitoringReadiness checks, metrics and rollback
Every change follows the same reviewed, tested and scanned path to production, with health checks and monitoring after deploy.

1. Secure the source and the pipeline itself

Before scanning anything, make sure the pipeline cannot be trivially abused.

  • Protect the default branch: required reviews, status checks and no force-pushes.
  • Use short-lived, OIDC-based credentials for cloud access instead of long-lived keys in CI variables.
  • Pin third-party actions and plugins to a commit SHA or verified version.
  • Restrict who can modify pipeline definitions and production deployment jobs.
  • Separate build runners for untrusted pull requests from those with deployment permissions.

2. Keep secrets out of code and logs

Most real-world pipeline incidents involve leaked credentials.

  • Run secret detection (e.g. Gitleaks) in pre-commit hooks and in CI.
  • Store secrets in a managed secret store and inject them at runtime.
  • Mask secrets in logs and avoid echoing environment variables in scripts.
  • Have a rotation runbook ready for when a secret is exposed — it will happen.

3. Add layered scanning

Each scanner covers a different risk. Introduce them one at a time, in report-only mode first.

  • SAST for insecure code patterns (e.g. Semgrep, CodeQL).
  • SCA for vulnerable and outdated dependencies (e.g. Snyk, Dependabot).
  • IaC scanning for cloud and Kubernetes misconfigurations (e.g. Checkov, tfsec).
  • Container image scanning for OS and library CVEs (e.g. Trivy, Snyk Container).

4. Define gates and an exception process

Scanning without a policy produces noise. Decide in advance what blocks a release.

  • Block on new critical/high findings that have a fix available.
  • Report medium and low findings to owners without blocking.
  • Allow time-boxed, approved exceptions with a recorded justification.
  • Assign remediation ownership and target timelines per severity.

5. Protect artifact integrity

Make sure what you deploy is exactly what you built and tested.

  • Build once, then promote the same immutable artifact between environments.
  • Reference images by digest in deployment manifests.
  • Generate an SBOM for each release and consider signing images (e.g. Sigstore cosign).
  • Restrict who and what can push to your container registry.

6. Make it auditable

Good pipelines produce evidence as a side effect.

  • Retain scan reports as pipeline artifacts.
  • Log approvals and exceptions with who, when and why.
  • Track a small set of metrics: open critical findings, mean time to remediate, exceptions outstanding.

You'll talk directly with Shahrooz Mehmood

Want a second pair of eyes on your setup?

A free discovery call is a quick way to find out which of these practices would make the biggest difference for your team.

  • Free 30-minute call
  • No obligation, no hard sell
  • Personal reply within two business days