This tutorial shows you how to build a complete DevSecOps pipeline that integrates security scanning at every stage.
Pipeline Architecture
Code โ SAST โ Build โ Image Scan โ Deploy to Staging โ DAST โ Deploy to ProductionEvery stage gates on security โ if vulnerabilities are found above your threshold, the pipeline stops.
Stage 1: Static Analysis (SAST)
Scan source code before building:
# GitHub Actions
- name: Run Semgrep SAST
uses: returntocorp/semgrep-action@v1
with:
config: p/owasp-top-ten p/security-audit
- name: Run Trivy filesystem scan
run: |
trivy fs --severity HIGH,CRITICAL --exit-code 1 .Stage 2: Dependency Scanning
- name: Check dependencies for vulnerabilities
run: |
trivy fs --scanners vuln --severity HIGH,CRITICAL .
- name: Check for secret leaks
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verifiedStage 3: Container Image Scanning
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan image
run: |
trivy image --severity HIGH,CRITICAL --exit-code 1 myapp:${{ github.sha }}Stage 4: Infrastructure as Code Scanning
- name: Scan Terraform
run: |
trivy config --severity HIGH,CRITICAL terraform/
- name: Scan Kubernetes manifests
run: |
trivy config --severity HIGH,CRITICAL k8s/Stage 5: Dynamic Analysis (DAST)
After deploying to staging, run DAST against the live application:
- name: OWASP ZAP Scan
uses: zaproxy/action-full-scan@v0.10.0
with:
target: "https://staging.example.com"
fail_action: "warn"Stage 6: Runtime Security
Once deployed, monitor for runtime threats:
# Falco runtime security
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: falco
namespace: security
# Detects: shell in container, sensitive file access,
# unexpected network connections, privilege escalationComplete GitHub Actions Pipeline
name: DevSecOps Pipeline
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: SAST - Semgrep
uses: returntocorp/semgrep-action@v1
- name: Secret scanning
run: trivy fs --scanners secret .
- name: Dependency scan
run: trivy fs --scanners vuln .
- name: Build image
run: docker build -t myapp:ci .
- name: Image scan
run: trivy image --exit-code 1 --severity CRITICAL myapp:ci
- name: IaC scan
run: trivy config k8s/Security Gates
Define your thresholds:
| Severity | Development | Staging | Production |
|---|---|---|---|
| Critical | Block | Block | Block |
| High | Warn | Block | Block |
| Medium | Info | Warn | Block |
| Low | Info | Info | Warn |
Tips and Tricks
- Start with
--exit-code 0(warn only) then gradually tighten to--exit-code 1(block) - Use
.trivyignorefor accepted risks with documented justification - Run SAST on every PR, full DAST on staging deploys only
- Generate SBOM (Software Bill of Materials) for every production image
- Sign images with Cosign for supply chain integrity