Skip to content

Trivy — Vulnerability Scanning

Trivy is used in three distinct scan modes across the DevSecOps pipeline: dependency scanning, Infrastructure-as-Code scanning, and container image scanning. Together they cover the full supply chain from source packages to deployed containers.


Three Scan Modes

Pipeline Flow
─────────────────────────────────────────────────────
Stage 4: trivy fs    → Scans dependency lockfiles
Stage 5: trivy config → Scans Bicep + YAML (IaC)
Stage 9: trivy image  → Scans built container image
─────────────────────────────────────────────────────

Severity Levels

Trivy uses a five-level severity model derived from CVSS scores and vendor advisories:

SeverityCVSS RangeColorPipeline Action
CRITICAL9.0 – 10.0RedBlocks (all modes)
HIGH7.0 – 8.9OrangeBlocks (IaC only)
MEDIUM4.0 – 6.9YellowReported, no block
LOW0.1 – 3.9BlueReported, no block
UNKNOWNGreyReported, no block

Thresholds are configurable in DevSecOps/config/thresholds.yml.


Mode 1: Dependency Scanning (trivy fs)

Scans dependency manifest files and lockfiles without downloading packages. Supported ecosystems:

EcosystemFiles Scanned
.NET / NuGet*.csproj, packages.lock.json
Node.jspackage.json, package-lock.json, yarn.lock
Flutter / Dartpubspec.yaml, pubspec.lock
Pythonrequirements.txt, Pipfile.lock, poetry.lock
yaml
# Stage 4 pipeline task
- task: Bash@3
  displayName: 'Stage 4 - Trivy Dependency Scan'
  inputs:
    script: |
      trivy fs \
        --scanners vuln \
        --severity CRITICAL \
        --exit-code 1 \
        --format table \
        --ignorefile $(Build.SourcesDirectory)/.trivyignore \
        $(Build.SourcesDirectory)

Trivy Config File (.trivy.yaml)

yaml
# .trivy.yaml — place in repository root
vulnerability:
  type:
    - os
    - library
  ignore-unfixed: false
  severity:
    - CRITICAL
    - HIGH
    - MEDIUM

cache:
  dir: /tmp/trivy-cache

db:
  no-progress: true

format: table

Mode 2: IaC Scanning (trivy config)

Scans Infrastructure-as-Code files for misconfigurations. Applied to all files under Devops/azure/infrastructure/:

File TypeWhat Is Checked
BicepOpen inbound rules, missing diagnostics, unencrypted storage, public blob access
ARM JSONSame as Bicep (converted)
Kubernetes YAMLPrivileged containers, missing resource limits, hostPath volumes
Docker ComposePrivileged mode, bind mounts on sensitive paths
yaml
# Stage 5 pipeline task
- task: Bash@3
  displayName: 'Stage 5 - Trivy IaC Scan'
  inputs:
    script: |
      trivy config \
        --severity HIGH,CRITICAL \
        --exit-code 1 \
        --format table \
        --tf-exclude-downloaded-modules \
        --ignorefile $(Build.SourcesDirectory)/.trivyignore \
        $(Build.SourcesDirectory)/Devops/azure/infrastructure

Common IaC Findings and Remediation

FindingRule IDRemediation
Storage blob public accessAVD-AZU-0008Set allowBlobPublicAccess: false
Key Vault no purge protectionAVD-AZU-0016Set enablePurgeProtection: true
CAE no managed identityAVD-AZU-0130Assign user-assigned managed identity
SQL no TDEAVD-AZU-0028Enable Transparent Data Encryption
Redis no SSLAVD-AZU-0023Set enableNonSslPort: false

Mode 3: Container Image Scanning (trivy image)

Scans the freshly built Docker image after Stage 8 (Docker Build) and before pushing to ACR:

yaml
# Stage 9 pipeline task
- task: Bash@3
  displayName: 'Stage 9 - Trivy Image Scan'
  inputs:
    script: |
      trivy image \
        --severity CRITICAL \
        --exit-code 1 \
        --ignore-unfixed \
        --format sarif \
        --output $(Build.ArtifactStagingDirectory)/trivy-image.sarif \
        --ignorefile $(Build.SourcesDirectory)/.trivyignore \
        $(acrName).azurecr.io/$(imageName):$(Build.BuildId)

The --ignore-unfixed flag skips CVEs that have no upstream fix available — these are tracked but not blocking.

SARIF Output

The SARIF report is uploaded to Azure DevOps Security tab for inline display:

yaml
- task: PublishBuildArtifacts@1
  condition: always()
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)/trivy-image.sarif'
    artifactName: 'security-trivy'

.trivyignore — Accepted False Positives

The .trivyignore file lists CVE IDs that the security team has reviewed and accepted as false positives or non-exploitable in the Microtec context.

# .trivyignore
#
# Format: one CVE ID per line
# Each entry must have a comment above it with:
#   - Date accepted
#   - Reviewer name
#   - Justification
#   - Expiry date (must be re-reviewed before this date)
#
# ─────────────────────────────────────────────────────────
# Accepted: 2025-03-01 | Reviewer: M.Araby
# Justification: CVE affects Node.js CLI tooling only,
#   not the Angular runtime bundle served to browsers.
# Expires: 2025-09-01 (re-review required)
CVE-2024-12345

# Accepted: 2025-04-10 | Reviewer: M.Araby
# Justification: CRITICAL in OpenSSL, but the affected function
#   (X.509 certificate parsing) is not called by this service.
# Expires: 2025-10-01
CVE-2024-67890

Policy: .trivyignore entries older than their expiry date will cause the pipeline to fail with a "stale ignore" error. Entries must be re-reviewed periodically.


SBOM Integration (Stage 10)

After Stage 9 image scan, Syft generates an SBOM from the same image. Trivy can also consume SBOMs for offline analysis:

bash
# Generate SBOM with Syft
syft $(imageName):$(tag) -o cyclonedx-json > sbom.cyclonedx.json

# Scan SBOM with Trivy (CI-independent, offline)
trivy sbom sbom.cyclonedx.json --severity CRITICAL,HIGH

Threshold Configuration Reference

From DevSecOps/config/thresholds.yml:

yaml
trivy:
  deps:
    severity: CRITICAL        # Block threshold for dependency scan
    ignore_unfixed: false     # Include unfixed vulnerabilities

  iac:
    severity: HIGH            # Block threshold for IaC scan (HIGH+CRITICAL)
    misconfig_scanners:
      - azure
      - dockerfile

  image:
    severity: CRITICAL        # Block threshold for image scan
    ignore_unfixed: true      # Skip CVEs with no available fix

Running Trivy Locally

Developers can run Trivy locally to check their changes before pushing:

bash
# Install (macOS)
brew install aquasecurity/trivy/trivy

# Scan local directory for dependency vulns
trivy fs --severity CRITICAL,HIGH --scanners vuln .

# Scan IaC files
trivy config --severity HIGH,CRITICAL Devops/azure/infrastructure/

# Scan a local image
trivy image --severity CRITICAL myimage:latest

# Update vulnerability database
trivy image --download-db-only

Internal Documentation — Microtec Platform Team