DevSecOps Pipeline: Building Security Into CI/CD, Step by Step
DevOps2026-09-23Agentixly Team

DevSecOps Pipeline: Building Security Into CI/CD, Step by Step

A DevSecOps pipeline moves security into pre-commit, PR, build, deploy and runtime. See the stages, tools, a GitHub Actions example and a rollout plan.

A DevSecOps pipeline is a CI/CD pipeline with automated security controls built into every stage, from the first commit through production, instead of one security review bolted on before launch. It replaces a single gate with five: pre-commit, pull request, build, deploy and runtime, each with its own controls and tools. This guide walks through every stage with real tool examples, a working GitHub Actions workflow, and a rollout plan you can start this quarter.

The payoff is not just fewer breaches. Teams that catch a vulnerability in a pull request fix it in minutes; teams that catch the same class of bug in production spend days on incident response, disclosure and customer trust repair, on top of the fix itself.

What Is a DevSecOps Pipeline?

DevSecOps extends DevOps by making security a shared, automated responsibility instead of a separate team that reviews finished work. The OWASP CI/CD Security Cheat Sheet frames the pipeline itself as an attack target that needs its own controls, not just a delivery mechanism for secure code. Shift left security means catching a vulnerability in a pull request, where fixing it takes minutes, instead of in production, where fixing it takes an incident. This guide focuses on the security layer itself; for the broader operating model it sits inside, see our DevOps best practices guide.

| Stage | Purpose | Example Controls | Example Tools | | --- | --- | --- | --- | | Pre-commit | Stop obvious mistakes before they reach the repository | Secret scanning, linters, formatters | Gitleaks, the pre-commit framework, ESLint | | Pull request | Review code and its dependencies before merge | SAST, software composition analysis, IaC scanning, human review | CodeQL, Trivy, Semgrep | | Build | Produce a trustworthy, traceable artifact | SBOM generation, artifact signing, provenance | Syft, Sigstore and cosign, SLSA provenance | | Deploy | Enforce policy before anything reaches production | Policy as code, admission control | Open Policy Agent, Kyverno, conftest | | Runtime | Catch what static analysis cannot | DAST, cloud security posture management, runtime detection | OWASP ZAP, cloud-native CSPM tools, eBPF-based runtime agents |

No two pipelines look identical, and the tools above are examples, not a mandate. What matters is that every stage has an owner, an automated check and a documented response for when the check fails.

This five-stage split is not just a convenient way to organize tools; it mirrors how NIST's Secure Software Development Framework (SP 800-218) groups secure development practices into preparing the organization, protecting software, producing well-secured software and responding to vulnerabilities. A pipeline built stage by stage against a recognized framework is also easier to defend in a SOC 2 audit or an enterprise security questionnaire, because each control maps to a named practice instead of an ad hoc habit one engineer set up.

How Do You Secure Pre-Commit and Pull Requests?

Pre-commit hooks catch the cheapest mistakes: hardcoded credentials, obvious lint failures, formatting drift. Tools such as Gitleaks or the pre-commit framework run locally, in seconds, before code ever reaches a shared branch. A secret that reaches git history needs to be rotated, not just deleted, because the commit history keeps it recoverable long after the file changes.

Pull requests carry the heaviest security load, since this is the last point where a human reviews a change before it merges. Static application security testing (SAST) analyzes source code for vulnerable patterns; GitHub's CodeQL is a common choice for teams already on GitHub, since it runs natively in Actions and reports directly into the Security tab. Software composition analysis (SCA) checks third-party dependencies for known vulnerabilities; scanners such as Trivy compare your lockfile against public vulnerability databases on every run.

Infrastructure as code (IaC) scanning applies the same idea to Terraform, CloudFormation and Kubernetes manifests, catching a public storage bucket or an overly broad IAM policy before it is ever applied. None of this replaces human review: automated checks catch known patterns, while reviewers catch business logic flaws and unnecessary complexity that no scanner understands. Treat a clean scan as a minimum bar; our API security best practices guide covers what reviewers should look for once a pull request touches an API.

How Do You Build an SBOM and Sign Your Artifacts?

A software bill of materials (SBOM) is a machine-readable inventory of every component in a build: direct dependencies, transitive dependencies, and their versions and licenses. CISA's SBOM guidance describes it as a nested inventory that lets you identify what is in your software, which matters the moment a new CVE drops and you need to know, in minutes rather than days, whether you ship the affected package. The two common formats are SPDX and CycloneDX, and tools such as Syft generate either one from a filesystem, a container image or a build artifact.

Generating an SBOM is only half the job. You also need to trust that the artifact matches the SBOM and that nobody tampered with it between build and deploy. Sigstore, an open-source signing project, and its cosign tool let you sign artifacts keylessly, using a short-lived certificate tied to your CI identity (a GitHub Actions OIDC token, for example) instead of a long-lived private key that can leak. Anyone can then verify the signature against a public transparency log without you managing key material at all.

SLSA (Supply-chain Levels for Software Artifacts), now an OpenSSF project with a stable v1.0 specification, defines increasing levels of build integrity, from a documented build process at the lowest level to a fully verifiable, tamper-resistant build platform at the highest. Most mid-market companies do not need to chase the top level immediately. Generating provenance, a signed record of how an artifact was built, from which source, on which system, is the practical starting point, and it is what the workflow below produces.

A GitHub Actions DevSecOps Pipeline Example

The workflow below runs on every pull request and on pushes to main. It scans for secrets, runs static analysis, and checks dependencies and infrastructure code in parallel jobs, then, only on main and only once those checks pass, builds the application, generates a software bill of materials and signs it keylessly with Sigstore. Adjust the language matrix, package manager commands and branch names to your own stack; the structure is what matters.

name: DevSecOps Pipeline

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  secrets-scan:
    name: Secret scanning
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v3
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  sast:
    name: Static analysis (CodeQL)
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v7
      - uses: github/codeql-action/init@v4
        with:
          languages: javascript-typescript
          build-mode: none
      - uses: github/codeql-action/analyze@v4

  dependency-and-iac-scan:
    name: SCA and IaC scanning (Trivy)
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v7
      - name: Scan dependencies for known vulnerabilities
        uses: aquasecurity/trivy-action@v0.36.0
        with:
          scan-type: "fs"
          scan-ref: "."
          format: "sarif"
          output: "trivy-deps.sarif"
          severity: "CRITICAL,HIGH"
          exit-code: "1"
      - name: Scan Terraform and Kubernetes manifests
        uses: aquasecurity/trivy-action@v0.36.0
        with:
          scan-type: "config"
          scan-ref: "."
          format: "sarif"
          output: "trivy-config.sarif"
          severity: "CRITICAL,HIGH"
      - name: Upload results to the Security tab
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: "."

  build-sbom-sign:
    name: Build, SBOM and signed artifact
    needs: [secrets-scan, sast, dependency-and-iac-scan]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: "22"
      - name: Install and build
        run: |
          npm ci
          npm run build
      - name: Generate a CycloneDX SBOM
        uses: anchore/sbom-action@v0
        with:
          path: "."
          format: "cyclonedx-json"
          output-file: "sbom.cdx.json"
      - name: Install cosign
        uses: sigstore/cosign-installer@v4.1.2
      - name: Sign the SBOM keylessly
        run: cosign sign-blob --yes sbom.cdx.json --output-signature sbom.cdx.json.sig

Three details are easy to miss. First, fetch-depth: 0 on checkout gives Gitleaks full commit history to scan, not just the latest commit. Second, the build job only starts after the three scanning jobs succeed, through needs, so a signed artifact can never skip its own security gate. Third, keyless signing needs id-token: write permission so the job can request a short-lived OIDC token from GitHub; without it, cosign has no identity to sign with.

How Do You Secure Deploy and Runtime?

Deploy-time controls stop a technically valid but policy-violating change from reaching production. Policy as code tools, such as Open Policy Agent, its Kubernetes-focused counterpart Kyverno, or conftest for testing Terraform plans and manifests in CI, let you write rules such as "no container may run as root," "no load balancer may skip TLS," or "no image outside our approved registry may deploy" as code, reviewed and versioned like everything else. In a Kubernetes cluster, these typically run as admission controllers: a deployment that violates policy is rejected before it is scheduled, not flagged after the fact.

Start with two or three high-value rules instead of importing a large policy library on day one. A rule nobody understands gets disabled the first time it blocks a legitimate deploy, and a disabled policy engine is worse than none, since it creates a false sense of coverage.

Runtime is the stage static analysis cannot reach, because some issues only exist once the application is running with real configuration and real traffic. Dynamic application security testing (DAST) tools, such as OWASP ZAP, attack a running application the way an external attacker would. Cloud security posture management (CSPM) continuously checks live cloud configuration against policy, catching drift that IaC scanning missed because someone changed a setting by hand after deployment. Runtime detection tools watch running workloads for anomalous behavior, such as a container unexpectedly spawning a shell.

Our zero trust security guide covers the identity and network controls that sit alongside these runtime protections, and our guide to DevOps as a service covers who typically owns this stage when a team has no dedicated platform or security engineer yet.

How Do You Triage Findings Without Alert Fatigue?

A pipeline that blocks every merge on every finding trains developers to bypass it. The fix is not fewer scans; it is a severity model that separates what must block a merge from what becomes a tracked, scheduled fix.

| Severity | Example | Response | Typical Fix Window | | --- | --- | --- | --- | | Critical | Remote code execution, a secret exposed in a public repository | Block merge or deploy immediately | Same day | | High | Injection flaw, a clear privilege escalation path | Block merge; escalate to on-call if already in production | 3 to 5 business days | | Medium | Missing security header, an outdated dependency with no known exploit | Ticket only, does not block merge | Current or next sprint | | Low | Style or best-practice deviation | Logged and batched | Best effort |

Illustrative scenario: a 25-engineer SaaS company turns on SAST, SCA, secret and IaC scanning across 40 repositories. Assume the scans surface roughly 300 findings in the first week, mostly medium and low severity dependency warnings accumulated over years. Blocking merges on all 300 would stall every team, so only the dozen critical and high findings block merges immediately, while the rest enter a backlog triaged over the following month. By week six the backlog is typically cleared and the weekly new-finding rate settles far lower, since most of the initial volume was historical debt rather than an ongoing rate. These figures are illustrative assumptions, not measured results.

Track a small number of metrics instead of a dashboard nobody reads: mean time to remediate by severity, the percentage of builds a security gate blocks, and the age of the oldest open critical finding. If that last number keeps growing, your severity SLAs exist on paper only.

Report these numbers in the same forum where engineering already reviews deployment frequency and incident metrics, not in a separate security-only meeting nobody outside the security team attends. A pipeline that produces findings nobody discusses is functionally identical to a pipeline that produces none.

What Does a DevSecOps Rollout Plan Look Like?

  1. Weeks 1 to 2: visibility only. Turn on secret scanning, SAST and SCA in report-only mode across every repository, without blocking anything yet. The goal is a true baseline, not a clean build.
  2. Weeks 3 to 4: fix the backlog. Triage existing findings with the severity model above, and clear every critical and high finding the baseline uncovered.
  3. Weeks 5 to 6: start blocking. Move critical and high severity SAST and SCA findings to block merges, and leave medium and low findings in report-only mode.
  4. Weeks 7 to 8: add IaC scanning and SBOM generation. Extend scanning to infrastructure code, and start generating and storing an SBOM on every build to main.
  5. Weeks 9 to 10: add signing and provenance. Introduce keyless artifact signing and start recording build provenance, even before you enforce verification anywhere.
  6. Weeks 11 to 12: add deploy-time policy and verification. Turn on admission control or a policy-as-code gate, and start rejecting unsigned artifacts in the lowest-risk environment first.
  7. Ongoing: expand runtime coverage and review metrics monthly. Add DAST and CSPM coverage, and review mean time to remediate, blocked-build rate and oldest open critical finding every month.

How Agentixly Approaches DevSecOps Pipelines

Agentixly builds DevSecOps pipelines as a joint effort between our cloud and DevOps engineering and cybersecurity teams, because a pipeline designed by only one side tends to either slow every merge to a crawl or wave security through unchecked. A typical engagement runs in three phases:

  1. Baseline audit. We map your current pipeline stage by stage against the model in this guide, flagging controls that are missing entirely versus present but not enforced.
  2. Phased rollout. We implement the rollout plan above against your actual repositories and cloud accounts, tuned to your stack, moving from report-only to enforcement on a timeline your team can absorb.
  3. Handover and metrics. Pipelines, policies and dashboards ship as code in your own repositories, with a documented severity model and the core metrics wired into a dashboard your team already uses.

Agentixly's engineers are veterans of Israel's elite technology units, including Unit 8200 and Unit 81, and that background shapes a pipeline design instinct toward how a system gets attacked, not just how it is supposed to work. If your pipeline needs to support a SOC 2 audit, our SOC 2 roadmap for startups maps directly onto the change management and vulnerability management evidence auditors expect.

The Bottom Line

A DevSecOps pipeline is not a single tool purchase; it is five stages, each with an owner, an automated check and a severity model that decides what blocks a merge and what becomes a ticket. Start in report-only mode, clear the historical backlog before you enforce anything, and let signing and policy gates follow once the basics hold.

If you want an outside review of your current pipeline or a team to build one from scratch, Agentixly's DevOps and cybersecurity teams can audit what you have and implement what is missing. Get in touch and tell us which stage of your pipeline worries you most.