# Third Party Software Vendoring Policy

This README explains the process of vendoring third-party libraries into the MongoDB server repository.

This policy applies to [github.com/mongodb/mongo](https://github.com/mongodb/mongo).

## Adding a new third-party library to the server

1. Fork the third-party library into [github.com/mongodb-forks](https://github.com/mongodb-forks).
    > **Note:** To track versions for vulnerabilities, forking a named version (e.g., `v2.0.1`) is required against forking a specific commit.
2. Pull the library from [github.com/mongodb-forks](https://github.com/mongodb-forks) into the `src/third_party` directory inside a folder named for the library being vendored.
3. Include the added library in `/sbom.json` under `components`. This will be verified by the linter in `buildscripts/sbom_linter.py`. For more detail, see the [SBOM](#sbom) section below.
4. Include a `scripts/import.sh` script inside the vendored library.
    > **Note:** A specific reference to the forked branch in [github.com/mongodb-forks](https://github.com/mongodb-forks) must be hardcoded. This helps developers understand and replicate the process used to vendor a specific library, facilitating maintenance.
5. Include a `VERSION=XYZ` line in the `scripts/import.sh` script (here `XYZ` indicates the version of the third party library).

## Updating a third-party library in the server to a new upstream version

1. Fork the new upstream version to the repo already created in [github.com/mongodb-forks](https://github.com/mongodb-forks).
2. Pull the forked version from [github.com/mongodb-forks](https://github.com/mongodb-forks) to the vendored library in `src/third_party`.
3. Update `src/third_party/<vendored-library>/scripts/import.sh` with the exact reference used.
4. Update `/sbom.json` with the new vendored version.
    > **Note:** Remember to update both the `version` and the `purl`.

## Modifying a third-party library in the server

1. Update the forked repo in [github.com/mongodb-forks](https://github.com/mongodb-forks).
2. Pull the updated fork to `src/third_party/<vendored-library>`.
3. Update the vendored commit hash in `src/third_party/<vendored-library>/scripts/import.sh`.

# SBOM

The `sbom.json` file in the root of the MongoDB repository contains key information about all the third party libraries that we use. It uses the CycloneDX 1.5 format.

Exhaustive documentation can be found at [https://cyclonedx.org/schema/](https://cyclonedx.org/schema/), this README is intended to describe our most common uses of fields. If your library does not easily fit the standard values below, please reach out to the Server Security team for assistance.

## Components

The top-level key "components" contains an array of third party components vendored in our repository. `component` objects have the following fields:

| Field Name | Description |
| --- | --- |
`name` | The name of the component.|
| `version` | The version of the component. The `import.sh` file created for the component should have a line like `VERSION=1.2.3` where the right side of the `=` matches this string.|
| `type` | The type of the component, such as library, application, framework, etc. For our vendored components, this will generally be `library`.|
| `purl` | Package URL. A URL that uniquely identifies the component and its version. This is a standard format that looks like `pkg:[type]/[packagename]@[version]`.|
| `supplier` | The source of the package, often correlated with the package type in the `purl`.
| `sbom-ref` | A UUID to identify the component, since all other fields are subject to change. Can be generated by running `uuidgen`.|
| `licenses` | Information about the licenses under which the component is used. For boilerplate licenses, this is the [SPDX license identifier](https://spdx.org/licenses/) for the license. This field also supports urls and text blobs.|
| `scope` | The intended usage scope of the component in MongoDB. If the binary is distributed with our software, this must be `required`. For components used only for testing, this should be `excluded`.|
| `evidence` | This contains an array of `occurences`,  which in turn contain `location` strings specifying the location of the component in our repo.|
| `properties` | Additional custom properties related to the component, see below.|

## Properties

Component objects contain a `properties` field that is used for adding our own proprietary information to the sbom. It is a key-value array, with each key being denoted by `name`, and each value being denoted by `value`. Potential keys here include the following:

| Field Name | Description |
| --- | --- |
| `internal:team_responsible` | The MongoDB team responsible for this library. The team name should match the string for the team in [mothra](https://github.com/10gen/mothra/blob/main/mothra/teams/database.yaml). |
| `emits_persisted_data` | This should be set to true if the component outputs persisted data to disk. This is important because in this case, updating the library could cause breakage due to the format of this data changing. |
| `info_link` | This is an informational link about the component. It is used to populate [README.third_party.md](/README.third_party.md) |
| `import_script_path` | The location of the script used to update the library to a new version. The standard location is `src/third_party/[componentdir]/scripts/import.sh`. |