Python library for generating CycloneDX SBOMs

Overview

Python Library for generating CycloneDX

GitHub Workflow Status Python Version Support PyPI Version GitHub license GitHub issues GitHub forks GitHub stars


This CycloneDX module for Python can generate valid CycloneDX bill-of-material document containing an aggregate of all project dependencies.

This module is not designed for standalone use. If you're looking for a CycloneDX tool to run to generate (SBOM) software bill-of-materials documents, why not checkout:

Additionally, the following tool can be used as well (and this library was written to help improve it)

Additionally, you can use this module yourself in your application to programmatically generate SBOMs.

CycloneDX is a lightweight BOM specification that is easily created, human-readable, and simple to parse.

Installation

Install from pypi.org as you would any other Python module:

pip install cyclonedx-python-lib

Architecture

This module break out into three key areas:

  1. Parser: Use a parser that suits your needs to automatically gather information about your environment or application
  2. Model: Internal models used to unify data from different parsers
  3. Output: Choose and configure an output which allows you to define output format as well as the CycloneDX schema version

Parsing

You can use one of the parsers to obtain information about your project or environment. Available parsers:

Parser Class / Import Description
Environment from cyclonedx.parser.environment import EnvironmentParser Looks at the packaged installed in your current Python environment.
PoetryParser from cyclonedx.parser.poetry import PoetryParser Parses poetry.lock content passed in as a string.
PoetryFileParser from cyclonedx.parser.poetry import PoetryFileParser Parses the poetry.lock file at the supplied path.
RequirementsParser from cyclonedx.parser.requirements import RequirementsParser Parses a multiline string that you provide that conforms to the requirements.txt PEP-508 standard.
RequirementsFileParser from cyclonedx.parser.requirements import RequirementsFileParser Parses a file that you provide the path to that conforms to the requirements.txt PEP-508 standard.

Example

from cyclonedx.parser.environment import EnvironmentParser

parser = EnvironmentParser()

Modelling

You can create a BOM Model from either an Parser instance or manually using the methods avaialbel directly on the Bom class.

Example from a Parser

from cyclonedx.model.bom import Bom
from cyclonedx.parser.environment import EnvironmentParser

parser = EnvironmentParser()
bom = Bom.from_parser(parser=parser)

Generating Output

Once you have an instance of a Bom you can produce output in either JSON or XML against any of the supporting CycloneDX schema versions as you require.

We provide two helper methods:

  1. Output to string (for you to do with as you require)
  2. Output directly to a filename you provide
Example as JSON
from cyclonedx.output import get_instance, OutputFormat

outputter = get_instance(bom=bom, output_format=OutputFormat.JSON)
outputter.output_as_string()
Example as XML
from cyclonedx.output import get_instance, SchemaVersion

outputter = get_instance(bom=bom, schema_version=SchemaVersion.V1_2)
outputter.output_to_file(filename='/tmp/sbom-v1.2.xml')

Schema Support

This library is a work in progress and complete support for all parts of the CycloneDX schema will come in future releases.

Here is a summary of the parts of the schema supported by this library:

Note: We refer throughout using XPath, but the same is true for both XML and JSON output formats.

XPath Support v1.3 Support v1.2 Support v1.1 Support v1.0 Notes
/bom Y Y Y Y This is the root element and is supported with all it's defined attributes.
/bom/metadata Y Y N/A N/A Only timestamp is currently supported
/bom/components Y Y Y Y  
/bom/components/component
./author Y Y N/A N/A  
./name Y Y Y Y  
./version Y Y Y Y  
./purl Y Y Y Y  

Notes on Schema Support

  1. N/A is where the CycloneDX standard does not include this
  2. If the table above does not refer to an element, it is not currently supported

Python Support

We endeavour to support all functionality for all current actively supported Python versions. However, some features may not be possible/present in older Python versions due to their lack of support.

Changelog

See our CHANGELOG.

Copyright & License

CycloneDX Python Lib is Copyright (c) OWASP Foundation. All Rights Reserved.

Permission to modify and redistribute is granted under the terms of the Apache 2.0 license.

Comments
  • Can some of the runtime dependencies be loosened?

    Can some of the runtime dependencies be loosened?

    Thanks for this!

    I know poetry makes it easy lock every little thing down, and it makes testing easier, higher assurance, yadda yadda, but practically, it's quite inflexible when the effective ranges are very small... and on a self-declared lib to boot.

    Specifically, hooray for declaring a setuptools dependency: so many pkgutils-using packages forget to.

    However the size of the range covered by setuptools ^50.3.2 makes it relatively hard to appease (as in: exactly 1 version).

    Selfishly, this is blocking me downstream in packaging this and ultimately jake 1.x for conda-forge.

    The same goes for importlib_metadata which unfortunately gets pinned in a number of packages, and seems to change a lot for a backport package.

    Anyhow: would the maintainers be open to a PR that:

    • loosened the range of e.g. setuptools to be something more like >=50.3.2,<59
    • added a CI test excursion for the lowest and highest bound

    In the meantime, I may try patching the pin over on conda-forge and running the full test suite...

    enhancement dependencies 
    opened by bollwyvl 23
  • 2.5.0 regression: `SortedSet` assumes comparability of members, but `Vulnerability` model is not comparable

    2.5.0 regression: `SortedSet` assumes comparability of members, but `Vulnerability` model is not comparable

    Hi there! Thanks a ton for this library.

    We currently use it to generate SBOMs in pip-audit, and I noticed an interested regression upon upgrading to 2.5.0: it looks like Component.add_vulnerability attempts to add the underlying Vulnerability model to a SortedSet, which in turn fails because Vulnerability doesn't appear to implement the standard comparable operators (e.g. __lt__).

    Here's the failing code on our side, which worked in 2.4.0:

            for (dep, vulns) in result.items():
                if dep.is_skipped():
                    continue
                dep = cast(service.ResolvedDependency, dep)
    
                c = Component(name=dep.name, version=str(dep.version))
                for vuln in vulns:
                    c.add_vulnerability(
                        Vulnerability(
                            id=vuln.id,
                            description=vuln.description,
                            recommendation="Upgrade",
                        )
                    )
    
                self._components.append(c)
    

    and the failing CI tests on 2.5.0: https://github.com/trailofbits/pip-audit/runs/6832431942?check_suite_focus=true

    In my estimation, this looks like a bug/regression, rather than a SemVer breakage -- the Vulnerability model also comes from CycloneDX, so it probably should have been made comparable at the same time that comparability was assumed by introducing SortedSet.

    xref https://github.com/trailofbits/pip-audit/pull/292

    opened by woodruffw 17
  • [FEATURE] Support for version 1.4 schema

    [FEATURE] Support for version 1.4 schema

    Creating issue to track adoption of the forthcoming version 1.4 schema specification for CycloneDX.

    Preview work can be seen here, but this IS NOT FINAL.

    Current estimates are that version 1.4 will be finalised late 2021, early 2022.

    enhancement schema 1.4 
    opened by madpah 14
  • feat: use `SortedSet` in model to improve reproducibility

    feat: use `SortedSet` in model to improve reproducibility

    Added __lt__() to all model classes used in SortedSet, with tests Explicitly declared Enums as (str, Enum) to allow sorting Added dependency to sortedcollections package Added ComparableTuple to make sorting compound objects easier

    Signed-off-by: Rodney Richardson [email protected]

    opened by RodneyRichardson 11
  • [BUG] Nested Components or Services breaks BOM validation

    [BUG] Nested Components or Services breaks BOM validation

    The schema documents suggest that components can be nested inside other components (i.e. for/with hierarchical merging).

    Hoewever, if I try to generate such a bom an exception is raised in the validate method here: https://github.com/CycloneDX/cyclonedx-python-lib/blob/6e12be70fb2a71de60428155b4d0ae82fa43ef2d/cyclonedx/model/bom.py#L384 The reason for that is, because nested bom_refs underneath other components are not found by the implementation inside validate.

    Am I misunderstanding the schema or is this missing from the validation?

    bug 
    opened by peschuster 9
  • [FEATURE]  option to generate reproducible output

    [FEATURE] option to generate reproducible output

    I would like the tool to create exactly the same output if I run it on the same (Pipfile.lock) input file twice. This would make it easier to detect changes over time.

    There are several places where the outputs differ:

    1. The bom-ref is a GUID, newly generated on each run. This could be the purl (as cyclonedx-dotnet appears to do).
    2. The order of externalReferences is not maintained.
    3. The order of components/libraries is not maintained.
    enhancement 
    opened by RodneyRichardson 9
  • feat(deps): remove unused `typing-extensions` constraints

    feat(deps): remove unused `typing-extensions` constraints

    To be able to use new types, which will be introduced in Python 3.11, the package version shouldn't be pinned to 3.10.x and the package can be installed with any Python version, because you can't know, what the user will use. Here is the official explanation on version pinning

    Starting with version 4.0.0, typing_extensions uses Semantic Versioning. The major version is incremented for all backwards-incompatible changes. Therefore, it’s safe to depend on typing_extensions like this: typing_extensions >=x.y, <(x+1), where x.y is the first version that includes all features you need.

    opened by gruebel 9
  • fix: type hint for get_component_by_purl is incorrect

    fix: type hint for get_component_by_purl is incorrect

    Signed-off-by: gruebel [email protected]

    • adjusted the type hint for get_component_by_purl and added a test for it 🙂
    • changed the list/filter expression to use a list comprehension, which is almost 2x faster in this case 🚀
    bug 
    opened by gruebel 8
  • [FEATURE] SPDX License factory

    [FEATURE] SPDX License factory

    have a license factory, a thing that i feed a string and that returns the appropriate license model: expression, named license, spdx license.

    required for

    • https://github.com/CycloneDX/cyclonedx-python/discussions/377
    • https://github.com/CycloneDX/cyclonedx-python/issues/378

    as a contrast implementation of https://github.com/CycloneDX/cyclonedx-python/pull/410

    solution ala

    • https://github.com/CycloneDX/cyclonedx-javascript-library/blob/main/src/factories/license.ts
    • https://github.com/CycloneDX/cyclonedx-php-library/blob/master/src/Core/Factories/LicenseFactory.php
    enhancement 
    opened by jkowalleck 7
  • Documentation is failing to build and publish since #93 was merged

    Documentation is failing to build and publish since #93 was merged

    See https://github.com/CycloneDX/cyclonedx-python-lib/runs/4595932920?check_suite_focus=true.

    This appears to be the case since #93 was merged.

    FYI: @jkowalleck

    documentation CI 
    opened by madpah 7
  • feat: add option to assign a UUID in `BOM` constructor

    feat: add option to assign a UUID in `BOM` constructor

    Mainly the BOM receives a newly generated uuid assigned on the fly. This is basically a fix to enable passing an optional parameter within the constructor to be used as the uuid.

    enhancement 
    opened by hakandilek 6
  • chore(deps): bump Gr1N/setup-poetry from 7 to 8

    chore(deps): bump Gr1N/setup-poetry from 7 to 8

    Bumps Gr1N/setup-poetry from 7 to 8.

    Release notes

    Sourced from Gr1N/setup-poetry's releases.

    v8

    • Action updated to use Node 16
    • Support for Python 3.10 and 3.11
    • Breaking Change, removed support for Python 3.6
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • feat: add support for python 3.11

    feat: add support for python 3.11

    the library supports python 3.11 in general.

    • [ ] add py 311 support to tox
    • [ ] add py 311 support to GH workflows
    • [ ] add py 311 support to trove classifiers
    documentation enhancement CI CT 
    opened by jkowalleck 0
  • chore(deps): bump relekang/python-semantic-release from 7.31.2 to 7.32.2

    chore(deps): bump relekang/python-semantic-release from 7.31.2 to 7.32.2

    Bumps relekang/python-semantic-release from 7.31.2 to 7.32.2.

    Release notes

    Sourced from relekang/python-semantic-release's releases.

    v7.32.2

    Fix

    • Fix changelog generation in tag-mode (#171) (482a62e)

    Documentation

    v7.32.1

    Fix

    • Corrections for deprecation warnings (#505) (d47afb6)

    Documentation

    v7.32.0

    Feature

    • Add setting for enforcing textual changelog sections (#502) (988437d)

    Documentation

    • Correct documented default behaviour for commit_version_number (#497) (ffae2dc)

    v7.31.4

    Fix

    • Account for trailing newlines in commit messages (#495) (111b151)

    v7.31.3

    Fix

    • Use commit_subject when searching for release commits (#488) (3849ed9)
    Changelog

    Sourced from relekang/python-semantic-release's changelog.

    v7.32.2 (2022-10-22)

    Fix

    • Fix changelog generation in tag-mode (#171) (482a62e)

    Documentation

    v7.32.1 (2022-10-07)

    Fix

    • Corrections for deprecation warnings (#505) (d47afb6)

    Documentation

    v7.32.0 (2022-09-25)

    Feature

    • Add setting for enforcing textual changelog sections (#502) (988437d)

    Documentation

    • Correct documented default behaviour for commit_version_number (#497) (ffae2dc)

    v7.31.4 (2022-08-23)

    Fix

    • Account for trailing newlines in commit messages (#495) (111b151)

    v7.31.3 (2022-08-22)

    Fix

    • Use commit_subject when searching for release commits (#488) (3849ed9)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • The resolves entries of a Patch object are not serialized to XML

    The resolves entries of a Patch object are not serialized to XML

    When a BOM is created that has Patch objects with a non empty resolves property, the Issues are ignored and do not appear in the output.

    The resolves property stored in a ReleaseNote object is already correctly serialized, so it is just a matter of some code reuse.

    See: https://github.com/CycloneDX/cyclonedx-python-lib/pull/312 for a patch and test.

    opened by schlenk 0
Releases(v3.1.1)
Owner
CycloneDX SBOM Standard
CycloneDX is a lightweight Software Bill of Materials (SBOM) standard, purpose-built for cybersecurity use cases. CycloneDX is a OWASP Flagship Project.
CycloneDX SBOM Standard
A simple and convenient build-and-run system for C and C++.

smake Smake is a simple and convenient build-and-run system for C and C++ projects. Why make another build system? CMake and GNU Make are great build

Venkataram Edavamadathil Sivaram 18 Nov 13, 2022
ThinkPHP全日志扫描工具,命令行版和BurpSuite插件版

ThinkPHP3和5日志扫描工具,提供命令行版和BurpSuite插件版,尽可能全的发掘网站日志信息 命令行版 安装 git clone https://github.com/r3change/TPLogScan.git cd TPLogScan/ pip install -r requireme

119 Dec 27, 2022
Blender addon for executing the operator in response to the received OSC message.

I/F Joiner 受信したOSCメッセージに応じてオペレータ(bpy.ops)を実行するアドオンです. OSC通信に対応したコントローラやアプリをインストールしたスマートフォンを使用してBlenderを操作することが可能になります. 同時開発しているAndroidコントローラ化アプリMocopa

simasimataiyo 6 Oct 02, 2022
This suite consists of two different scripts, made to automate attacks against NoSQL databases.

NoSQL-Attack-Suite This suite consists of two different scripts, made to automate attacks against NoSQL databases. The first one looks for a NoSQL Aut

16 Dec 26, 2022
Combines power of torch, numerical methods to conquer and solve ALL {O,P}DEs

torch_DE_solver Combines power of torch, numerical methods and math overall to conquer and solve ALL {O,P}DEs There are three examples to provide a li

Natural Systems Simulation Lab 28 Dec 12, 2022
Reproducible nvim completion framework benchmarks.

Nvim.Bench Reproducible nvim completion framework benchmarks. Runs inside Docker. Fair and balanced Methodology Note: for all "randomness", they are g

i love my dog 14 Nov 20, 2022
python scripts and other files to generate induction encoder PCBs in Kicad

induction_encoder python scripts and other files to generate induction encoder PCBs in Kicad Targeting the Renesas IPS2200 encoder chips.

Taylor Alexander 8 Feb 16, 2022
Placeholders is a single-unit storage solution for your Frontend.

Placeholder Placeholders is a single-unit file storage solution for your Frontend. Why Placeholder? Generally, when a website/service requests for fil

Tanmoy Sen Gupta 1 Nov 09, 2021
Subcert is an subdomain enumeration tool, that finds all the subdomains from certificate transparency logs.

Subcert Subcert is a subdomain enumeration tool, that finds all the valid subdomains from certificate transparency logs. Table of contents Setup Demo

A3h1nt 59 Dec 16, 2022
Customisable coding font with alternates, ligatures and contextual positioning

Guide Ligature Support Links Log License Guide Live Preview + Download larsenwork.com/monoid Install Quit your editor/program. Unzip and open the fold

Andreas Larsen 7.6k Dec 30, 2022
validation for pre-commit.ci configuration

pre-commit-ci-config validation for pre-commit.ci configuration installation pip install pre-commit-ci-config api pre_commit_ci_config.SCHEMA a cfgv s

pre-commit.ci 17 Jul 11, 2022
A pairs trade is a market neutral trading strategy enabling traders to profit from virtually any market conditions.

A pairs trade is a market neutral trading strategy enabling traders to profit from virtually any market conditions. This strategy is categorized as a statistical arbitrage and convergence trading str

Kanupriya Anand 13 Nov 27, 2022
🤞 Website-Survival-Detection

- 🤞 Website-Survival-Detection It can help you to detect the survival status of the website in batches and return the status code! - 📜 Instructions

B0kd1 4 Nov 14, 2022
Visualize Data From Stray Scanner https://keke.dev/blog/2021/03/10/Stray-Scanner.html

StrayVisualizer A set of scripts to work with data collected using Stray Scanner. Usage Installing Dependencies Install dependencies with pip -r requi

Kenneth Blomqvist 45 Dec 30, 2022
A Python program for calculating the 95%CI for GNSS-derived site velocities

GNSS_Vel_95%CI A Python program for calculating the 95%CI for GNSS-derived site velocities Function_GNSS_95CI.py is a Python function for calculating

<a href=[email protected]"> 4 Dec 16, 2022
Collapse a set of redundant kmers to use IUPAC degenerate bases

kmer-collapse Collapse a set of redundant kmers to use IUPAC degenerate bases Overview Given an input set of kmers, find the smallest set of kmers tha

Alex Reynolds 3 Jan 06, 2022
Simple GUI menu for micropython using a rotary encoder and basic display.

Micropython encoder based menu This is a simple menu system written in micropython. It uses a switch, a rotary encoder and an OLED display.

80 Jan 07, 2023
A weekly dive into commonly used modules in the Rust ecosystem, with story flavor!

The goal of this project is to bring the same concept as PyMOTW to the Rust world. PyMOTW was an invaluable resource for me when I was learning Python years ago, and I hope that I can help someone in

Scott Lyons 20 Aug 26, 2022
🎴 LearnQuick is a flashcard application that you can study with decks and cards.

🎴 LearnQuick is a flashcard application that you can study with decks and cards. The main function of the application is to show the front sides of the created cards to the user and ask them to guess

Mehmet Güdük 7 Aug 21, 2022
CDM Device Checker for python

CDM Device Checker for python

zackmark29 79 Dec 14, 2022