Downloading SBOMs

You can use the API or SDK to download the SBOM for an Asset Version.

Check out SDK examples in our Github repo here!

Using the Python SDK

This script does the following:

  1. Calls generate_sbom_download_url using the asset_version_id, sbom_type, and sbom_subtype to initiate the SBOM generation. This is a blocking call that will return the URL to download the SBOM once it is ready.
  2. Once the download URL is returned, it sends an HTTP GET request to the URL and writes the content to a local file.
import finite_state_sdk
import requests

# Access the environment variables
CLIENT_ID = os.getenv('CLIENT_ID')
CLIENT_SECRET = os.getenv('CLIENT_SECRET')
ORGANIZATION_CONTEXT = os.getenv('ORGANIZATION_CONTEXT')

token = finite_state_sdk.get_auth_token(CLIENT_ID, CLIENT_SECRET)

asset_version_id = "1234567890"
sbom_type = "CYCLONEDX"  # can be "CYCLONEDX" or "SPDX" (SPDX supports "SBOM_ONLY")
sbom_subtype = "SBOM_ONLY"  # can be "SBOM_ONLY", "SBOM_WITH_VDR", or "VDR_ONLY"
url = finite_state_sdk.generate_sbom_download_url(token, organization_context, \
  sbom_type=sbom_type, sbom_subtype=sbom_subtype, asset_version_id=asset_version_id)

print(f'Got download url: {url}')

# Send an HTTP GET request to the URL
response = requests.get(url)

# Check if the request was successful (status code 200)
if response.status_code == 200:
    # Open a local file in binary write mode and write the content to it
    # or replace this code with something else to process the content
    print("File downloaded successfully.")
    output_filename = f'sbom.{sbom_type}.{sbom_subtype}.json'
    with open(output_filename, 'wb') as file:
        file.write(response.content)
        print(f'Wrote file to {output_filename}')
else:
    print("Failed to download the file. Status code:", response.status_code)

Using the API

  1. First, initiate the SBOM generation by calling launchCycloneDxExport mutation. This will return an exportJobId.
mutation LaunchCycloneDxExport($cdxSubtype: CycloneDxExportSubtype!, $assetVersionId: ID!) {
  launchCycloneDxExport(cdxSubtype: $cdxSubtype, assetVersionId: $assetVersionId) {
    exportJobId
  }
}
  1. Next, poll the generateExportDownloadPresignedUrl query using the exportJobId until the status is COMPLETED and the downloadLink is populated. This is usually very quick, but for very large SBOMs may take a minute or more.
query GenerateExportDownloadPresignedUrl($exportId: ID!) {
  generateExportDownloadPresignedUrl(exportId: $exportId) {
    downloadLink
    status
  }
}