# Designing a Secure Pipeline — DevSecOps

Source: https://www.skillbyai.com/en/devsecops/dso-pipeline-design

> Lay out where each security check belongs in a CI/CD pipeline and decide which findings block a merge or a release.

## Checks, gates and their placement

A secure pipeline places each check where it gives the fastest useful feedback. On the **pull request**: secret scanning, SAST on changed code, dependency scanning, IaC scanning and unit tests including security tests. These must be quick and their results shown inline in the review. On **build**: produce the artefact once, scan the image, generate the SBOM, sign the artefact and record provenance. Before **deploy**: verify signatures, enforce policies (no critical vulnerabilities with a fix available, no containers running as root) and run DAST against a staging environment. In **production**: runtime monitoring and periodic re-scans, because new CVEs appear for images that were clean yesterday. A **gate** is a check that blocks progress. Gates should be few and precise, with a documented exception process; most other findings become tickets with a deadline rather than blockers.

## A pipeline with security gates

Each stage adds its own checks: the pull request runs fast scanners, the build produces a scanned and signed artefact, staging runs dynamic tests, and the release gate verifies everything before production.

![Four connected stages: pull request checks, build and sign, staging tests, release gate.](assets/figures/devsecops/section-6-map.svg) — Figure 6.1: pull request checks -> build and sign -> staging tests -> release gate.

## A pull-request security workflow

Jobs run in parallel so the review gets results quickly. Each tool fails its job on serious findings.

```yaml
name: pr-security
on: pull_request
permissions:
  contents: read
jobs:
  secrets:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}  # required for organisation-owned repos
  sast:
    runs-on: ubuntu-latest
    container: semgrep/semgrep
    steps:
      - uses: actions/checkout@v4
      - run: semgrep scan --config p/default --error
  deps:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm audit --audit-level=high
```

## Build once, promote the same artefact

Rebuilding for each environment means production runs something that was never tested or scanned. Build one image, refer to it by **digest**, and promote that exact digest from staging to production.

**Quiz:** Which check is best suited to run before deploy against a running staging environment rather than on the pull request?

- [x] DAST
- [ ] Secret scanning
- [ ] Linting
- [ ] Unit tests

*Answer:* DAST. DAST needs a running application to send requests to, so it fits after deployment to a test or staging environment.
