The most reliable SBOM is the one your build produces on every release. Threat Detective's CI integration lets your pipeline upload SBOMs automatically, authenticated with short-lived identity tokens (OIDC) that your CI provider issues for each run. There are no API keys or secrets to store or rotate.
Step 1: create the integration
Open your project's Settings tab and click Manage CI/CD Integrations, then New CI/CD Integration.
Choose your CI provider: GitHub Actions, GitLab CI, CircleCI, Bitbucket Pipelines, or Custom for any other OIDC-capable system.
Connect your repository: give the integration a name, enter the repository in
owner/repositoryformat, and optionally restrict it to a branch (leave blank to allow any branch).Click Save Integration.
Uploads are only accepted when the CI token's issuer, repository and (if set) branch match the integration. A token from any other repository is rejected. The advanced settings let you tighten this further with an audience, subject filter or claim conditions.
Step 2 (GitHub): use the official action
For GitHub Actions, the easiest path is our published action, threatdetective/upload-sbom-action. It requests the OIDC token, uploads the file, and reports the result as step outputs. Two things to set up in your workflow:
permissions:
id-token: write # lets the action request an OIDC token
contents: read
steps:
- uses: actions/checkout@v4
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
format: cyclonedx-json
output-file: sbom.json
- name: Upload SBOM
uses: threatdetective/upload-sbom-action@v1
with:
project-id: YOUR_PROJECT_ID
sbom-file: sbom.json
Without id-token: write the action can't request a token and will fail; that permission is the whole authentication story. Your project ID appears on the integration's Pipeline Setup panel, which shows this snippet with the real values filled in.
Useful options: version and software-item-name override what's read from the SBOM's metadata (handy for tagging uploads with the branch or tag name), and wait-for-completion: true makes the step poll until the import finishes, exposing status, component-count and the created version's ID as outputs for later steps. auto-create is on by default, so new software items are created from the SBOM automatically.
Step 2 (other providers): call the API
For GitLab CI, CircleCI, Bitbucket and custom systems, the integration's Pipeline Setup panel shows a ready-made snippet with your project URL and audience filled in: obtain the OIDC token from your CI provider, then POST the SBOM to /api/v1/projects/YOUR_PROJECT_ID/sbom with the token as a bearer credential in the request's authorisation header.
The endpoint accepts CycloneDX and SPDX (2.2/2.3 JSON and tag-value, 3.0.x JSON-LD), up to 50 MB.
How uploads behave
The API responds
202 Acceptedwith animport_id, and a status endpoint lets your pipeline poll until the import completes (the GitHub Action'swait-for-completiondoes this for you).Re-uploading the same CycloneDX document (same serial number) returns an "already been imported" response instead of creating a duplicate, so re-runs of a workflow are safe.
Rate limit: 60 requests per minute per integration.
Uploads appear in the project's Imports page and on the integration's Recent Imports table, and run through exactly the same pipeline as a manual upload, including the vulnerability scan.
Trial plans include one CI integration; paid plans are unlimited.
