Integrate software composition analysis checks into pipelines
Integrating Software Composition Analysis into CI/CD pipelines enables automated, continuous dependency security and compliance checking throughout the software development lifecycle. Rather than performing security assessments once before release, pipeline-integrated SCA continuously validates dependencies with every code change, catching vulnerabilities early when they're easiest and least expensive to fix.
Why integrate SCA into pipelines?
Traditional security approaches created dangerous patterns where security teams discovered vulnerabilities late in development when pressure to release was highest. This pattern resulted in either shipping vulnerable software or expensive last-minute remediation efforts delaying releases.
Shift-left security benefits
Early vulnerability detection:
- Immediate feedback: Developers receive vulnerability notifications within minutes of introducing vulnerable dependencies.
- Lower remediation costs: Fixing vulnerabilities during development costs significantly less than fixing them in production.
- Context preservation: Developers have full context about dependency choices when vulnerabilities are discovered immediately.
- Incremental fixes: Small, continuous security improvements are easier to implement than large remediation efforts.
Continuous compliance:
- Policy enforcement: Automated pipeline checks enforce license and security policies on every commit.
- Audit trails: Pipeline scan results provide compliance evidence and audit trails.
- Consistent standards: All code changes undergo the same security review regardless of who submits them.
- Risk prevention: Blocking vulnerable dependencies before merge prevents security debt accumulation.
Development velocity:
- Automated reviews: SCA tools perform dependency analysis automatically without requiring manual security team reviews.
- Parallel processing: Security scans run in parallel with other build steps, minimizing impact on build times.
- Faster releases: Continuous security validation throughout development enables faster, more confident releases.
- Reduced rework: Catching issues early eliminates expensive rework during release preparation.
Pipeline integration points
Effective SCA implementation includes multiple integration points throughout the CI/CD pipeline.
Pull request validation
Pre-merge security checks: Pull request validation catches vulnerable dependencies before they're merged into main branches, preventing security debt accumulation.
Azure Pipelines pull request validation:
trigger: none
pr:
branches:
include:
- main
- develop
pool:
vmImage: "ubuntu-latest"
steps:
- task: UseNode@1
inputs:
version: "18.x"
displayName: "Install Node.js"
- script: npm ci
displayName: "Install dependencies"
- task: WhiteSource@21
inputs:
cwd: "$(System.DefaultWorkingDirectory)"
projectName: "$(Build.Repository.Name)"
displayName: "Run Mend SCA scan"
- task: PublishTestResults@2
inputs:
testResultsFormat: "JUnit"
testResultsFiles: "**/test-results.xml"
displayName: "Publish scan results"
GitHub Actions pull request validation:
name: Security Scan
on:
pull_request:
branches: [main, develop]
jobs:
sca-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
- name: Install dependencies
run: npm ci
- name: Run Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
- name: Upload scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: snyk.sarif
Pull request checks:
- Dependency changes: Detect which dependencies changed in the pull request.
- New vulnerabilities: Identify new vulnerabilities introduced by dependency changes.
- License violations: Flag license policy violations before merge.
- Quality gates: Block pull requests that violate security or compliance policies.
- Review comments: Post scan findings as pull request comments for reviewer visibility.
Continuous integration builds
Build-time SCA scanning: Every CI build should include SCA scanning to validate dependencies in the complete application context.
Azure Pipelines CI integration:
trigger:
branches:
include:
- main
- develop
- feature/*
pool:
vmImage: "ubuntu-latest"
variables:
buildConfiguration: "Release"
steps:
- task: UseDotNet@2
inputs:
packageType: "sdk"
version: "7.x"
displayName: "Install .NET SDK"
- task: DotNetCoreCLI@2
inputs:
command: "restore"
projects: "**/*.csproj"
displayName: "Restore NuGet packages"
- task: WhiteSource@21
inputs:
cwd: "$(System.DefaultWorkingDirectory)"
projectName: "$(Build.Repository.Name)"
scanComment: "CI Build $(Build.BuildNumber)"
checkPolicies: true
failBuildOnPolicyViolation: true
displayName: "Mend SCA scan with policy enforcement"
- task: DotNetCoreCLI@2
inputs:
command: "build"
projects: "**/*.csproj"
arguments: "--configuration $(buildConfiguration)"
displayName: "Build application"
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: "$(Build.ArtifactStagingDirectory)"
artifactName: "drop"
displayName: "Publish build artifacts"
GitHub Actions CI integration:
name: CI Build
on:
push:
branches: [main, develop]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run OWASP Dependency-Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: "my-application"
path: "."
format: "SARIF"
args: >
--failOnCVSS 7
--suppression suppression.xml
- name: Upload scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: dependency-check-report.sarif
- name: Build application
run: python setup.py build
- name: Generate SBOM
run: |
pip install cyclonedx-bom
cyclonedx-py -i requirements.txt -o sbom.json
- name: Upload SBOM artifact
uses: actions/upload-artifact@v3
with:
name: sbom
path: sbom.json
CI build features:
- Full dependency scanning: Scan all dependencies including transitive dependencies.
- Policy enforcement: Fail builds that violate security or compliance policies.
- SBOM generation: Create software bill of materials artifacts for downstream consumption.
- Baseline comparison: Compare current scan results against previous builds to detect regressions.
- Metrics collection: Track vulnerability counts, remediation rates, and compliance scores over time.
Scheduled deep scans
Comprehensive periodic analysis: Scheduled scans provide thorough analysis without blocking developer workflow.
Azure Pipelines scheduled scan:
schedules:
- cron: "0 2 * * *"
displayName: "Nightly security scan"
branches:
include:
- main
always: true
trigger: none
pr: none
pool:
vmImage: "ubuntu-latest"
steps:
- task: NodeTool@0
inputs:
versionSpec: "18.x"
displayName: "Install Node.js"
- script: npm ci
displayName: "Install dependencies"
- task: Snyk@1
inputs:
serviceConnectionEndpoint: "SnykConnection"
testType: "app"
severityThreshold: "low"
monitorOnBuild: true
failOnIssues: false
projectName: "$(Build.Repository.Name)"
displayName: "Deep Snyk scan (all severities)"
- task: BlackDuck@1
inputs:
BlackDuckService: "BlackDuckConnection"
ScanMode: "intelligent"
DetectArguments: "--detect.policy.check.fail.on.severities ALL"
displayName: "Black Duck comprehensive scan"
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: "$(Build.ArtifactStagingDirectory)/SecurityReports"
artifactName: "SecurityReports"
displayName: "Publish detailed scan reports"
Scheduled scan advantages:
- Thorough analysis: Deep scanning with all severity levels without blocking development.
- New vulnerability detection: Detect newly disclosed vulnerabilities in unchanged dependencies.
- Comprehensive reporting: Generate detailed reports for security teams and management.
- Trend analysis: Track security posture changes over time through consistent scanning.
Release pipeline validation
Pre-deployment security gates: Release pipelines should validate artifacts before deploying to production environments.
Azure Pipelines release gate:
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- task: DotNetCoreCLI@2
inputs:
command: "build"
- stage: SecurityValidation
dependsOn: Build
jobs:
- job: SCAValidation
steps:
- task: DownloadBuildArtifacts@0
inputs:
artifactName: "drop"
- task: WhiteSource@21
inputs:
cwd: "$(System.ArtifactsDirectory)/drop"
projectName: "$(Build.Repository.Name)"
checkPolicies: true
failBuildOnPolicyViolation: true
displayName: "Validate artifact dependencies"
- stage: DeployProduction
dependsOn: SecurityValidation
condition: succeeded()
jobs:
- deployment: DeployToProduction
environment: "production"
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
inputs:
azureSubscription: "AzureConnection"
appName: "my-web-app"
package: "$(Pipeline.Workspace)/drop"
Release validation checks:
- Artifact scanning: Scan compiled artifacts and container images before deployment.
- Production-specific policies: Apply stricter security policies for production deployments.
- Compliance verification: Verify license compliance before production release.
- Approval gates: Require manual approval for deployments with known but accepted risks.
Quality gates and policy enforcement
Defining security policies: SCA tools enforce policies that define acceptable security and compliance standards.
Severity-based policies
Block builds based on vulnerability severity:
Example Mend policy:
{
"name": "Production Security Policy",
"enabled": true,
"rules": [
{
"type": "VULNERABILITY_SEVERITY",
"action": "FAIL_BUILD",
"minSeverity": "HIGH"
},
{
"type": "VULNERABILITY_AGE",
"action": "FAIL_BUILD",
"maxAge": 30,
"minSeverity": "MEDIUM"
}
]
}
This policy fails builds containing high or critical vulnerabilities, and medium vulnerabilities older than 30 days.
Example Snyk policy:
# .snyk policy file
version: v1.0.0
patch: {}
ignore: {}
policies:
- severity:
low: ignore
medium: warn
high: fail
critical: fail
License-based policies
Enforce license compliance:
Example license policy:
{
"name": "License Compliance Policy",
"enabled": true,
"rules": [
{
"type": "LICENSE_TYPE",
"action": "FAIL_BUILD",
"deniedLicenses": ["GPL-2.0", "GPL-3.0", "AGPL-3.0"]
},
{
"type": "LICENSE_TYPE",
"action": "REQUIRE_APPROVAL",
"approvalRequired": ["LGPL-2.1", "LGPL-3.0", "MPL-2.0"]
}
]
}
License policy categories:
- Denied licenses: Licenses prohibited in all circumstances (strong copyleft for proprietary software).
- Approval-required licenses: Licenses requiring legal review before use (weak copyleft, custom licenses).
- Allowed licenses: Permissive licenses acceptable without review (MIT, Apache 2.0, BSD).
Custom policy rules
Advanced policy conditions:
{
"name": "Advanced Security Policy",
"enabled": true,
"rules": [
{
"type": "VULNERABILITY_CVSS_SCORE",
"action": "FAIL_BUILD",
"minScore": 7.0,
"condition": "exploitMaturity == 'FUNCTIONAL' OR exploitMaturity == 'HIGH'"
},
{
"type": "DEPENDENCY_AGE",
"action": "WARN",
"maxAge": 365,
"message": "Dependency has not been updated in over a year"
},
{
"type": "MAINTAINER_STATUS",
"action": "WARN",
"condition": "abandonedProject == true"
}
]
}
SBOM generation in pipelines
Software Bill of Materials (SBOM) documents provide comprehensive inventory of all software components.
Generate SBOM artifacts
CycloneDX SBOM generation:
steps:
- task: UseNode@1
inputs:
version: "18.x"
- script: |
npm ci
npm install -g @cyclonedx/cyclonedx-npm
cyclonedx-npm --output-file sbom.json
displayName: "Generate CycloneDX SBOM"
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: "sbom.json"
artifactName: "SBOM"
SPDX SBOM generation:
steps:
- script: |
pip install spdx-tools
pip-licenses --format=json --output-file=licenses.json
# Convert to SPDX format using custom script
python scripts/generate_spdx.py licenses.json sbom.spdx
displayName: "Generate SPDX SBOM"
SBOM use cases:
- Compliance evidence: Provide to customers or auditors demonstrating dependency transparency.
- Vulnerability tracking: Use SBOM to quickly determine if newly disclosed vulnerabilities affect deployed software.
- Supply chain security: Track software provenance and detect supply chain attacks.
- License compliance: Document all license obligations in deployed software.
Tool-specific integrations
Mend (formerly WhiteSource)
Azure Pipelines Mend task:
- task: WhiteSource@21
inputs:
cwd: "$(System.DefaultWorkingDirectory)"
projectName: "$(Build.Repository.Name)"
checkPolicies: true
failBuildOnPolicyViolation: true
scanComment: "Build $(Build.BuildNumber)"
displayName: "Mend SCA scan"
Snyk
Azure Pipelines Snyk task:
- task: SnykSecurityScan@1
inputs:
serviceConnectionEndpoint: "SnykConnection"
testType: "app"
severityThreshold: "high"
monitorOnBuild: true
failOnIssues: true
displayName: "Snyk security scan"
OWASP Dependency-Check
Azure Pipelines OWASP task:
- script: |
wget https://github.com/jeremylong/DependencyCheck/releases/download/v8.0.0/dependency-check-8.0.0-release.zip
unzip dependency-check-8.0.0-release.zip
./dependency-check/bin/dependency-check.sh \
--project "$(Build.Repository.Name)" \
--scan . \
--format ALL \
--failOnCVSS 7
displayName: "OWASP Dependency-Check scan"
Black Duck
Azure Pipelines Black Duck task:
- task: BlackDuck@1
inputs:
BlackDuckService: "BlackDuckConnection"
ScanMode: "intelligent"
DetectArguments: "--detect.policy.check.fail.on.severities CRITICAL,HIGH"
displayName: "Black Duck scan"
Best practices for pipeline integration
Optimize scan performance:
- Incremental scanning: Use incremental scans for pull requests, full scans for main branch builds.
- Caching: Cache dependency resolution and scan results to speed up subsequent runs.
- Parallel execution: Run SCA scans in parallel with other build steps when possible.
- Scan scheduling: Run comprehensive scans on schedules rather than blocking every commit.
Manage false positives:
- Suppression files: Maintain suppression files for known false positives.
- Context-aware policies: Configure policies considering whether vulnerable code is actually used.
- Regular review: Periodically review suppressed findings to ensure they remain false positives.
Provide actionable feedback:
- Clear messages: Provide clear explanations of policy violations and remediation steps.
- Remediation guidance: Link to documentation explaining how to fix vulnerabilities.
- Prioritization: Rank findings by severity and exploitability to help developers prioritize.
Monitor and improve:
- Metrics dashboards: Track vulnerability trends, remediation time, and compliance rates.
- Team education: Train developers on secure dependency selection and vulnerability remediation.
- Process iteration: Continuously refine policies and integration based on team feedback and metrics.
Integrating Software Composition Analysis into CI/CD pipelines transforms security from a late-stage gate into a continuous validation process throughout development. Automated, policy-driven scanning catches vulnerabilities early, enforces compliance continuously, and provides the foundation for secure software delivery. The next unit examines specific SCA tools and how to evaluate their capabilities for your organization's needs.