Stasis

Security Scan

Comprehensive security scanning with Trivy, Snyk, and Gitleaks

Security Scanning

CI/CD pipeline for comprehensive security scanning with multiple tools.

Overview

This pipeline scans for:

  • Container vulnerabilities (Trivy)
  • Dependency vulnerabilities (Snyk)
  • Secret detection (Gitleaks)
  • SAST (Static Application Security Testing)
  • SBOM (Software Bill of Materials) generation

Use Case

  • Pre-deployment security checks
  • Compliance requirements
  • Vulnerability management
  • Supply chain security

Prerequisites

  • Docker images or source code
  • Snyk account and API token
  • Optional: Gitleaks license

Configuration

# runner.yaml
image:
  name: "aquasec/trivy"
  tag: "latest"
  pull_policy: "Always"

on:
  push:
    - "main"
    - "develop"
  schedule:
    - "0 2 * * 1"  # Weekly on Monday at 2am

global_env:
  TRIVY_NO_PROGRESS: "true"
  TRIVY_FORMAT: "json"

timeout: 1800  # 30 minutes

steps:
  setup:
    type: "pre"
    scripts:
      - trivy --version
      - apk add --no-cache curl git

  container_scan:
    type: "exec"
    scripts:
      - |
        echo "Scanning container image..."
        trivy image \
          --severity HIGH,CRITICAL \
          --format table \
          --output container-report.txt \
          ${IMAGE_NAME}:latest
      - |
        echo "Generating JSON report..."
        trivy image \
          --severity HIGH,CRITICAL \
          --format json \
          --output container-report.json \
          ${IMAGE_NAME}:latest
    envs:
      IMAGE_NAME: "${CI_REGISTRY_IMAGE}"
    continue_on_error: false
    artifacts:
      - "container-report.txt"
      - "container-report.json"

  filesystem_scan:
    type: "exec"
    scripts:
      - |
        echo "Scanning filesystem..."
        trivy fs \
          --severity HIGH,CRITICAL \
          --format table \
          --output fs-report.txt \
          .
    continue_on_error: false
    artifacts:
      - "fs-report.txt"
      - "fs-report.json"

  secret_scan:
    type: "exec"
    scripts:
      - |
        echo "Installing Gitleaks..."
        curl -sSfL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_8.18.1_linux_amd64.tar.gz | tar xz
        mv gitleaks /usr/local/bin/
      - |
        echo "Scanning for secrets..."
        gitleaks detect \
          --source . \
          --report-path secrets-report.json \
          --report-format json \
          --verbose || true
    continue_on_error: true
    artifacts:
      - "secrets-report.json"

  sbom_generation:
    type: "exec"
    scripts:
      - |
        echo "Generating SBOM..."
        trivy image \
          --format cyclonedx \
          --output sbom.cdx.json \
          ${IMAGE_NAME}:latest
      - |
        echo "Generating SPDX SBOM..."
        trivy image \
          --format spdx-json \
          --output sbom.spdx.json \
          ${IMAGE_NAME}:latest
    envs:
      IMAGE_NAME: "${CI_REGISTRY_IMAGE}"
    continue_on_error: true
    artifacts:
      - "sbom.cdx.json"
      - "sbom.spdx.json"

  snyk_test:
    type: "exec"
    scripts:
      - |
        echo "Installing Snyk..."
        curl -sSfL https://static.snyk.io/cli/latest/snyk-linux -o /usr/local/bin/snyk
        chmod +x /usr/local/bin/snyk
      - |
        echo "Running Snyk test..."
        snyk test \
          --severity-threshold=high \
          --json-file-output=snyk-report.json \
          --all-projects || true
    envs:
      SNYK_TOKEN: "${SNYK_TOKEN}"
    continue_on_error: true
    artifacts:
      - "snyk-report.json"

  aggregate_results:
    type: "post"
    scripts:
      - |
        echo "=== Security Scan Summary ==="
        echo ""
        echo "Container Scan:"
        grep -c "HIGH\|CRITICAL" container-report.txt || echo "0 vulnerabilities"
        echo ""
        echo "Filesystem Scan:"
        grep -c "HIGH\|CRITICAL" fs-report.txt || echo "0 vulnerabilities"
        echo ""
        echo "Secret Scan:"
        python3 -c "import json; print(len(json.load(open('secrets-report.json'))))" 2>/dev/null || echo "0 secrets found"
    when: "always"

Step-by-Step Explanation

Step 1: Container Scan

container_scan:
  type: "exec"
  scripts:
    - trivy image --severity HIGH,CRITICAL --format table --output container-report.txt ${IMAGE_NAME}:latest

What it does:

  • Scans container image for vulnerabilities
  • Focuses on HIGH and CRITICAL severity
  • Generates human-readable and JSON reports

Step 2: Filesystem Scan

filesystem_scan:
  type: "exec"
  scripts:
    - trivy fs --severity HIGH,CRITICAL --format table --output fs-report.txt .

What it does:

  • Scans source code and dependencies
  • Detects vulnerable packages

Step 3: Secret Scan

secret_scan:
  type: "exec"
  scripts:
    - gitleaks detect --source . --report-path secrets-report.json --verbose || true

What it does:

  • Detects hardcoded secrets
  • Scans git history
  • Identifies API keys, passwords, tokens

Step 4: SBOM Generation

sbom_generation:
  type: "exec"
  scripts:
    - trivy image --format cyclonedx --output sbom.cdx.json ${IMAGE_NAME}:latest
    - trivy image --format spdx-json --output sbom.spdx.json ${IMAGE_NAME}:latest

What it does:

  • Generates Software Bill of Materials
  • CycloneDX format (industry standard)
  • SPDX format (Linux Foundation)

Step 5: Snyk Test

snyk_test:
  type: "exec"
  scripts:
    - snyk test --severity-threshold=high --json-file-output=snyk-report.json --all-projects || true
  envs:
    SNYK_TOKEN: "${SNYK_TOKEN}"

What it does:

  • Runs Snyk vulnerability scan
  • Scans all projects
  • Requires Snyk API token

Environment Variables

VariableRequiredDescription
SNYK_TOKENFor SnykSnyk API token
CI_REGISTRY_IMAGEFor container scanContainer image name

Artifacts

FileDescription
container-report.txtContainer vulnerability report
container-report.jsonContainer vulnerability JSON
fs-report.txtFilesystem vulnerability report
secrets-report.jsonSecret detection report
sbom.cdx.jsonCycloneDX SBOM
sbom.spdx.jsonSPDX SBOM
snyk-report.jsonSnyk vulnerability report

Customization

Add vulnerability exceptions

Create .trivyignore:

# Ignore specific vulnerabilities
CVE-2023-12345
CVE-2023-67890

Add Docker Scout

docker_scout:
  type: "exec"
  scripts:
    - docker scout cves ${IMAGE_NAME}:latest --format json --output scout-report.json || true
  continue_on_error: true

Next Steps

On this page