Wednesday, 22 October 2025

Building a CI/CD Security Pipeline with SAST, DAST, and Trivy in GitLab | 2025 Guide

Building a CI/CD Security Pipeline with SAST, DAST, and Trivy in GitLab

Complete CI/CD security pipeline in GitLab with SAST, DAST, and Trivy vulnerability scanning - DevSecOps implementation guide 2025

In 2025, DevSecOps isn't just a buzzword—it's a necessity. With cyber threats evolving at an unprecedented rate, integrating security directly into your CI/CD pipeline is no longer optional. This comprehensive guide will walk you through building a robust security pipeline using GitLab's native SAST capabilities, dynamic application security testing, and Trivy for vulnerability scanning. By the end, you'll have a production-ready pipeline that catches security issues before they reach production.

🚀 Why CI/CD Security Matters in 2025

The landscape of application security has dramatically shifted. Traditional security reviews at the end of development cycles are no longer sufficient. Here's why integrated security pipelines are essential:

  • Shift-Left Security: Catch vulnerabilities early when they're cheaper and easier to fix
  • Compliance Requirements: Meet evolving regulatory standards automatically
  • Supply Chain Security: Protect against dependency vulnerabilities
  • Zero-Trust Development: Assume every commit could introduce security risks

🔧 Understanding the Security Toolchain

Let's break down the core components of our security pipeline:

SAST (Static Application Security Testing)

SAST analyzes source code for potential vulnerabilities without executing the program. GitLab provides built-in SAST scanning that detects issues like SQL injection, XSS, and insecure authentication mechanisms.

DAST (Dynamic Application Security Testing)

DAST tests running applications from the outside, simulating real-world attacks. It identifies runtime vulnerabilities that SAST might miss.

Trivy Vulnerability Scanning

Trivy scans container images, file systems, and Git repositories for known vulnerabilities in dependencies and system packages.

💻 Complete GitLab CI/CD Pipeline Configuration


# .gitlab-ci.yml - Complete Security Pipeline
stages:
  - test
  - security-sast
  - security-dast
  - container-scan
  - dependency-scan
  - deploy-staging
  - security-dast-staging
  - deploy-production

variables:
  SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
  TRIVY_TIMEOUT: "10m"

# SAST Scanning
sast:
  stage: security-sast
  image: 
    name: "registry.gitlab.com/gitlab-org/security-products/sast:latest"
    entrypoint: [""]
  variables:
    SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
  artifacts:
    reports:
      sast: gl-sast-report.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# DAST Scanning
dast:
  stage: security-dast
  image: 
    name: "registry.gitlab.com/gitlab-org/security-products/dast:latest"
    entrypoint: [""]
  variables:
    DAST_WEBSITE: "https://your-app-staging.example.com"
    DAST_AUTH_URL: "https://your-app-staging.example.com/login"
  artifacts:
    reports:
      dast: gl-dast-report.json
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Trivy Container Scanning
container_scanning:
  stage: container-scan
  image: 
    name: "aquasec/trivy:0.50.1"
    entrypoint: [""]
  variables:
    TRIVY_USERNAME: "$CI_REGISTRY_USER"
    TRIVY_PASSWORD: "$CI_REGISTRY_PASSWORD"
  script:
    - trivy image --exit-code 0 --format template --template "@/contrib/gitlab.tpl" --output "gl-container-scanning-report.json" $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - trivy image --exit-code 1 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  artifacts:
    reports:
      container_scanning: gl-container-scanning-report.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Dependency Scanning
dependency_scanning:
  stage: dependency-scan
  image: 
    name: "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:latest"
    entrypoint: [""]
  artifacts:
    reports:
      dependency_scanning: gl-dependency-scanning-report.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Custom Trivy Advanced Scanning
trivy_advanced:
  stage: container-scan
  image: 
    name: "aquasec/trivy:0.50.1"
    entrypoint: [""]
  script:
    - |
      trivy config . --exit-code 0 --severity MEDIUM,HIGH,CRITICAL
      trivy filesystem . --exit-code 0 --severity HIGH,CRITICAL --skip-dirs node_modules
      trivy repo https://github.com/your-org/your-repo --exit-code 1 --severity CRITICAL
  rules:
    - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master"

  

⚡ Advanced Security Pipeline Configuration

For enterprise environments, consider these advanced configurations:

Custom SAST Rules

Create custom SAST rules to match your organization's security requirements:


# .gitlab-ci.yml - Custom SAST Configuration
include:
  - template: Security/SAST.gitlab-ci.yml

sast:
  variables:
    SAST_BANDIT_EXCLUDED_PATHS: "*/tests/*,*/test/*"
    SAST_BRAKEMAN_LEVEL: "1"
    SAST_FLAWFINDER_LEVEL: "3"
    SECURE_LOG_LEVEL: "debug"
  before_script:
    - echo "Starting SAST analysis for $CI_PROJECT_PATH"
  after_script:
    - |
      if [ -f "gl-sast-report.json" ]; then
        echo "SAST analysis completed. Report generated."
      fi

  

Automated Security Gates

Implement security gates to prevent vulnerable code from merging:


# Security Approval Gates
security_approval:
  stage: .pre
  image: alpine:latest
  script:
    - |
      # Check for critical vulnerabilities
      if [ -f "gl-container-scanning-report.json" ]; then
        CRITICAL_COUNT=$(jq '[.vulnerabilities[] | select(.severity == "Critical")] | length' gl-container-scanning-report.json)
        if [ "$CRITICAL_COUNT" -gt 0 ]; then
          echo "❌ Critical vulnerabilities found. Blocking merge."
          exit 1
        fi
      fi
      
      # Check SAST high severity issues
      if [ -f "gl-sast-report.json" ]; then
        HIGH_ISSUES=$(jq '.vulnerabilities | map(select(.severity == "High")) | length' gl-sast-report.json)
        if [ "$HIGH_ISSUES" -gt 3 ]; then
          echo "❌ Too many high severity issues found."
          exit 1
        fi
      fi
      echo "✅ Security checks passed"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

  

🔍 Integrating Trivy for Comprehensive Scanning

Trivy provides extensive vulnerability scanning capabilities. Here's how to leverage its full potential:

  • Container Image Scanning: Scan Docker images for OS package vulnerabilities
  • Filesystem Scanning: Check local directories for security issues
  • Git Repository Scanning: Scan remote repositories for secrets and vulnerabilities
  • Kubernetes Scanning: Integrate with your Kubernetes clusters

#!/bin/bash
# Advanced Trivy Scanning Script

# Scan container image with multiple output formats
trivy image --format json --output trivy-report.json your-image:latest

# Scan filesystem excluding specific directories
trivy filesystem --skip-dirs node_modules,vendor --severity HIGH,CRITICAL .

# Scan for misconfigurations in Kubernetes manifests
trivy k8s --report summary cluster

# Scan for exposed secrets in Git history
trivy repo --format table https://github.com/your-org/your-repo

# Generate SBOM (Software Bill of Materials)
trivy image --format cyclonedx your-image:latest

# Continuous monitoring with exit codes
trivy image --exit-code 1 --severity CRITICAL your-image:latest
if [ $? -eq 1 ]; then
    echo "Critical vulnerabilities found! Failing pipeline."
    exit 1
fi

  

🎯 Best Practices for Security Pipeline Implementation

  1. Start Small, Scale Gradually: Begin with basic SAST and gradually add DAST, container scanning, and dependency scanning
  2. Customize Severity Thresholds: Adjust severity levels based on your risk tolerance
  3. Implement Security Gates: Use pipeline conditions to block deployments when critical issues are found
  4. Regularly Update Scanning Tools: Keep your security scanners updated to detect the latest vulnerabilities
  5. Educate Development Teams: Provide clear remediation guidance for identified vulnerabilities

📊 Monitoring and Reporting

Effective security pipelines include comprehensive monitoring and reporting:

  • GitLab Security Dashboard: Centralized view of all security findings
  • Custom Metrics: Track vulnerability trends over time
  • Integration with External Tools: Connect with JIRA, Slack, or email notifications
  • Compliance Reporting: Generate reports for regulatory requirements

❓ Frequently Asked Questions

What's the difference between SAST and DAST?
SAST (Static Application Security Testing) analyzes source code for vulnerabilities without executing it, while DAST (Dynamic Application Security Testing) tests running applications from the outside. SAST finds coding issues early, DAST finds runtime vulnerabilities.
How does Trivy compare to other vulnerability scanners?
Trivy is known for its speed, simplicity, and comprehensive coverage. It scans containers, file systems, Git repositories, and Kubernetes configurations with a single tool, making it ideal for CI/CD pipelines compared to more specialized scanners.
Can I customize security thresholds for different environments?
Yes, you can configure different severity thresholds for development, staging, and production environments. For example, you might allow medium-severity issues in development but block deployment to production for any high or critical issues.
How do I handle false positives in security scanning?
Implement a process for triaging findings, use tool-specific configuration to exclude known false positives, and gradually tune your rulesets. GitLab allows you to dismiss specific findings and create custom rules.
What's the performance impact of adding security scanning to CI/CD?
Modern security tools are optimized for CI/CD environments. Use parallel execution, caching, and selective scanning (only changed files) to minimize impact. Most pipelines see less than 10% increase in total runtime with proper optimization.

💬 Found this article helpful? Have questions about implementing security in your CI/CD pipeline? Please leave a comment below or share it with your network to help others learn about DevSecOps best practices!

About LK-TECH Academy — Practical tutorials & explainers on software engineering, AI, and infrastructure. Follow for concise, hands-on guides.

No comments:

Post a Comment