The template will be triggered at each pipeline execution on your production branch (`main` or `master` by default) and each release pipeline (upon semver tag creation).
It will scan for all SBOM file in your project structure and will upload them to the configured Dependency Track server.\
:information_source: SBOM files should have been generated in the upstream pipeline with appropriate tools, and propagated as build artifacts. Most to-be-continuous templates already support - whenever possible - a job to produce a SBOM report.
### API Key permissions
In order to operate, this template needs a Dependency Track API Key.
Here are some details about mandatory and optional permissions used by the template:
| `BOM_UPLOAD` | **mandatory** | Required to publish SBOM files to the Dependency Track server |
| `PROJECT_CREATION_UPLOAD` | **optional** | This is required if you want to automatically create the project while uploading the SBOM files when the project does not exist (**but the parent project must exist**) |
| `VIEW_PORTFOLIO` and `PORTFOLIO_MANAGEMENT` | **optional** | Required if you want to automatically create one or several project ancestors prior to uploading the SBOM files.<br/>Granting those permissions is not recommended in the general case as they virtually give administration rights to the API Key owner |
### Project Path
Whenever a SBOM file is found, the template uploads it to the Dependency Track server under a certain project.\
The target project is determined by evaluating the `project-path` input / `$DEPTRACK_PROJECT_PATH` variable (see [configuration chapter](#configuration)).
The project path is a sequence of elements separated by double slashes `//` (the separator is also configurable with the `path-separator` input / `$DEPTRACK_PATH_SEPARATOR` variable).\
Each element is expected to be one of the following:
1.`#11111111-1111-1111-1111-111111111111`: a project [Universally Unique Identifier (UUID)](https://en.wikipedia.org/wiki/Universally_unique_identifier)(starting with a hash `#`)
2.`project-name@version`: a **project name** and a **version** (separated with a `@`)
3.`project-name`: a **project name** only (empty version)
Lastly, the project path supports some **expressions**, that will be dynamically replaced when being evaluated:
| `{file_prefix}` | SBOM filename prefix (before the first dot).<br/>Ex: when processing the file `reports/docker-sbom.cyclonedx.json`, `{file_prefix}` will be `docker-sbom`. |
| `{sbom_name}` | `Metadata > Component > Name` info extracted from the SBOM file (json or xml) |
| `{sbom_version}` | `Metadata > Component > Version` info extracted from the SBOM file (json or xml) |
| `{sbom_type}` | `Metadata > Component > Type` info extracted from the SBOM file (json or xml) |
#### Default project path
By default, the Dependency Track project path is set to `$CI_PROJECT_NAMESPACE//$CI_PROJECT_PATH-{file_prefix}@$CI_COMMIT_REF_NAME` (with path separator `//`).
That means:
- The project structure in Dependency Track will always be two levels deep:
- a _root_ project bearing the name of the GitLab project namespace,
- and _leaf_ projects (hosting SBOM files) bearing the full path of the GitLab project as a name, suffixed with the
SBOM file prefix and with project version matching either the Git branch name or the Git tag name (depending on the
kind of pipeline that originated the SBOM file).
- If the API key has only the `BOM_UPLOAD` permission, then all the projects hierarchy must pre-exist down to the leaf
sub-projects.
- If the API key has the extra `PROJECT_CREATION_UPLOAD` permission, then only the root project must pre-exist, the template
will automatically create the leaf projects if not found.
- If the API key has the extra `VIEW_PORTFOLIO` and `PORTFOLIO_MANAGEMENT` permissions (not recommanded), then the entire
project hierarchy will be automatically created by the template if it doesn't exist.
Example: Let's imagine a GitLab project located in `acme-program/acme-services/acme-user-api` with 2 SBOM files generated by the pipeline:
-`py-sbom.cyclonedx.json`: the SBOM of the Python application implementation, with version `1.1.0`
-`docker-sbom.cyclonedx.json`: the SBOM of the container image, with version `main`
Lastly, let's suppose the project production branch is `main`, and 2 software versions have been released so far: `1.0.0` and `1.1.0`.
Then the corresponding Dependency Track project structure will be:
> :bulb: this default configuration handles the Dependency Track constraint that each project name has to be globally
> unique in the server.
#### Other use cases
The default template behavior can be changed by overridding the `project-path` input / `$DEPTRACK_PROJECT_PATH` variable.
Examples:
-`#550e8400-e29b-41d4-a716-446655440000`: every SBOM found will be published to the project with UUID `550e8400-e29b-41d4-a716-446655440000`<br/>
:information_source: as Dependency Track is only able to store one SBOM per project, this configuration is suitable only if exactly one SBOM file is found (otherwise each one will overwrite the previous one)
-`my-project@v1.1.0`: every SBOM found will be published to the project with name `my-project` and version `v1.1.0`<br/>
:information_source: depending on your API key permissions, `sbom-scanner` might try to automatically create the project if it doesn't exist<br/>
:information_source: as in the previous example, this configuration is suitable only if exactly one SBOM file is found
-`#550e8400-e29b-41d4-a716-446655440000/my-project-{file_prefix}@{sbom_version}`: every SBOM found will be published to a project named `my-project-{file_prefix}` and version `{sbom_version}` (extracted from the SBOM file),
direct child of project with UUID `550e8400-e29b-41d4-a716-446655440000`<br/>
:information_source: depending on your API key permissions, `sbom-scanner` might try to automatically create the project if it doesn't exist
-`acme-program@v2/acme-services@v1.3/acme-user-api@v1.3/acme-user-api-{file_prefix}`: complete project path only defined by project names and versions<br/>
:information_source: depending on your API key permissions, `sbom-scanner` might try to automatically create the project and its ancestors if they don't exist
## Configuration
The Dependency Track template uses the following configuration.
| Input / Variable | Description | Default value |