Skip to content

Pipeline Security

A secure pipeline finds vulnerabilities before they reach production. This page covers each security stage, when to run it, and what to do with the results.

commit → SAST → Secret Detection → Dependency Scan
→ build image → Container Scan
→ deploy to staging → DAST
→ merge gate: block on Critical findings

SAST scans source code without running it. GitLab includes built-in SAST templates:

include:
- template: Security/SAST.gitlab-ci.yml
variables:
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"

GitLab’s SAST auto-detects the language and picks the right analyser (Semgrep for most languages, Gosec for Go, Bandit for Python).

What it catches: SQL injection, XSS, hardcoded credentials, insecure deserialization, path traversal.

Never let credentials reach Git history:

include:
- template: Security/Secret-Detection.gitlab-ci.yml

GitLab’s secret detection uses Gitleaks under the hood — it scans the full diff on every commit and the entire history on the first run.

Common findings: AWS keys, private SSH keys, JWT secrets, API tokens, .env fragments accidentally committed.

Scan third-party libraries against the NVD and OSV databases:

include:
- template: Security/Dependency-Scanning.gitlab-ci.yml

For Node.js projects, also consider running npm audit --audit-level=high as a separate job to catch issues faster.

Scan your built image layer by layer with Trivy:

container_scan:
stage: scan
image:
name: aquasec/trivy:latest
entrypoint: ['']
script:
- trivy image --exit-code 1 --severity CRITICAL $IMAGE_TAG
needs: [build:image]

--exit-code 1 fails the job (and blocks the merge) if any Critical CVE is found.

DAST runs against the deployed application. GitLab wraps OWASP ZAP:

include:
- template: Security/DAST.gitlab-ci.yml
variables:
DAST_WEBSITE: https://staging.almamy.net
DAST_FULL_SCAN_ENABLED: "false" # passive scan on MR, full scan on main

DAST is slow (~5–15 min). Run it only against main or nightly, not on every MR.

Use the GitLab Security Approvals feature to block merges when Critical or High findings appear:

  1. Project → Settings → Merge requests → Security approvals
  2. Require 1 approval from the Security team when scanner reports Critical findings.

All security jobs should emit SAST/dependency/DAST report artefacts so GitLab aggregates them in the MR Security tab:

container_scan:
artifacts:
reports:
container_scanning: gl-container-scanning-report.json

Sign every image with Cosign so Kubernetes admission can verify provenance:

Terminal window
cosign sign --key cosign.key $IMAGE_TAG

Then enforce signature verification in your Kubernetes cluster with Kyverno or OPA Gatekeeper.