How to Upload Vulnerability Reports to Teamscale
A vulnerability report is a machine-readable document describing the third-party components a build depends on, together with metadata such as their versions, licenses and known vulnerabilities. Teamscale currently accepts vulnerability reports in the form of Software Bills of Materials (SBOMs); the feature is named generically because support for further report formats may be added in the future. Teamscale can import the reports your builds produce and display their components and vulnerabilities in the Software Composition perspective.
Uploading vulnerability reports complements the JFrog Xray connector: it lets you populate the Software Composition perspective straight from your CI pipeline. It does not require a Software Composition Analysis (SCA) tool connector to be configured for the project.
Supported Formats
Teamscale accepts the following SBOM formats:
| Format | Serialization | Notes |
|---|---|---|
| CycloneDX | JSON or XML | Prefer this format if you need vulnerability data (see Vulnerabilities). |
| SPDX 2.x | JSON only | Components and licenses only; SPDX carries no vulnerability data (see Vulnerabilities). |
The format is detected automatically by Teamscale. Teamscale rejects a file that it cannot recognize or parse, and teamscale-upload then fails with an error message.
Generating a Report
Any tool that writes one of the formats above can feed Teamscale. Common choices are:
- The CycloneDX plugins for build tools such as Maven, Gradle, npm or .NET.
- Syft for containers, images and file systems.
- Trivy, which additionally reports the vulnerabilities it finds.
- Grype, which adds vulnerabilities to an SBOM you already have.
Build-tool plugins such as the CycloneDX ones list the components but no vulnerabilities. Use a scanner if you want Teamscale to show vulnerabilities as well. Refer to the documentation of your tool for how to make it write CycloneDX or SPDX.
Prerequisites
- The Teamscale server must be reachable via HTTP(S) from the machine performing the upload.
- You need a Teamscale user with the Perform External Uploads permission for the target project — the same permission required for other external uploads. For a production setup we recommend creating a technical user with the Build role.
- You need that user's access key (not their password). You can generate an access key on the profile page:
<TEAMSCALE_URL>/user/access-key. - You need
teamscale-uploadversion 2.11.0 or later.
No analysis profile setting or SCA connector needs to be enabled for the upload to work.
Uploading a Report
Upload a report with the vulnerability-report command of teamscale-upload:
teamscale-upload/bin/teamscale-upload vulnerability-report \
--server https://teamscale-server:8080 \
--project my-project \
--user build \
--accesskey <ACCESSKEY> \
--build-name my-service \
--build-version 1.4.2 \
sbom.cyclonedx.jsonteamscale-upload exits with code 0 if the upload succeeded. Any other exit code indicates a problem, which teamscale-upload logs to the console. Run teamscale-upload vulnerability-report --help to see all options.
Options
| Option | Required | Description |
|---|---|---|
--server | yes | The URL of the Teamscale server. |
--project | yes | The ID of the Teamscale project to upload to. |
--user | yes | The Teamscale user that performs the upload. |
--accesskey | no | The access key of that user. You can also provide it in the environment variable TEAMSCALE_ACCESS_KEY, which keeps it out of the command line. |
--build-name | yes | Name of the build artifact the report describes, for example, a module, a service, a binary or the output of a CI job. Use the same name every time you rebuild that artifact. See Choosing Build Name and Build Version. |
--build-version | yes | Free-form text that identifies this upload within the build, for example, a branch name, a release version or a commit hash. See Choosing Build Name and Build Version. |
--commit | no | The commit the build was produced from. Teamscale uses it to link the build and its violations to that commit. If you omit it, teamscale-upload detects the commit from your CI system or from the Git or SVN checkout in the working directory. |
REPORT | yes | The path or pattern of the report file. It must resolve to exactly one file. Teamscale detects the format automatically. |
Both the build name and the build version may contain slashes, so values such as feature/login can be used as-is. Neither value may contain the # character.
Teamscale stores and parses the report while handling the upload, so its components and vulnerabilities are available in the Web UI and via the REST API as soon as the upload finishes.
Reading the Uploaded Data
The components, vulnerabilities and violations of the uploaded reports can also be read via the REST API, for example, to gate a pipeline on them. These endpoints are documented in the API reference of your Teamscale instance, as described here.
Choosing Build Name and Build Version
The two values decide which reports Teamscale keeps and how you find them later.
Build name. The build name identifies the build artifact, for example, a module, a service, a library, a binary or the output of a CI job. Use one build name per artifact, and use exactly the same name each time you rebuild that artifact. If the name changes between builds, Teamscale shows the uploads as separate builds.
Build version. The build version is free-form text. Teamscale does not interpret it and does not attach further meaning to it. It keeps one report per combination of build name and build version:
- If you upload a report with a new build version, Teamscale adds it as a new version of the build.
- If you upload a report with a build name and build version that already exist, the new report replaces the old one. Teamscale also replaces the commit that it links to that version.
The commit plays no role in this decision. Teamscale replaces a report only if both the build name and the build version match.
Choose the build version according to which reports you want to keep:
| You want to keep | Use as build version | Example values |
|---|---|---|
| The latest report of each branch | The branch name | main, feature/login |
| One report per release | The release version | 2026.6.0, 2026.6.1 |
| One report per release on each branch | Branch name and release version | main/2026.6.0, release-2026.6/2026.6.1 |
| One report per commit | A value that contains the commit hash | main/0842320e |
The latest report of each branch. Use the branch name as build version. Every new commit on the branch uploads its report with the same build version, so the new report replaces the previous one. Teamscale therefore stores only the most recent report of each branch.
One report per release. Use the version number of your software, for example, 2026.6.0 and then 2026.6.1. Every release gets its own entry, so you can compare the components of different releases. If you rebuild a release, the new report replaces the old one.
Branch and release combined. Combine both values into one build version, for example, main/2026.6.0. You can then tell the uploads apart by branch and by release. Teamscale stores the combined value as plain text, so choose a format that you can read later.
One report per commit. The build version must differ for every commit. The easiest way is to include the commit hash, for example, $CI_COMMIT_SHA on GitLab CI. You can add the branch name as well, for example, main/0842320e, to see the branch in the Builds view. Teamscale then stores a report for every commit, so the number of versions grows with every upload.
Different strategies for different branches. You can use several of these strategies for the same build at the same time. For example, your feature branches can upload with the branch name as build version, so Teamscale keeps only their latest report. At the same time, your release branches can upload with the release version, so Teamscale keeps one report per release. Make sure that the values of the different strategies never coincide, because equal values replace each other.
Uploading Several Reports for One Commit
You can upload any number of reports for the same commit, for example, one per module or one per container image. Give each report its own build name. Because the build names differ, the reports do not replace each other, even though they share the commit.
You can then view the reports of a commit in two ways:
- Combined. The SBOM view and the Violations view show the components and violations of all reports uploaded for the selected commit in one table. The Build column shows which report each entry comes from.
- Individually. The Builds view lists each build separately. Open a build version to see the components, vulnerabilities and violations of that single report.
Uploading from a CI Pipeline
Generate the report as part of your build with the tool of your choice, then upload the resulting file with the identifiers your CI system already provides. The following example uses GitLab CI variables and keeps the latest report of each branch:
# The access key is read from the masked CI variable TEAMSCALE_ACCESS_KEY.
# The commit is detected automatically.
teamscale-upload/bin/teamscale-upload vulnerability-report \
--server https://teamscale-server:8080 \
--project my-project \
--user build \
--build-name my-service \
--build-version "$CI_COMMIT_REF_NAME" \
bom.jsonTo keep a report for every commit instead, use --build-version "$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA". See Choosing Build Name and Build Version for further options.
Store the access key as a masked CI variable rather than in the pipeline definition.
Vulnerabilities
Teamscale surfaces only the vulnerabilities the uploaded report itself contains. It does not run its own security checks on the components and does not query external vulnerability databases. How much vulnerability data is available therefore depends on the format:
- CycloneDX files can carry a dedicated
vulnerabilitiessection, which Teamscale imports in full. - SPDX 2.x has no vulnerability section, so reports in this format generally carry no vulnerability data.
Use CycloneDX if you want Teamscale to show vulnerabilities and the resulting policy violations for your components.
Each vulnerability in the report becomes both a vulnerability (shown on the build details) and a violation of type security (shown in the Violations view, where it can be marked as tolerated or false positive). Teamscale normalizes the severity ratings of the report to Critical, High, Medium, Low, None or Unknown.
Viewing Uploaded Reports
Uploaded reports appear in the Software Composition perspective:
- The SBOM view lists the components of all reports uploaded for the selected commit.
- The Builds view lists each build and its versions; the build details include an SBOM tab with that version's components and a Vulnerabilities tab.
- The Violations view lists the policy violations derived from the vulnerabilities of the reports uploaded for the selected commit, where you can mark them as tolerated or false positive.
