CycloneDX BOM Repository Server

August 26, 2022 ยท View on GitHub

Test CI Docker Image License Website Slack Invite Group Discussion Twitter

CycloneDX BOM Repository Server

A BOM repository server for distributing CycloneDX BOMs.

You can test it out locally using Docker by running:

docker run --env ALLOWEDMETHODS__GET="true" --env ALLOWEDMETHODS__POST="true" --env ALLOWEDMETHODS__DELETE="true" --tty --interactive -p 8000:8080 cyclonedx/cyclonedx-bom-repo-server

Or, if you would like to persist BOM repository storage between runs by using local folder "bomstorage":

mkdir bomstorage
docker run --volume "$(pwd)/bomstorage":/repo --env ALLOWEDMETHODS__GET="true" --env ALLOWEDMETHODS__POST="true" --env ALLOWEDMETHODS__DELETE="true" --tty --interactive -p 8000:8080 cyclonedx/cyclonedx-bom-repo-server

then hit "http://localhost:8000/swagger" from browser

To build your own docker image

git clone github.com:CycloneDX/cyclonedx-bom-repo-server.git
cd cyclonedx-bom-repo-server
./build-and-run.sh

API Endpoints

The server supports Swagger/Open API Specification.

The JSON endpoint is /swagger/v1/swagger.json. The UI can be accessed at /swagger.

A summary of the available endpoints and methods are below:

PathHTTP MethodRequired ParametersOptional ParametersDescription
/v1/bomGETserialNumberversion, originalIf only the serialNumber parameter is supplied, retrieve the latest version of the BOM from the repository. If providing serialNumber and version, a specific version of the BOM will be retrieved. Supports HTTP content negotiation for all CycloneDX BOM formats and versions. If original is true, returns the original, unmodified BOM.
/v1/bomPOSTBOM content in request body and appropriate Content-Type headerAdds a new BOM to the repository. Supports all CycloneDX BOM formats and versions. If the submitted BOM does not have a serial number, one will be generated. If the BOM does not have a version the next version number will be added. The response will contain an appropriate Location header to reference the BOM in the repository.
/v1/bomDELETEserialNumberversionIf only the serialNumber parameter is supplied, all versions of the BOM will be deleted from the repository. If serialNumber and version are supplied, only the specific version will be deleted from the repository.
/v1/bomexchangeGETbomIdentifierInput valid serial number UUID URN or CDX URN to retrieve BOM.
/v1/bomexchangePOSTBOM content in request body and appropriate Content-Type headerAdds a new BOM to the repository. Supports all CycloneDX BOM formats and versions. If the submitted BOM does not have a serial number, one will be generated. If the BOM does not have a version the next version number will be added. The response will contain an appropriate Location header to reference the BOM in the repository.
/v1/searchGETOne of group, name, versionrest of group, name, versionRetrieve a list of BOM serial numbers and versions that match the supplied metadata component search criteria.

NOTE: BOM serial numbers should be unique for a particular device/software version. When updating an existing BOM for the same software version, the BOM serial number should remain the same, and the version number should be incremented. For this reason, updating an existing BOM version is not supported. There is, of course, nothing to prevent deleting an existing BOM version and re-publishing it with the same serial number and version. But this is not recommended.

Example cURL Usage

Retrieving a BOM from the repository

curl -X GET 'http://localhost:8000/v1/bom?serialNumber=urn%3Auuid%3A3e671687-395b-41f5-a30f-a58921a69b79' -H 'accept: application/vnd.cyclonedx+json; version=1.4'

Adding a new BOM to the repository

curl -X POST "http://localhost:8000/v1/bom" -H  "accept: */*" -H  "Content-Type: application/vnd.cyclonedx+json; version=1.4" -d "{\"bomFormat\":\"CycloneDX\",\"specVersion\":\"1.3\",\"serialNumber\":\"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79\",\"version\":1,\"components\":[{\"type\":\"library\",\"name\":\"acme-library\",\"version\":\"1.0.0\"}]}"

Deleting a BOM from the repository

curl -X DELETE 'http://localhost:8000/v1/bom/serialNumber=urn%3Auuid%3A3e671687-395b-41f5-a30f-a58921a69b79?version=1' -H 'accept: */*'

Configuration

The server can be configured by changing the src/CycloneDX.BomRepoServer/appsettings.json file or setting the following environment variables

Environment Variable NameSupported ValuesDescriptionDefault Value
REPO__DIRECTORYAny valid directory pathThe directory BOMs are storedRepo (set to \repo within the official Container since tbd)
ALLOWEDMETHODS__GETtrue or falseAllows or forbids BOM retrievalfalse
ALLOWEDMETHODS__POSTtrue or falseAllows or forbids BOM creationfalse
ALLOWEDMETHODS__DELETEtrue or falseAllows or forbids BOM deletionfalse
RETENTION__MAXBOMVERSIONSAny integer value >= 0The maximum number of BOM versions that will be retained. If zero, the number of BOM versions are ignored for retention.0
RETENTION__MAXBOMAGEAny integer value >= 0The maximum age of a BOM, in days, before it is removed. If zero, the BOM age is ignored for retention.0

Storage

The server storage type is configured under the Repo section. Currently we support the storage types FileSystem and S3 with options varying depending on the type.

...
"Repo": {
  "StorageType": "FileSystem",
  "Options": {
    "Directory": "Repo"
  }
}
...
...
"Repo": {
    "StorageType": "S3",
    "Options": {
      "Endpoint": "localhost:9000",
      "AccessKey": "bomserver-minioadmin",
      "SecretKey": "bomserver-minioadmin",
      "ForcePathStyle": true,
      "UseHttp": false,
      "BucketName": "bomserver"
  }
}
...

Authentication and Authorization

Authentication and authorization are expected to be configured at the web server or API gateway level.

For simplicity of deployment the allowed methods can be configured, and default to safe options (everything is forbidden by default).

It is recommended to deploy two instances of the BOM repository server.

One, requiring authentication and additional security controls, with GET and POST methods permitted to support publishing BOMs.

And a second instance, public facing, with only the GET method enabled. And authentication configured if required.

More advanced authentication and authorization use cases should be handled with a solution like an API gateway. And are considered out of scope of this project.

NOTE: It is recommended, subject to your operational environment and risk profile, to not require authentication for public facing instances. This enables downstream consumers, who might not have a direct commercial arrangement with your organization, to retrieve BOMs.

System Requirements

The CycloneDX BOM Repository Server has been designed as a lightweight, high performance, BOM repository server. Any production web server should be capable of running it.

However, there is an in memory cache of BOM metadata. Memory requirements will differ based on the amount of BOM metadata that requires caching.

All BOMs are converted to Protocol Buffer format before storage for efficiency.

As an alternative to the Docker image, the server can be hosted using Nginx, Apache, IIS, or Kestrel. More information can be found in the Web server implementations in ASP.NET Core documentation.

High Availability Deployments

The server supports sharing repository storage between multiple frontend instances. Which can be used for full active/active high availability clustering.

When deploying to multiple data centres it is recommended to have one master instance that supports publishing BOMs. And use data replication to any other target data centres used for distributing BOMs.

BOM Metadata Cache & Searching

To support high performance searching, there is an in memory cache of BOM metadata.

This cache is initially populated during startup and updated by a background thread every 10 minutes. For this reason, a newly published BOM may not immediately be returned in search results.