Commit ea9d205f authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

feat(path): default project path that handles the project unicity conttraint

parent 3438762a
Loading
Loading
Loading
Loading
+29 −27
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ Here are some details about mandatory and optional permissions used by the templ
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 forward slashes `/` (although the separator is also configurable with the `path-separator` input / `$DEPTRACK_PATH_SEPARATOR` variable).\
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 `#`)
@@ -81,34 +81,47 @@ Lastly, the project path supports some **expressions**, that will be dynamically

#### Default project path

By default, the Dependency Track project path is set to `$CI_PROJECT_PATH/$CI_PROJECT_NAME-{file_prefix}@{sbom_version}`.
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 **match exactly** the GitLab groups, sub-groups and projects hierarchy.
- Each SBOM file found will be uploaded to a sub-project with same name as the project, suffixed with the SBOM file prefix and with project version extracted from the SBOM file.
- If the API key has only the `BOM_UPLOAD` permission, then all the projects hierarchy must pre-exist down to the parent project and even SBOM sub-projects.
- If the API key has the extra `PROJECT_CREATION_UPLOAD` permission, then all the projects hierarchy must pre-exist down to the parent project (hosting the SBOM sub-projects).
- If the API key has the extra `VIEW_PORTFOLIO` and `PORTFOLIO_MANAGEMENT` permissions (not recommanded), then the project hierarchy will be automatically created by the template if it doesn't exist.
- 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:

```
| Project name                                              | Version |
| ---------------------------------- | ------- |
| 📂 acme-program                    |         |
| ├─📂 acme-services                 |         |
| │ ├─📂 acme-user-api               |         |
| │ │ ├─📄 acme-user-api-py-sbom     | 1.1.0   |
| │ │ └─📄 acme-user-api-docker-sbom | main    |
| --------------------------------------------------------- | ------- |
| 📂 acme-program/acme-services                             |         |
| ├─📄 acme-program/acme-services/acme-user-api-py-sbom     | main    |
| ├─📄 acme-program/acme-services/acme-user-api-py-sbom     | 1.0.0   |
| ├─📄 acme-program/acme-services/acme-user-api-py-sbom     | 1.1.0   |
| ├─📄 acme-program/acme-services/acme-user-api-docker-sbom | main    |
| ├─📄 acme-program/acme-services/acme-user-api-docker-sbom | 1.0.0   |
| ├─📄 acme-program/acme-services/acme-user-api-docker-sbom | 1.1.0   |
| ...
```

> :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.
@@ -126,17 +139,6 @@ Examples:
- `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

> :bulb: you may decide to overwrite the path separator (ex: double slash `//`) if you want your project names to contain slashes.
>
> Example:
>
> ```yaml
> variables:
>   DEPTRACK_PATH_SEPARATOR: "//"
>   # flaten the projects hierarchy to depth 2 (full GitLab project namespace is mapped to one single DT project)
>   DEPTRACK_PROJECT_PATH: "$CI_PROJECT_PATH//$CI_PROJECT_NAME-{file_prefix}@{sbom_version}"
> ```

## Configuration

The Dependency Track template uses the following configuration.
@@ -146,8 +148,8 @@ The Dependency Track template uses the following configuration.
| `sbom-scanner-image` / `DEPTRACK_SBOM_SCANNER_IMAGE` | The container image with [Dependency Track SBOM Scanner](https://gitlab.com/to-be-continuous/tools/dt-sbom-scanner) tool | `registry.gitlab.com/to-be-continuous/tools/dt-sbom-scanner:latest` |
| `base-api-url` / `DEPTRACK_BASE_API_URL`             | Dependency Track server base API url (includes `/api`)                                                                   | _none_ (required)                                                   |
| :lock: `DEPTRACK_API_KEY`                            | Dependency Track API key                                                                                                 | _none_ (required)                                                   |
| `project-path` / `DEPTRACK_PROJECT_PATH`             | Dependency Track target project path to publish SBOM files to                                                            | `$CI_PROJECT_PATH/$CI_PROJECT_NAME-{file_prefix}@{sbom_version}`    |
| `path-separator` / `DEPTRACK_PATH_SEPARATOR`         | Separator to use in project path                                                                                         | `/`                                                                 |
| `project-path` / `DEPTRACK_PROJECT_PATH`             | Dependency Track target project path to publish SBOM files to                                                            | `$CI_PROJECT_NAMESPACE//$CI_PROJECT_PATH-{file_prefix}@$CI_COMMIT_REF_NAME`    |
| `path-separator` / `DEPTRACK_PATH_SEPARATOR`         | Separator to use in project path                                                                                         | `//`                                                                 |
| `sbom-patterns` / `DEPTRACK_SBOM_PATTERNS`           | SBOM file patterns to publish (supports glob patterns)                                                                   | `**/*.cyclonedx.json **/*.cyclonedx.xml`                            |

### Secrets management
+2 −2
Original line number Diff line number Diff line
@@ -26,12 +26,12 @@
    {
      "name": "DEPTRACK_PROJECT_PATH",
      "description": "Dependency Track target project path to publish SBOM files to",
      "default": "$CI_PROJECT_PATH/$CI_PROJECT_NAME-{file_prefix}@{sbom_version}"
      "default": "$CI_PROJECT_NAMESPACE//$CI_PROJECT_PATH-{file_prefix}@$CI_COMMIT_REF_NAME"
    },
    {
      "name": "DEPTRACK_PATH_SEPARATOR",
      "description": "Separator to use in project path",
      "default": "/",
      "default": "//",
      "advanced": true
    },
    {
+3 −3
Original line number Diff line number Diff line
@@ -23,10 +23,10 @@ spec:
      default: ''
    project-path:
      description: Dependency Track target project path to publish SBOM files to
      default: '$CI_PROJECT_PATH/$CI_PROJECT_NAME-{file_prefix}@{sbom_version}'
      default: '$CI_PROJECT_NAMESPACE//$CI_PROJECT_PATH-{file_prefix}@$CI_COMMIT_REF_NAME'
    path-separator:
      description: Separator to use in project path
      default: '/'
      default: '//'
    sbom-patterns:
      description: SBOM file patterns to publish (supports glob patterns)
      default: '**/*.cyclonedx.json **/*.cyclonedx.xml'