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.
The security pipeline
Section titled “The security pipeline”commit → SAST → Secret Detection → Dependency Scan → build image → Container Scan → deploy to staging → DAST → merge gate: block on Critical findingsSAST — Static Analysis
Section titled “SAST — Static Analysis”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.
Secret Detection
Section titled “Secret Detection”Never let credentials reach Git history:
include: - template: Security/Secret-Detection.gitlab-ci.ymlGitLab’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.
Dependency Scanning
Section titled “Dependency Scanning”Scan third-party libraries against the NVD and OSV databases:
include: - template: Security/Dependency-Scanning.gitlab-ci.ymlFor Node.js projects, also consider running npm audit --audit-level=high as a separate job to catch issues faster.
Container Image Scanning
Section titled “Container Image Scanning”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 — Dynamic Analysis
Section titled “DAST — Dynamic Analysis”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 mainDAST is slow (~5–15 min). Run it only against main or nightly, not on every MR.
Merge gate — blocking on findings
Section titled “Merge gate — blocking on findings”Use the GitLab Security Approvals feature to block merges when Critical or High findings appear:
- Project → Settings → Merge requests → Security approvals
- Require 1 approval from the Security team when scanner reports Critical findings.
Artefacts and reports
Section titled “Artefacts and reports”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.jsonSupply chain: sign your images
Section titled “Supply chain: sign your images”Sign every image with Cosign so Kubernetes admission can verify provenance:
cosign sign --key cosign.key $IMAGE_TAGThen enforce signature verification in your Kubernetes cluster with Kyverno or OPA Gatekeeper.