Automated system for publishing Software Bill of Materials (SBOMs) for Contrast Security products.
🌐 Live Site: https://contrastsecurity.dev/sbom-public/
This repository automatically generates and publishes SBOMs for Contrast Security products in both SPDX and CycloneDX formats. A modern, searchable web interface hosted on GitHub Pages provides easy access to all SBOMs for transparency and compliance.
- 🔄 Automated SBOM Generation: Workflow-triggered generation with manual dispatch option
- 📦 Multi-Source Support: Fetches artifacts from S3, Maven Central, npm, PyPI, NuGet, and Artifactory
- 🔐 Anonymous Access: Works with public repositories without credentials
- 📋 Dual Format: SPDX and CycloneDX for maximum compatibility
- 🔍 Searchable Interface: Modern web UI with filtering and sorting
- 🌳 Dependency Tree Viewer: Interactive, collapsible tree visualization with search
- 📱 Mobile Responsive: Works seamlessly on all devices
- ⚡ Static Site: Fast, no backend required
- 🛡️ Enhanced Detection: Comprehensive multi-language dependency scanning
8 of 8 products • 84 versions • 168 SBOM files (SPDX + CycloneDX)
| Product | Versions | Source | Status |
|---|---|---|---|
| EOP | 13 | Manual (S3) | ✅ Active |
| Java Agent | 10 | Maven Central | ✅ Active |
| Flex Agent | 11 | Manual | ✅ Active |
| Go Agent (Linux AMD64) | 10 | Artifactory (public) | ✅ Active |
| Node Agent | 10 | npm | ✅ Active |
| Python Agent | 10 | PyPI | ✅ Active |
| DotNet Core Agent | 10 | NuGet | ✅ Active |
| DotNet Core IIS Installer | 10 | NuGet | ✅ Active |
- SBOM Generator: Syft by Anchore (with enhanced multi-language catalogers)
- Automation: GitHub Actions workflows
- Hosting: GitHub Pages (static site)
- Frontend: Vanilla JavaScript with modern UI
- Visualization: Interactive dependency tree viewer
┌─────────────┐
│ Sources │
│ - S3 │
│ - Maven │
│ - npm │
│ - PyPI │
│ - NuGet │
│ - Artifactory│
└──────┬──────┘
│
▼
┌─────────────┐
│ Fetch & │
│ Generate │
│ (Syft) │
└──────┬──────┘
│
▼
┌─────────────┐
│ Build │
│ Index │
└──────┬──────┘
│
▼
┌─────────────┐
│ GitHub │
│ Pages │
└─────────────┘
.
├── .github/workflows/
│ └── generate-sboms.yml # Main automation workflow
├── config/
│ └── products.yml # Product definitions
├── scripts/
│ ├── fetch-and-generate.sh # Unified fetch + SBOM generation
│ ├── build-index.sh # Index builder
│ └── build-site.js # Static site builder
├── site/ # Website source files
│ ├── index.html
│ ├── app.js
│ ├── styles.css
│ ├── dependency-tree.html
│ ├── dependency-tree.js
│ └── logo.svg
├── docs/ # Generated GitHub Pages site
│ ├── sboms/ # Generated SBOMs
│ │ ├── index.json # Product/version index
│ │ ├── {product}/
│ │ │ ├── metadata.json
│ │ │ └── {version}/
│ │ │ ├── sbom.spdx.json
│ │ │ └── sbom.cyclonedx.json
│ └── [website files]
├── SPEC.md # Technical specification
└── README.md # This file
-
GitHub Repository with Pages enabled:
- Settings → Pages → Source: Deploy from branch
- Branch:
master→/docs
-
Required GitHub Secrets:
ARTIFACTORY_URL # Base URL (e.g., https://pkg.contrastsecurity.com/artifactory) S3_PUBLIC_URL # Public S3 bucket URL (for EOP) -
Optional GitHub Secrets (for private Artifactory repositories):
ARTIFACTORY_USER # Artifactory username ARTIFACTORY_PASSWORD # Artifactory password or API token
Products are configured in config/products.yml:
products:
# Maven Central example
- name: "Java Agent"
source: "maven"
maven_group_id: "com.contrastsecurity"
maven_artifact_id: "contrast-agent"
max_versions: 10
# npm registry example
- name: "Node Agent"
source: "npm"
npm_package: "@contrast/agent"
max_versions: 10
# PyPI registry example
- name: "Python Agent"
source: "pypi"
pypi_package: "contrast-agent"
max_versions: 10
# NuGet registry example
- name: "DotNet Core Agent"
source: "nuget"
nuget_package: "Contrast.SensorsNetCore"
max_versions: 10
# Artifactory with flat structure (version/file)
- name: "Flex Agent"
source: "artifactory"
artifactory_path: "flex-agent-release"
artifact_pattern: "contrast-flex-agent*"
max_versions: 10
# Artifactory with nested structure (version/platform/file)
- name: "Go Agent (Linux AMD64)"
source: "artifactory"
artifactory_path: "go-agent-release"
platform_subdir: "linux-amd64"
artifact_pattern: "contrast-go*"
max_versions: 10See config/products.yml for complete examples.
Platform Subdirectory Support: For Artifactory repositories with nested version/platform/file structures, use the platform_subdir field to specify the platform directory within each version folder.
Visit the live site: https://contrastsecurity.dev/sbom-public/
Features:
- Search: Filter by product name or version
- Sort: By name, date, or version count
- Download: SPDX or CycloneDX formats
- View: Inspect SBOM content in-browser
- Dependency Tree: Interactive hierarchical view with expand/collapse and search
- Go to Actions tab
- Select Generate SBOMs workflow
- Click Run workflow
- Select branch and run
Performance Optimization: The workflow is optimized to only process NEW releases. On the first run, it generates SBOMs for all configured versions. On subsequent runs, it:
- Checks each product's latest releases (up to max_versions)
- Skips versions that already have SBOMs
- Only downloads and generates SBOMs for new releases
- Completes in <1 minute when no new releases are available
This means the workflow can run frequently (daily, weekly) without consuming excessive resources.
Test the website locally:
# Serve the docs directory
python3 -m http.server --directory docs 8000
# Or use any static file server
npx serve docs
# Visit http://localhost:8000Test SBOM generation locally:
# Set environment variables
export ARTIFACTORY_URL="https://pkg.contrastsecurity.com/artifactory"
export S3_PUBLIC_URL="https://your-bucket.s3.amazonaws.com/path/"
# Run the fetch and generate script
./scripts/fetch-and-generate.sh
# Build the index
./scripts/build-index.sh
# Build the site
node scripts/build-site.js-
Edit
config/products.yml:- name: "New Product" source: "maven" maven_group_id: "com.contrastsecurity" maven_artifact_id: "new-product" max_versions: 10
-
Commit and push changes
-
Run workflow manually or wait for next scheduled run
-
SBOMs will appear on the website automatically
Currently, several products require Artifactory credentials. To enable them:
-
Add GitHub Secrets (if not already present):
ARTIFACTORY_USER=your-username ARTIFACTORY_PASSWORD=your-password-or-token -
Run workflow - products will be fetched automatically
- Workflow Status: Check Actions tab for run history
- Email Notifications: GitHub sends emails on workflow failures
- Site Health: Visit the live site to verify updates
- Workflow Artifacts: Auto-deleted after 90 days
- SBOMs in docs/: Persisted in Git (small JSON files)
- Repository Size: Monitor with
git count-objects -vH
- Edit files in
site/directory - Run
node scripts/build-site.jsto copy todocs/ - Commit and push changes
- GitHub Pages updates automatically
The system is designed to work with public repositories:
- S3: Uses public HTTP endpoints (no AWS credentials)
- Maven Central: Public API
- npm: Public registry API
- PyPI: Public registry API
- NuGet: Public registry API v3
- Artifactory: Public repos use REST API anonymously
For private Artifactory repositories:
- Credentials stored as GitHub encrypted secrets
- Used only during workflow execution
- Never exposed in logs or outputs
SBOMs are automatically protected from overwrite:
- Version-level protection: The
check_sbom_exists()function checks for existing SBOMs before processing each version - Automatic skip: If both SPDX and CycloneDX files exist for a version, it's skipped entirely
- Manual SBOMs preserved: EOP and Flex Agent manually-committed SBOMs remain protected
- Selective regeneration: To regenerate specific SBOMs, delete the version directory and rerun the workflow
- No data loss: Once generated, SBOMs won't be accidentally overwritten
Check the Actions tab for detailed logs. Common issues:
- Secrets not set: Add required secrets in repository settings
- Network errors: Retry the workflow
- Invalid config: Validate
products.ymlsyntax
If a product doesn't appear:
- Check workflow logs for fetch errors
- Verify source repository/URL is correct
- For Artifactory: Ensure credentials have read access
- Check
docs/sboms/index.jsonfor product entry
- Hard refresh browser (Ctrl+Shift+R / Cmd+Shift+R)
- Check GitHub Pages Settings → Pages → Build status
- Wait 2-5 minutes for CDN cache to clear
For detailed technical specifications, see SPEC.md.
Topics covered:
- Complete configuration schema
- Script implementation details
- Workflow specification
- Security model
- Extension guide
This is a Contrast Security internal project. For questions or issues:
- Check the SPEC.md for technical details
- Review workflow logs in Actions tab
- Contact the Contrast Security OSS team
This repository is maintained by Contrast Security for transparency and compliance purposes.
The SBOMs published here are for informational purposes and subject to change.