Scan for Vulnerabilities

Octopus.Script exported 2025-11-02 by mcasperson belongs to ‘SBOM’ category.

This step extracts the Docker image, finds any bom.json files, and scans them for vulnerabilities using Trivy.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Application package containing the SBOM to scan

Sbom.Package =

Script body

Steps based on this template will execute the following PowerShell script.

Write-Host "Pulling Trivy Docker Image"
Write-Host "##octopus[stdout-verbose]"
docker pull ghcr.io/aquasecurity/trivy
Write-Host "##octopus[stdout-default]"

$SUCCESS = 0

Write-Host "##octopus[stdout-verbose]"
Get-ChildItem -Path "." | Out-String
Write-Host "##octopus[stdout-default]"

# Find all bom.json files
$bomFiles = Get-ChildItem -Path "." -Filter "bom.json" -Recurse -File

if ($bomFiles.Count -eq 0) {
    Write-Host "No bom.json files found in the current directory."
    exit 0
}

foreach ($file in $bomFiles) {
    Write-Host "Scanning $($file.FullName)"

    # Delete any existing report file
    if (Test-Path "$PWD/depscan-bom.json") {
        Remove-Item "$PWD/depscan-bom.json" -Force
    }

    # Generate the report, capturing the output
    try {
        $OUTPUT = docker run --rm -v "$($file.FullName):/input/$($file.Name)" ghcr.io/aquasecurity/trivy sbom -q "/input/$($file.Name)"
        $exitCode = $LASTEXITCODE
    }
    catch {
        $OUTPUT = $_.Exception.Message
        $exitCode = 1
    }

    # Run again to generate the JSON output
    docker run --rm -v "${PWD}:/output" -v "$($file.FullName):/input/$($file.Name)" ghcr.io/aquasecurity/trivy sbom -q -f json -o /output/depscan-bom.json "/input/$($file.Name)"

    # Octopus Deploy artifact
    New-OctopusArtifact "$PWD/depscan-bom.json"

    # Parse JSON output to count vulnerabilities
    $jsonContent = Get-Content -Path "depscan-bom.json" | ConvertFrom-Json
    $CRITICAL = ($jsonContent.Results | ForEach-Object { $_.Vulnerabilities } | Where-Object { $_.Severity -eq "CRITICAL" }).Count
    $HIGH = ($jsonContent.Results | ForEach-Object { $_.Vulnerabilities } | Where-Object { $_.Severity -eq "HIGH" }).Count

    if ("#{Octopus.Environment.Name}" -eq "Security") {
        Write-Highlight "🟥 $CRITICAL critical vulnerabilities"
        Write-Highlight "🟧 $HIGH high vulnerabilities"
    }

    # Set success to 1 if exit code is not zero
    if ($exitCode -ne 0) {
        $SUCCESS = 1
    }

    # Print the output
    $OUTPUT | ForEach-Object {
        if ($_.Length -gt 0) {
            Write-Host $_
        }
    }
}

# Cleanup
for ($i = 1; $i -le 10; $i++) {
    try {
        if (Test-Path "bundle") {
            Set-ItemProperty -Path "bundle" -Name IsReadOnly -Value $false -Recurse -ErrorAction SilentlyContinue
            Remove-Item -Path "bundle" -Recurse -Force -ErrorAction Stop
            break
        }
    }
    catch {
        Write-Host "Attempting to clean up files"
        Start-Sleep -Seconds 1
    }
}

# Set Octopus variable
Set-OctopusVariable -Name "VerificationResult" -Value $SUCCESS

exit 0

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "a38bfff8-8dde-4dd6-9fd0-c90bb4709d5a",
  "Name": "Scan for Vulnerabilities",
  "Description": "This step extracts the Docker image, finds any bom.json files, and scans them for vulnerabilities using Trivy.",
  "Version": 2,
  "ExportedAt": "2025-11-02T21:42:33.662Z",
  "ActionType": "Octopus.Script",
  "Author": "mcasperson",
  "Packages": [
    {
      "Id": "9b495093-0020-4df8-bc44-2fd65ab13943",
      "Name": "application",
      "PackageId": "",
      "FeedId": null,
      "AcquisitionLocation": "Server",
      "Properties": {
        "Extract": "True",
        "SelectionMode": "deferred",
        "PackageParameterName": "Sbom.Package"
      }
    }
  ],
  "Parameters": [
    {
      "Id": "9cea163a-a048-4ff5-9405-56fdcb9015c7",
      "Name": "Sbom.Package",
      "Label": "Application package containing the SBOM to scan",
      "HelpText": null,
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Package"
      }
    }
  ],
  "Properties": {
    "OctopusUseBundledTooling": "False",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "Write-Host \"Pulling Trivy Docker Image\"\nWrite-Host \"##octopus[stdout-verbose]\"\ndocker pull ghcr.io/aquasecurity/trivy\nWrite-Host \"##octopus[stdout-default]\"\n\n$SUCCESS = 0\n\nWrite-Host \"##octopus[stdout-verbose]\"\nGet-ChildItem -Path \".\" | Out-String\nWrite-Host \"##octopus[stdout-default]\"\n\n# Find all bom.json files\n$bomFiles = Get-ChildItem -Path \".\" -Filter \"bom.json\" -Recurse -File\n\nif ($bomFiles.Count -eq 0) {\n    Write-Host \"No bom.json files found in the current directory.\"\n    exit 0\n}\n\nforeach ($file in $bomFiles) {\n    Write-Host \"Scanning $($file.FullName)\"\n\n    # Delete any existing report file\n    if (Test-Path \"$PWD/depscan-bom.json\") {\n        Remove-Item \"$PWD/depscan-bom.json\" -Force\n    }\n\n    # Generate the report, capturing the output\n    try {\n        $OUTPUT = docker run --rm -v \"$($file.FullName):/input/$($file.Name)\" ghcr.io/aquasecurity/trivy sbom -q \"/input/$($file.Name)\"\n        $exitCode = $LASTEXITCODE\n    }\n    catch {\n        $OUTPUT = $_.Exception.Message\n        $exitCode = 1\n    }\n\n    # Run again to generate the JSON output\n    docker run --rm -v \"${PWD}:/output\" -v \"$($file.FullName):/input/$($file.Name)\" ghcr.io/aquasecurity/trivy sbom -q -f json -o /output/depscan-bom.json \"/input/$($file.Name)\"\n\n    # Octopus Deploy artifact\n    New-OctopusArtifact \"$PWD/depscan-bom.json\"\n\n    # Parse JSON output to count vulnerabilities\n    $jsonContent = Get-Content -Path \"depscan-bom.json\" | ConvertFrom-Json\n    $CRITICAL = ($jsonContent.Results | ForEach-Object { $_.Vulnerabilities } | Where-Object { $_.Severity -eq \"CRITICAL\" }).Count\n    $HIGH = ($jsonContent.Results | ForEach-Object { $_.Vulnerabilities } | Where-Object { $_.Severity -eq \"HIGH\" }).Count\n\n    if (\"#{Octopus.Environment.Name}\" -eq \"Security\") {\n        Write-Highlight \"🟥 $CRITICAL critical vulnerabilities\"\n        Write-Highlight \"🟧 $HIGH high vulnerabilities\"\n    }\n\n    # Set success to 1 if exit code is not zero\n    if ($exitCode -ne 0) {\n        $SUCCESS = 1\n    }\n\n    # Print the output\n    $OUTPUT | ForEach-Object {\n        if ($_.Length -gt 0) {\n            Write-Host $_\n        }\n    }\n}\n\n# Cleanup\nfor ($i = 1; $i -le 10; $i++) {\n    try {\n        if (Test-Path \"bundle\") {\n            Set-ItemProperty -Path \"bundle\" -Name IsReadOnly -Value $false -Recurse -ErrorAction SilentlyContinue\n            Remove-Item -Path \"bundle\" -Recurse -Force -ErrorAction Stop\n            break\n        }\n    }\n    catch {\n        Write-Host \"Attempting to clean up files\"\n        Start-Sleep -Seconds 1\n    }\n}\n\n# Set Octopus variable\nSet-OctopusVariable -Name \"VerificationResult\" -Value $SUCCESS\n\nexit 0"
  },
  "Category": "SBOM",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/a381802920158308/step-templates/sbom-scan.json",
  "Website": "/step-templates/a38bfff8-8dde-4dd6-9fd0-c90bb4709d5a",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Sunday, November 2, 2025