DevSecOps Pipeline Integration â SAST, DAST, Dependency Scanning, and Security Gates
In this tutorial, you'll learn about DevSecOps Pipeline Integration. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
DevSecOps integrates Security Testing directly into the CI/CD pipeline â shifting left by running Static Analysis, dynamic scanning, dependency checks, and container analysis at every commit instead of waiting for a separate security review.
What You'll Learn
Why It Matters
Traditional Security Testing happens at the end of development â a penetration test before release that finds dozens of issues requiring emergency fixes. DevSecOps embeds automated security checks into every pipeline run. Vulnerabilities are caught minutes after they are introduced, when they cost the least to fix. The pipeline itself enforces security gates that block releases failing critical checks.
Real-World Use
Durga Antivirus Pro's CI/CD pipeline runs six security stages on every Pull Request: SAST with Semgrep for custom rule violations, dependency scanning with npm audit and Trivy, container image scanning for OS vulnerabilities, infrastructure scanning for Terraform misconfigurations, DAST against the staging environment, and license Compliance checks â all enforced through quality gates that block merging on high-severity findings.
flowchart LR
A[Code Commit] --> B[SAST: Semgrep]
A --> C[Dep Scan: npm audit]
A --> D[IaC Scan: Checkov]
B --> E[Build & Test]
C --> E
D --> E
E --> F[Container Scan]
F --> G[DAST: OWASP ZAP]
G --> H{Security Gate}
H -->|Pass| I[Deploy]
H -->|Fail| J[Block & Notify]
style H fill:#ff9800,color:#fff
style J fill:#f44336,color:#fff
style I fill:#4CAF50,color:#fff
Prerequisites: CI/CD pipeline concepts, basic Docker knowledge, familiarity with OWASP vulnerability classifications.
SAST â Static Application Security Testing
SAST analyzes source code for security vulnerabilities without executing the application. It catches issues like SQL Injection, cross-site scripting, hardcoded credentials, and insecure cryptographic usage.
# .github/workflows/sast.yml
name: SAST Scan
on:
pull_request:
branches: [main]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/javascript
p/nodejs
p/security-audit
auditOn: push
publishDeployment: ${{ secrets.SEMGREP_APP_TOKEN }}
- name: Check for blocking findings
run: |
if grep -q '"severity": "ERROR"' semgrep-results.json; then
echo "Blocking security issues found!"
exit 1
fi
- name: Comment results on PR
uses: actions/github-script@v7
if: github.event_name == 'pull_request'
with:
script: |
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('semgrep-results.json'));
// Format and post findings as PR comment
Expected behavior: Semgrep scans every changed file in the Pull Request against curated rule sets (OWASP Top 10, language-specific, custom rules). If any ERROR-severity findings exist, the pipeline fails and results are posted as a PR comment.
# Run Semgrep locally
semgrep --config=auto --severity=ERROR .
# Expected output:
# Scanning 142 files with 234 rules.
# Found 3 findings:
# src/auth.js:12
# ⯠Severity: ERROR ⯠Rule: jwt-hardcoded-secret
# Hardcoded JWT secret detected. Use environment variables.
# src/db.js:45
# ⯠Severity: ERROR ⯠Rule: sql-injection
# User input concatenated into SQL query. Use parameterized queries.
# Ran 234 rules on 142 files: 3 findings.
DAST â Dynamic Application Security Testing
DAST tests the running application for vulnerabilities by sending malicious payloads and analyzing responses. It catches runtime issues SAST misses, such as misconfigured security headers and authentication bypasses.
# .github/workflows/dast.yml
name: DAST Scan
on:
deployment_status: # Runs when staging deployment completes
types: [success]
jobs:
zap-scan:
runs-on: ubuntu-latest
steps:
- name: Run OWASP ZAP Scan
uses: zaproxy/action-full-scan@v0.11.0
with:
target: ${{ github.event.deployment_status.target_url }}
rules_file_name: .zap/rules.tsv
cmd_options: '-a -j -J zap-report.json'
issue_title: "DAST Scan Results"
fail_action: true
- name: Upload scan report
uses: actions/upload-artifact@v4
with:
name: zap-report
path: zap-report.json
Expected behavior: After the staging environment deploys successfully, DAST runs against the live URL. OWASP ZAP spiders the application, fuzzes endpoints, and checks for vulnerabilities. High-risk findings fail the workflow, preventing the same build from reaching production.
# Run OWASP ZAP in daemon mode
docker run -d --name zap -p 8080:8080 \
-v $(pwd):/zap/wrk:rw \
ghcr.io/zaproxy/zaproxy:stable \
zap.sh -daemon -port 8080 -host 0.0.0.0
# Run an active scan
docker exec zap zap-cli active-scan \
--recursive https://staging.myapp.com
# Expected output:
# Active Scan started against https://staging.myapp.com
# Spidering: 45 URLs discovered
# Active Scan: 1200+ requests sent
# Alerts found:
# - Medium: Missing X-Frame-Options header
# - Medium: Cookie without SameSite attribute
# - Low: Server header disclosure
Dependency Scanning
Open-source dependencies are a primary attack vector. Dependency scanning checks every package against known vulnerability databases.
dep-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: npm audit
run: |
npm audit --audit-level=high --json > audit-results.json
if jq -e '.metadata.vulnerabilities.high > 0 or
.metadata.vulnerabilities.critical > 0' \
audit-results.json > /dev/null; then
echo "High or critical vulnerabilities found!"
jq '.vulnerabilities | to_entries[] |
{package: .key, severity: .value.severity,
title: .value.title, fix: .value.fixAvailable}' \
audit-results.json
exit 1
fi
- uses: actions/upload-artifact@v4
with:
name: npm-audit
path: audit-results.json
Expected behavior: npm audit checks the project's dependency tree against the npm Advisory database. If any package has a high or critical vulnerability, the pipeline fails and displays remediation advice.
# Scan with Trivy for OS-level dependencies
trivy filesystem --severity CRITICAL,HIGH .
# Expected output:
# Total: 5 (CRITICAL: 2, HIGH: 3)
# +------------------+---------------------+----------+-----------+
# | Library | Vulnerability | Severity | Installed |
# +------------------+---------------------+----------+-----------+
# | lodash | CVE-2024-XXXX | CRITICAL | 4.17.20 |
# | express | CVE-2024-YYYY | HIGH | 4.18.1 |
# | node-fetch | CVE-2024-ZZZZ | HIGH | 2.6.7 |
# +------------------+---------------------+----------+-----------+
IaC Security Scanning
Infrastructure as Code configurations introduce security risks â open security groups, unencrypted storage, and public buckets are common misconfigurations.
iac-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Checkov
id: checkov
uses: bridgecrewio/checkov-action@master
with:
directory: terraform/
framework: terraform
output_format: cli
soft_fail: false
download_external_modules: true
- name: Run tfsec
run: |
tfsec terraform/ --format sarif \
--output-file tfsec-results.sarif
Expected behavior: Checkov and tfsec scan Terraform, CloudFormation, and Kubernetes manifests for misconfigurations against the CIS and Cloud Security benchmarks. Open security groups, unencrypted S3 buckets, and overly permissive IAM roles all trigger failures.
# Checkov flags this as a FAIL
resource "aws_security_group" "public_ssh" {
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # FAIL: SSH open to world
}
}
Expected output:
# checkov report for terraform/
# Passed checks: 45, Failed checks: 3
#
# FAIL: CKV_AWS_24 "Ensure no security groups allow ingress from 0.0.0.0:0 to port 22"
# File: /terraform/security-groups.tf:4-10
#
# FAIL: CKV_AWS_23 "Ensure every security group rule has a description"
Security Gates
Security gates are quality thresholds that block the pipeline from proceeding when certain conditions are met.
# security-gate.sh
#!/bin/bash
set -e
HIGH_CRITICAL=$(jq '.runs[0].results |
map(select(.level == "error")) | length' sarif-results.json)
if [ "$HIGH_CRITICAL" -gt 0 ]; then
echo "BLOCKED: $HIGH_CRITICAL error-severity findings"
exit 1
fi
echo "PASSED: Security gate cleared"
Expected behavior: The security gate script runs after all scans complete. If any ERROR-level findings exist, the script exits with code 1, causing the pipeline to fail. Only when all scans pass the gate does the pipeline proceed to deployment.
Container and Secret Scanning
container-scan:
needs: build
steps:
- name: Scan Docker image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: CRITICAL,HIGH
exit-code: 1
secret-scan:
steps:
- name: Scan for secrets
uses: trufflesecurity/trufflehog@v3
with:
extra_args: --only-verified
Expected behavior: Container scanning blocks images with CRITICAL OS vulnerabilities. Secret scanning prevents API keys, tokens, and passwords from being committed.
Common Errors
Running SAST only on main branch: Vulnerabilities found on main are already in the codebase. Run SAST on every Pull Request to catch issues before they merge.
Not tuning scanner rules: Default rule sets produce many false positives. Teams ignore the results entirely. Invest time in customizing rules and suppressing known false positives.
Skipping DAST because it is slow: DAST takes 20-60 minutes but catches runtime vulnerabilities no other scan finds. Run it as part of the staging deploy workflow rather than on every commit.
Failing the build on every finding: Blocking the pipeline on LOW or INFO findings creates resentment against security. Gate only on HIGH and CRITICAL, and track lower-severity issues separately.
Not scanning IaC configurations: Misconfigured infrastructure is one of the most common breach vectors. Terraform and Kubernetes manifests must be scanned alongside application code.
Scanning dependencies without fixing them: Generating a list of vulnerabilities is useless without automated remediation. Configure Dependabot or Renovate to open fix PRs automatically.
Practice Questions
What is the difference between SAST and DAST? Answer: SAST analyzes source code statically without running the application. DAST tests the running application by sending payloads and observing responses. SAST finds issues early; DAST finds runtime misconfigurations.
Why should security gates be based only on HIGH and CRITICAL findings? Answer: Blocking on LOW and INFO findings creates too many pipeline failures, leading teams to ignore or disable security gates entirely. Focus on the most impactful vulnerabilities.
How does dependency scanning work in a DevSecOps pipeline? Answer: The scanner compares every installed package version against vulnerability databases (npm Advisory, NVD, GitHub Advisory). If any version has a known CVE at or above the severity threshold, the pipeline blocks.
Why should IaC scanning be included in the DevSecOps pipeline? Answer: IaC misconfigurations (open security groups, unencrypted storage, public S3 buckets) are common breach vectors. Automated IaC scanning catches these before they are deployed.
Challenge
Build a complete DevSecOps pipeline that runs SAST (Semgrep) on every Pull Request, dependency scanning (npm audit), IaC scanning (Checkov on Terraform), container scanning (Trivy), and a DAST scan (OWASP ZAP) after staging deployment. Implement a security gate that blocks the pipeline on HIGH and CRITICAL findings while posting WARNINGS as PR comments.
Mini Project
Create a GitHub Actions workflow with four security jobs: SAST using Semgrep with OWASP Top 10 rules, dependency scanning using npm audit, container scanning using Trivy with exit-code 1 on CRITICAL or HIGH, and IaC scanning using Checkov on a Terraform directory. Add a security gate job that aggregates results from all scanners and blocks deployment if any HIGH or CRITICAL findings exist. Configure Dependabot to auto-open PRs for vulnerable dependencies. Use a real-world web application repository to test the pipeline end-to-end.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro