Client

BOMnipotent Client is a tool to interact with BOMnipotent Server. It can be used by consumers to download documents, or to request access. Server admins and managers on the other hand can use it to remotely modify the server database.

Feb 24, 2025

Subsections of Client

Basic Usage

This section covers the basics of using the BOMnipotent Client. It is relevant for both consumers and producers of supply chain security documents.

Feb 24, 2025

Subsections of Basic Usage

Installing the Client

To manually download BOMnipotent Client, go to https://www.bomnipotent.de/downloads/, select your platform and version, and click on the download button.

To automate this process further, you can access the download link directly:

Invoke-WebRequest -Uri https://www.bomnipotent.de/downloads/raw/latest/windows/bomnipotent_client.exe -OutFile bomnipotent_client.exe
curl -O https://www.bomnipotent.de/downloads/raw/latest/macos/bomnipotent_client
chmod +x bomnipotent_client
wget https://www.bomnipotent.de/downloads/raw/latest/debian-glibc/bomnipotent_client;
chmod +x bomnipotent_client
wget https://www.bomnipotent.de/downloads/raw/latest/linux-musl/bomnipotent_client;
chmod +x bomnipotent_client

Replace “latest” with a specific version tag, e.g. “v1.0.0”, to download that version instead of the latest.

To access BOMnipotent Client from anywhere in your system, move it into a folder that is included in your PATH environment variable. This step is optional, though.

Mar 16, 2025

Account Creation

Most interactions with BOMnipotent require some permission. The sole exception is accessing data classified as TLP:WHITE / TLP:CLEAR.

Permissions are linked to user accounts. For more information on how permissions are granted, see the section about Access Management.

Creating a new Account

To create a new user account, run

Input (long variant)
bomnipotent_client --domain=bomnipotent_server_of_your_choice user request user@example.com
Input (short variant)
bomnipotent_client -d bomnipotent_server_of_your_choice user request user@example.com
Output
[INFO] Generating new key pair.
[INFO] Storing secret key to '/root/.config/bomnipotent/secret_key.pem' and public key to '/root/.config/bomnipotent/public_key.pem'.
[INFO] User request submitted. A verification email has been sent to your inbox. The verification link expires after 1h.

If you call this for the first time, it will create a new key pair following the OpenPGP standard. A key pair consists of a public and a secret key. Both are stored in your local userfolder.

The secret key is more commonly called “private key”, but the author believes that “secret” is a more apt description and reduces the chance to confuse it with the public key.

The public key can, in principle, be shared with anyone. The “user request” call sends it to the BOMnipotent server. The secret key however should be treated like a password!

Subsequent calls to BOMnipotent Client will reuse an existing key pair.

Most BOMnipotent Server instances will require you to confirm that you have access to the provided email address. They will send you a verification link, which expires after some time.

If you missed the time window or something else went wrong, simply send the same request to the server again. It will then generate a new verification email for you:

Input (long variant)
bomnipotent_client --domain=bomnipotent_server_of_your_choice user request user@example.com
Input (short variant)
bomnipotent_client -d bomnipotent_server_of_your_choice user request user@example.com
Output
[INFO] User request re-submitted. A brand new verification email has been sent to your inbox. The verification link expires after 1h.

After your request is made and your email verified, you need to wait for a user manager of the server to approve your account. Once that happened you can start making authenticated requests.

If you are said user manager and are looking for how approve users, consult the section about User Management.

Using stored Keys

If you have a key pair stored in the default user location (which depends on your platform), BOMnipotent Client will automatically read and use it.

If you would instead like to reuse an existing key stored at a different location, you can add the path as a positional argument:

Input (long variant)
bomnipotent_client --domain=bomnipotent_server_of_your_choice user request other_user@example.com /home/keys/stored_public_key.pem
Input (short variant)
bomnipotent_client -d bomnipotent_server_of_your_choice user request other_user@example.com /home/keys/stored_public_key.pem
Output
[INFO] User request submitted. A verification email has been sent to your inbox. The verification link expires after 1h.

For this to work the key needs to follow the OpenPGP standard, and it needs to be stored in PEM format.

If you accidently specify the path to your secret key, BOMnipotent Client will throw an error before sending it to the server.

Aug 13, 2025

Authenticating

Authentication requires that you have requested a user account, and that it has been approved by a user manager.

Once your account (meaning your username and public key) is approved, you can provide your username to Bomnipotent Client to make a request that can be authenticated by the server:

Input (long variant)
bomnipotent_client --domain=<server> --user=<your-email> <command>
Input (short variant)
bomnipotent_client -d <server> -u <your-email> <command>

BOMnipotent Client then automatically reads your secret key and uses it for authentication.

Your secret key is used to cryptographically sign the HTTP method, your username, a timestamp and the request body. This simultaneously protects your request against others impersonating you, malicious modifications and replay attacks. The secret key achieves all that without ever having to leave your local computer, the beauty of which is, sadly, beyond the scope of this documentation.

If you are not storing your keys in the default user location, you have to tell BOMnipotent Client the path to it via a command line option:

Input (long variant)
bomnipotent_client --domain=bomnipotent_server_of_your_choice --user=<your-email> --secret-key=<path/to/key> <command>
Input (short variant)
bomnipotent_client -d bomnipotent_server_of_your_choice -u <your-email> -s <path/to/key> <command>

To avoid providing three extra arguments to every single request, you can instead store this data in a User Session.

Aug 10, 2025

User Session

Login

The BOMnipotent Client offers several global optional arguments. To avoid having to provide these time and time again, you can use the login command to store them in a user session. This will create a file in the local user folder which stores the provided parameters:

Input (long variant)
bomnipotent_client --domain=bomnipotent_server_of_your_choice --user=user@example.com --output-mode=normal --secret-key=/home/some_secret_key.pem session login
Input (short variant)
bomnipotent_client -d bomnipotent_server_of_your_choice -u user@example.com -o normal -s /home/some_secret_key.pem session login
Output
[INFO] Storing session data in /root/.config/bomnipotent/session.toml

Whenever you call the BOMnipotent Client from now on, it will use these parameters automatically.

Any relative filepaths you provide will be resolved to absolute paths before storing them. This way, the session data can be used from anywhere on your computer.

Overriding and Overwriting

If you are logged in and provide any of the global optional parameters to a BOMnipotent Client call, it will use these instead:

Input (long variant)
bomnipotent_client --domain=bomnipotent.wwh-soft.com health # Will contact the other server
Input (short variant)
bomnipotent_client -d bomnipotent.wwh-soft.com health # Will contact the other server
Output
[INFO] The service at https://bomnipotent.wwh-soft.com is healthy.

To permanently change the data stored in the session, simply login again with the new parameters.

This can also be used to remove parameters, simply by not providing them:

Input (long variant)
bomnipotent_client --domain=some_other_bomnipotent_server --user=other_user@example.com session login # Will set secret-key and other non-specified options to none.
Input (short variant)
bomnipotent_client -d some_other_bomnipotent_server -u other_user@example.com session login # Will set secret-key and other non-specified options to none.
Output
[INFO] Storing session data in /root/.config/bomnipotent/session.toml

Status

To print the current parameters of your session, call “session status”. The output is in TOML format (which is also how it is stored on your filesystem):

Input
bomnipotent_client session status
Output
domain = "bomnipotent_server_of_your_choice"
user = "user@example.com"
output_mode = "Normal"
secret_key_path = "/home/some_secret_key.pem"

If you prefer JSON, merely append the “json” option:

Input (long variant)
bomnipotent_client session status --json
Input (short variant)
bomnipotent_client session status -j
Output
{
  "domain": "bomnipotent_server_of_your_choice",
  "user": "user@example.com",
  "output_mode": "Normal",
  "secret_key_path": "/home/some_secret_key.pem"
}

If you are not logged in, you get an informational log and an empty TOML/JSON output:

Input
bomnipotent_client session status
Output
[INFO] No session data is currently stored
Input (long variant)
bomnipotent_client session status --json
Input (short variant)
bomnipotent_client session status -j
Output
[INFO] No session data is currently stored
{}

If you would like to use this command to programatically check if session data exists, you can for example use the “raw” output mode to avoid the info trace, and check if the return value is empty:

#!/bin/bash

output=$(bomnipotent_client --output-mode raw session status)
if [ -n "$output" ]; then
    echo "Found session data:"
    echo "$output"
else
    echo "Session not logged in."
fi
$output = bomnipotent_client --output-mode raw session status
if ($output) {
    Write-Output "Found session data:"
    Write-Output $output
} else {
    Write-Output "Session not logged in."
}

Logout

To remove all parameters, call logout:

Input
bomnipotent_client session logout
Output
[INFO] Deleting session data at '/root/.config/bomnipotent/session.toml'.

This will remove the session file.

Aug 10, 2025

Log Level

BOMnipotent Client offers several severity levels of logs:

  • error
  • warn
  • info (default)
  • debug
  • trace

They can be selected via:

Input (long variant)
bomnipotent_client --log-level=<LEVEL> <COMMAND>
Input (short variant)
bomnipotent_client -l <LEVEL> <COMMAND>

This defines the minimum severity level for a message to be logged: Choosing log level debug makes BOMnipotent print all messages of severity error, warn, info and debug, but not trace.

By default, BOMnipotent Client logs messages to stdout, regardless of severity level. You can instruct it to log to a file instead.

Info, Warn and Error

The default log-level is info. It prints some information, but does not overwhelm the user.

Input
bomnipotent_client health
Output
[INFO] The service at https://bomnipotent_server_of_your_choice is healthy.
Input
bomnipotent_client bom list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product                โ”‚ Version โ”‚ Timestamp               โ”‚ TLP       โ”‚ Components โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Project           โ”‚ 3.1.4   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ TLP:GREEN โ”‚ 75         โ”‚
โ”‚ Your Project           โ”‚ 1.0.0   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ Default   โ”‚ 75         โ”‚
โ”‚ Your Project           โ”‚ 1.1.0   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ Default   โ”‚ 75         โ”‚
โ”‚ Your Project Container โ”‚ 1.2.3   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ TLP:WHITE โ”‚ 939        โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Debug

The debug output mode prints some additional information which may be of interest when looking for the cause of an error in the input or setup:

Input (long variant)
bomnipotent_client --log-level=debug health | tail -n 10
Input (short variant)
bomnipotent_client -l debug health | tail -n 10
Output
[DEBUG] TLS1.3 encrypted extensions: ServerExtensions { server_name_ack: (), unknown_extensions: {}, .. }
[DEBUG] ALPN protocol is None
[DEBUG] add_parsable_certificates processed 143 valid and 0 invalid certs
[DEBUG] Loaded 143 CA certificates from the system
[DEBUG] Call<RecvResponse>
[DEBUG] Call<RecvBody>
[DEBUG] Response { status: 200, version: HTTP/1.1, headers: {"content-type": "text/plain; charset=utf-8", "content-length": "68", "date": "Wed, 01 Jan 2025 10:11:12 GMT", "<NOTICE>": "2 HEADERS ARE REDACTED"} }
[DEBUG] Call<Cleanup>
[DEBUG] Pool gone: PoolKey { scheme: "https", authority: bomnipotent_server_of_your_choice, proxy: None }
[INFO] The service at https://bomnipotent_server_of_your_choice is healthy.

Trace

In output mode trace, BOMnipotent prints everything it finds even the slightest bit interesting. This is mainly useful for finding the cause of an error in the program itself.

Input (long variant)
bomnipotent_client --log-level=trace health | grep "TRACE" | head -n 10
Input (short variant)
bomnipotent_client -l trace health | grep "TRACE" | head -n 10
Output
[TRACE] Running command Health with args Arguments {
[TRACE] Using platform's default root certificates.
[TRACE] Armored signature:
[TRACE] Resolve: bomnipotent_server_of_your_choice:443
[TRACE] Try connect TcpStream to 172.20.0.3:443
[TRACE] Try wrap in TLS
[TRACE] Sending ClientHello Message {
[TRACE] 4745 5420 2f68 6561 6c74 6820 4854 5450  GET./health.HTTP
[TRACE] 2f31 2e31 0d0a 6163 6365 7074 3a20 2a2f  /1.1..accept:.*/
[TRACE] 2a0d 0a68 6f73 743a 2062 6f6d 6e69 706f  *..host:.bomnipo
Jul 18, 2025

Log File

To store the log output of a call to BOMnipotent Client in a file instead of printing it to stdout, call

Input (long variant)
bomnipotent_client --log-file=/tmp/bomnipotent.log bom list
Input (short variant)
bomnipotent_client -f /tmp/bomnipotent.log bom list

The output is the same, except that the stdout output is coloured according to its severity level, while the file output is not.

If BOMnipotent Client is called repeatedly with the same log-file, it will overwrite the existing contents, if the existing file looks like a log-file.

A file looks like a log-file to BOMnipotent if it is either empty or contains at least one of the strings “[ERROR]”, “[WARN]”, “[INFO]”, “[DEBUG]” or “[TRACE]”.

If an existing file does not look like a log-file, BOMnipotent gets cautious and aborts:

Input (long variant)
bomnipotent_client --log-file=/home/george_r_r_martin_not_a.log bom list
Input (short variant)
bomnipotent_client -f /home/george_r_r_martin_not_a.log bom list
Output
Failed to set log target: Log-file "/home/george_r_r_martin_not_a.log" already exists and does not look like a log-file. Aborting before overwriting any data you do not want overwritten.

Because the commands “bom get” / “csaf get” as well as the “fetch” command are meant for machine-processing, they print their output to stdout even if a log-file is configured. This separation of outputs makes it possible to simultaneously process the data and store potential error messages.

Jun 16, 2025

Output Mode

Withouth any specifications of the output-mode, BOMnipotent Client prints its log messages either to stdout, or to a configured log-file. This is great if it used by humans, but not so useful for automation. This is why BOMnipotent Client offers the two additional output-modes “code” and “raw”. They modify which output is printed where.

Output Streams

In output-modes “code” or “raw”, only the HTTP code or the response body are printed to stdout. If you configure a log-file, any logs up to the specified log-level will be stored there.

If on the other hand you do not specify a log-file, BOMnipotent still wants you to know if something goes wrong. This is why, in this case, logs of severity “error” or “warn” are printed to stderr.

Modes

Code

The code output prints only the HTTP status code of the response to stdout.

Input (long variant)
bomnipotent_client --output-mode=code health
Input (short variant)
bomnipotent_client -o code health
Output
200

This can come in handy if you want to use BOMnipotent Client in a script:

#!/bin/bash
set -e # Return on error
# ...other code...
bomnipotent_client \
    --output-mode=code \
    --domain=$domain \
    --log-level=debug \
    --log-file="/tmp/loggy.log" \
    session login
code=$(bomnipotent_client health)
if (( code != 200 )); then
    echo "Server at $domain is not healthy!"
    cat /tmp/loggy.log
    exit 1;
fi

Note that there is no newline or carriage return character at the end of the output.

Attention: In code mode, BOMnipotent Client always exits with a terminal exit code of 0 (signaling success) if it can obtain any HTTP code. This way, the program is easier to use inside scripts that return on errors.

Raw

For calls to BOMnipotent Client that access some structured data, the raw output prints the response body, which is typically data in JSON format.

Input (long variant)
bomnipotent_client --output-mode=raw bom list
Input (short variant)
bomnipotent_client -o raw bom list
Output
[{"product":"Best Project","version":"3.1.4","timestamp":"2025-01-01T10:11:12Z","tlp":"TLP:GREEN","components":75},{"product":"Your Project","version":"1.0.0","timestamp":"2025-01-01T10:11:12Z","tlp":null,"components":75},{"product":"Your Project","version":"1.1.0","timestamp":"2025-01-01T10:11:12Z","tlp":null,"components":75},{"product":"Your Project Container","version":"1.2.3","timestamp":"2025-01-01T10:11:12Z","tlp":"TLP:WHITE","components":939}]

The output can then easily be parsed and processed by your program logic.

Note that there is no newline or carriage return character at the end of the output.

Jun 16, 2025

For Consumers

This section covers typical use cases for consumers of supply chain security documents. In this context, “consumer” refers to a person or automation that has reading access (limited or unrestricted) to BOMs, vulnerabilities or CSAF documents.

Feb 24, 2025

Subsections of For Consumers

BOMs

Bills of Materials stand at the forefront of both BOMnipotents functionality and name. A BOM is a list of all components that make up a product. In the context of cybersecurity, the most prominent variant is the Software Bill of Materials (SBOM), but BOMs allow for more general considerations as well.

List

Running the following command will list all BOMs accessible to you:

Input
bomnipotent_client bom list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product                โ”‚ Version โ”‚ Timestamp               โ”‚ TLP       โ”‚ Components โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Project           โ”‚ 3.1.4   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ TLP:GREEN โ”‚ 75         โ”‚
โ”‚ Your Project           โ”‚ 1.0.0   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ Default   โ”‚ 75         โ”‚
โ”‚ Your Project           โ”‚ 1.1.0   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ Default   โ”‚ 75         โ”‚
โ”‚ Your Project Container โ”‚ 1.2.3   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ TLP:WHITE โ”‚ 939        โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

BOMs with label TLP:WHITE / TLP:CLEAR are visible to everyone. In this example, your account has access to one BOM with label TLP:AMBER.

The command accepts the optional filters “name” and “version”:

Input (long variant)
bomnipotent_client bom list --name="Your Project" --version="1.0.0"
Input (short variant)
bomnipotent_client bom list -n "Your Project" -v "1.0.0"
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product      โ”‚ Version โ”‚ Timestamp               โ”‚ TLP     โ”‚ Components โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Your Project โ”‚ 1.0.0   โ”‚ 2025-01-01 10:11:12 UTC โ”‚ Default โ”‚ 75         โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Download

To create a local copy of all boms the server exposes to you, run:

Input
bomnipotent_client bom download /home/boms
Output
[INFO] Storing BOMs under '/home/boms'.

This will store the BOMs in the provided folder ("./boms", in this example). It will create the folder structure if it does not already exist. The BOMs are stored in files following the naming scheme {product name}_{product version}.cdx.json.

To avoid inconsistent behaviour accross operating systems, the name and version of the product are converted into lowercase, and most special characters are replaced by an underscore ‘_’. This means that, in principle, different products could lead to the same filename. In that case, BOMnipotent will display a warning instead of silently overwriting a file.

The client also downloads several files containing a hash and the filename of the hashed file.

If OpenPGP is configured on the server, the client furthermore downloads cryptografic signatures for the BOMs. They are saved in “.json.asc” files, and can for example be verified using Sequoia-PGP.

Input
tree /home/boms/
Output
/home/boms/
|-- best_project_3.1.4.cdx.json
|-- best_project_3.1.4.cdx.json.asc
|-- best_project_3.1.4.cdx.json.sha256
|-- best_project_3.1.4.cdx.json.sha512
|-- your_project_1.0.0.cdx.json
|-- your_project_1.0.0.cdx.json.asc
|-- your_project_1.0.0.cdx.json.sha256
|-- your_project_1.0.0.cdx.json.sha512
|-- your_project_1.1.0.cdx.json
|-- your_project_1.1.0.cdx.json.asc
|-- your_project_1.1.0.cdx.json.sha256
|-- your_project_1.1.0.cdx.json.sha512
|-- your_project_container_1.2.3.cdx.json
|-- your_project_container_1.2.3.cdx.json.asc
|-- your_project_container_1.2.3.cdx.json.sha256
`-- your_project_container_1.2.3.cdx.json.sha512

1 directory, 16 files

Before requesting files for download, BOMnipotent Client makes an inventory of the BOMs already present in the folder, and downloads only the missing ones.

BOMnipotent does not automatically replace existing files, even if they have changed on the server. It instead prints a warning message:

Input
bomnipotent_client bom download /home/boms
Output
[INFO] Storing BOMs under '/home/boms'.
[WARN] File '/home/boms/best_project_3.1.4.cdx.json' already exists.
The existing BOM doc has name 'BEST%PROJECT' and version '3.1.4' while the new one has name 'Best Project' and version '3.1.4'.
Note that to avoid shenangians with the filesystem, both are mapped to the same filename 'best_project_3.1.4.cdx.json'.
Skipping download to prevent data loss.

You can tell BOMnipotent that you really want this file overwritten by using the “overwrite” flag:

Input (long variant)
bomnipotent_client bom download /home/boms --overwrite
Input (short variant)
bomnipotent_client bom download /home/boms -o
Output
[INFO] Storing BOMs under '/home/boms'.
[INFO] Overwriting existing BOM document at '/home/boms/best_project_3.1.4.cdx.json'.

Analogously to the list command, the download command accepts the filters “name” and “version”, to only download a subset of BOMs:

Input (long variant)
bomnipotent_client bom download /home/boms --name="Your Project" --version="1.0.0"
Input (short variant)
bomnipotent_client bom download /home/boms -n "Your Project" -v "1.0.0"
Output
[INFO] Storing BOMs under '/home/boms'.

Get

You can directly display the contents of a single BOM to the console output by calling

Input
bomnipotent_client bom get "Your Project" "1.0.0" | grep -v "serialNumber" | head -n 16
Output
{
  "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "version": 1,
  "metadata": {
    "timestamp": "2025-01-01T10:11:12Z",
    "tools": {
      "components": [
        {
          "type": "application",
          "author": "anchore",
          "name": "syft",
          "version": "1.30.0"
        }
      ]

This is especially useful if you want to use the contents of this BOM in a script. For example, to check for vulnerabilities in the supply chain, you could call:

Input
bomnipotent_client bom get "Your Project" "1.0.0" | grype
Output
NAME    INSTALLED  FIXED IN  TYPE        VULNERABILITY        SEVERITY  EPSS  RISK  
rustls  0.23.15    0.23.18   rust-crate  GHSA-qg5g-gv98-5ffh  Medium    N/A   N/A

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client bom exist --name="Your Project" --version="1.0.0"
Input (short variant)
bomnipotent_client bom exist -n "Your Project" -v "1.0.0"
Output
[INFO] The server contains 1 BOM(s) matching the filters.
Aug 13, 2025

Components

The purpose of a Bill of Materials is to catalogue components of a product. BOMnipotent Client can be used to list all packages etc. contained in any product that is accessible to your user account. Simply call the client with the arguments “component”, “list”, and then name and version of the product:

Input
bomnipotent_client component list "Your Project" "1.0.0" | awk 'NR <= 16'
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Name                       โ”‚ Version                    โ”‚ Type    โ”‚ CPE                        โ”‚ PURL                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /home/your_project/Cargo.l โ”‚                            โ”‚ file    โ”‚                            โ”‚                            โ”‚
โ”‚ ock                        โ”‚                            โ”‚         โ”‚                            โ”‚                            โ”‚
โ”‚ aho-corasick               โ”‚ 1.1.3                      โ”‚ library โ”‚ cpe:2.3:a:aho-corasick:aho โ”‚ pkg:cargo/aho-corasick@1.1 โ”‚
โ”‚                            โ”‚                            โ”‚         โ”‚ -corasick:1.1.3:*:*:*:*:*: โ”‚ .3                         โ”‚
โ”‚                            โ”‚                            โ”‚         โ”‚ *:*                        โ”‚                            โ”‚
โ”‚ aws-lc-rs                  โ”‚ 1.13.1                     โ”‚ library โ”‚ cpe:2.3:a:aws-lc-rs:aws-lc โ”‚ pkg:cargo/aws-lc-rs@1.13.1 โ”‚
โ”‚                            โ”‚                            โ”‚         โ”‚ -rs:1.13.1:*:*:*:*:*:*:*   โ”‚                            โ”‚
โ”‚ aws-lc-sys                 โ”‚ 0.29.0                     โ”‚ library โ”‚ cpe:2.3:a:aws-lc-sys:aws-l โ”‚ pkg:cargo/aws-lc-sys@0.29. โ”‚
โ”‚                            โ”‚                            โ”‚         โ”‚ c-sys:0.29.0:*:*:*:*:*:*:* โ”‚ 0                          โ”‚
โ”‚ bindgen                    โ”‚ 0.69.5                     โ”‚ library โ”‚ cpe:2.3:a:bindgen:bindgen: โ”‚ pkg:cargo/bindgen@0.69.5   โ”‚
โ”‚                            โ”‚                            โ”‚         โ”‚ 0.69.5:*:*:*:*:*:*:*       โ”‚                            โ”‚
โ”‚ bitflags                   โ”‚ 2.9.1                      โ”‚ library โ”‚ cpe:2.3:a:bitflags:bitflag โ”‚ pkg:cargo/bitflags@2.9.1   โ”‚

The command accepts the optional filters “name”, “version”, “type”, “cpe” and “purl” (not all used here for the sake of breviy):

Input (long variant)
bomnipotent_client component list "Your Project" "1.0.0" --name=aho-corasick --version=1.1.3 --type=library
Input (short variant)
bomnipotent_client component list "Your Project" "1.0.0" -n aho-corasick -v 1.1.3 -t library
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Name         โ”‚ Version โ”‚ Type    โ”‚ CPE                        โ”‚ PURL                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ aho-corasick โ”‚ 1.1.3   โ”‚ library โ”‚ cpe:2.3:a:aho-corasick:aho โ”‚ pkg:cargo/aho-corasick@1.1 โ”‚
โ”‚              โ”‚         โ”‚         โ”‚ -corasick:1.1.3:*:*:*:*:*: โ”‚ .3                         โ”‚
โ”‚              โ”‚         โ”‚         โ”‚ *:*                        โ”‚                            โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

This output is primarily meant to be human-readable. Using the --output=raw option makes it machine-readable in principle, but downloading the complete BOM is most likely preferable to parsing this table output.

A vendor of a product should periodically scan the BOM of a product for vulnerabilities, for example by using tools like grype. The next section explains how you as the user of a product can access these list.

Jun 16, 2025

Vulnerabilities

List

To dispaly a list of known vulnerabilities accessible to you, call:

Input
bomnipotent_client vulnerability list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product Name โ”‚ Product Version โ”‚ Vulnerability       โ”‚ Description                โ”‚ Score โ”‚ Severity โ”‚ TLP       โ”‚ CSAF Assessments           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Project โ”‚ 3.1.4           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ TLP:GREEN โ”‚                            โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚           โ”‚                            โ”‚
โ”‚ Your Project โ”‚ 1.0.0           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ Default   โ”‚ known_affected, according  โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚           โ”‚ to ghsa-qg5g-gv98-5ffh_adv โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚           โ”‚ isory                      โ”‚
โ”‚ Your Project โ”‚ 1.1.0           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ Default   โ”‚ fixed, according to ghsa-q โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚           โ”‚ g5g-gv98-5ffh_advisory, re โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚           โ”‚ commended, according to gh โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚           โ”‚ sa-qg5g-gv98-5ffh_advisory โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The output contains an ID for the vulnerability, a description, and a CVSS value and/or severity if available. It also contains a TLP Classification derived from that of the affected product, and ideally a CSAF Assessment by the vendor.

The list can be filtered by name and/or version of the affected product:

Input (long variant)
bomnipotent_client vulnerability list --name="Your Project" --version="1.0.0"
Input (short variant)
bomnipotent_client vulnerability list -n "Your Project" -v "1.0.0"
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product Name โ”‚ Product Version โ”‚ Vulnerability       โ”‚ Description                โ”‚ Score โ”‚ Severity โ”‚ TLP     โ”‚ CSAF Assessments           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Your Project โ”‚ 1.0.0           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ Default โ”‚ known_affected, according  โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚         โ”‚ to ghsa-qg5g-gv98-5ffh_adv โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚         โ”‚ isory                      โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

To display only those vulnerabilities that are not yet covered by a CSAF advisory, call:

Input (long variant)
bomnipotent_client vulnerability list --unassessed
Input (short variant)
bomnipotent_client vulnerability list -u
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product Name โ”‚ Product Version โ”‚ Vulnerability       โ”‚ Description                โ”‚ Score โ”‚ Severity โ”‚ TLP       โ”‚ CSAF Assessments โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Project โ”‚ 3.1.4           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ TLP:GREEN โ”‚                  โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚           โ”‚                  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
[ERROR] Found 1 unassessed vulnerabilities.

The behaviour here is special: If there are any unassessed vulnerabilities, the client will return an error code. This is meant to ease the integration with scripts that regularly check for new vulnerabilities, as is for example described in the section about CI/CD.

Listing only vulnerabilities that have an advisory is also possible, but does not exhibit any special client behaviour:

Input (long variant)
bomnipotent_client vulnerability list --unassessed=false
Input (short variant)
bomnipotent_client vulnerability list -u false
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product Name โ”‚ Product Version โ”‚ Vulnerability       โ”‚ Description                โ”‚ Score โ”‚ Severity โ”‚ TLP     โ”‚ CSAF Assessments           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Your Project โ”‚ 1.0.0           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ Default โ”‚ known_affected, according  โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚         โ”‚ to ghsa-qg5g-gv98-5ffh_adv โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚         โ”‚ isory                      โ”‚
โ”‚ Your Project โ”‚ 1.1.0           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ Default โ”‚ fixed, according to ghsa-q โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚         โ”‚ g5g-gv98-5ffh_advisory, re โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚         โ”‚ commended, according to gh โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚                            โ”‚       โ”‚          โ”‚         โ”‚ sa-qg5g-gv98-5ffh_advisory โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The CSAF document is a crucial part of vulnerability handling, because it tells you, the user of the product, how you should react to this supply chain vulnerability. Read the next section to find out how to access them.

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client vulnerability exist --name="Your Project" --version="1.0.0"
Input (short variant)
bomnipotent_client vulnerability exist -n "Your Project" -v "1.0.0"
Output
[INFO] The server contains 1 vulnerabilities matching the filters.
Jul 18, 2025

CSAF Documents

When a vulnerability becomes known in one of the components of a product that you use, one of the most natural questions to ask is “What do I have to do now?”. The Common Security Advisory Framework (CSAF) aims to provide an answer to that question in an automated fashion. It is a mainly machine-readable format for exchanging advisories about security vulnerabilities.

One of the main functionalities of BOMnipotent is to make distribution of CSAF documents as easy as possible. Any running instance of BOMnipotent Server acts as a “CSAF Provider” according to the OASIS standard.

List

Running the following command will give you a list of all CSAF documents accessible to you:

Input
bomnipotent_client csaf list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ID                         โ”‚ Title                      โ”‚ Initial Release         โ”‚ Current Release         โ”‚ Status โ”‚ TLP       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ Network-reachable panic in โ”‚ 2025-01-01 10:11:12 UTC โ”‚ 2025-01-01 10:11:12 UTC โ”‚ final  โ”‚ TLP:AMBER โ”‚
โ”‚ ry                         โ”‚  Your Product              โ”‚                         โ”‚                         โ”‚        โ”‚           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Accesible CSAF documents are those that are either labeled TLP:WHITE/TLP:CLEAR, or that concern a product that you have been granted access to.

Filter

The “csaf list” command allows quite a large number of filters, to display only some of all CSAF documents:

  • id: The ID of a CSAF document is unique, so this filter will display at most one result.
  • filename: According to the OASIS standard, CSAF IDs allow more characters than filenames. Thus, a CSAF doc’s filename is not necessarily unique.
  • before: Show only CSAF documents that were initially released before a certain datetime. The input can be of the forms “YYYY”, “YYYY-MM”, “YYYY-MM-DD”, “YYYY-MM-DD HH”, “YYYY-MM-DD HH:MM” or “YYYY-MM-DD HH:MM:SS”. If the input is less precise than seconds, it is assumend to be minimal. This means that “before 2025-08” filters for documents that were released before 2025-08-01 00:00:00. UTC is assumed as the timezone, unless you explicitly specify another one by adding an offset ("+02:00" for example) to the input.
  • after: Show only CSAF documents that were initially released after a certain datetime. If the input is less precise than seconds, it is assumed to be maximal. This means that “after 2025-08” filters for documents that were release after 2025-08-31 13:59:59.
  • year: Show only CSAF documents that were initially released within a given year.
  • status: Filter by document status. The OASIS standard lists all allowed values.
  • tlp: Show only CSAF document with a certain TLP classification. In addition to the labels of TLP1 and TLP2, “default”, “none”, “unclassified” and “unlabeled” are valid inputs here (all denoting the same thing).
Input (long variant)
bomnipotent_client csaf list --year=2025 --status=final --tlp=amber
Input (short variant)
bomnipotent_client csaf list -y 2025 -s final -t amber
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ID                         โ”‚ Title                      โ”‚ Initial Release         โ”‚ Current Release         โ”‚ Status โ”‚ TLP       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ Network-reachable panic in โ”‚ 2025-01-01 10:11:12 UTC โ”‚ 2025-01-01 10:11:12 UTC โ”‚ final  โ”‚ TLP:AMBER โ”‚
โ”‚ ry                         โ”‚  Your Product              โ”‚                         โ”‚                         โ”‚        โ”‚           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
Input (long variant)
bomnipotent_client csaf list --before=2025-03-01 --after="2024-11-08 15:44:13.26+02:00"
Input (short variant)
bomnipotent_client csaf list -b 2025-03-01 -a "2024-11-08 15:44:13.26+02:00"
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ID                         โ”‚ Title                      โ”‚ Initial Release         โ”‚ Current Release         โ”‚ Status โ”‚ TLP       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ Network-reachable panic in โ”‚ 2025-01-01 10:11:12 UTC โ”‚ 2025-01-01 10:11:12 UTC โ”‚ final  โ”‚ TLP:AMBER โ”‚
โ”‚ ry                         โ”‚  Your Product              โ”‚                         โ”‚                         โ”‚        โ”‚           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Download

To locally mirror all CSAF documents accessible to you, run

Input
bomnipotent_client csaf download /home/csaf
Output
[INFO] Storing CSAF documents under '/home/csaf'.

This will store the CSAF documents in the provided folder ("/home/csaf", in this example). It will create the folder structure if it does not already exist. The CSAF documents are stored in file paths following the naming scheme “{tlp}/{initial_release_year}/{csaf_id}.json”.

The filenames of CSAF documents follow a naming scheme defined by the OASIS standard: The ids are converted into lowercase, and most special characters are replaced by an underscore ‘_’. This means that, in principle, different CSAF documents could lead to the same filepath. In that case, BOMnipotent will display an error instead of silently overwriting a file.

The client also downloads several files containing a hash and the filename of the hashed file.

If OpenPGP is configured on the server, the client furthermore downloads cryptografic signatures for the CSAF documents. They are saved in “.json.asc” files, and can for example be verified using Sequoia-PGP.

Input
tree /home/csaf/
Output
/home/csaf/
`-- amber
    `-- 2025
        |-- ghsa-qg5g-gv98-5ffh_advisory.json
        |-- ghsa-qg5g-gv98-5ffh_advisory.json.asc
        |-- ghsa-qg5g-gv98-5ffh_advisory.json.sha256
        `-- ghsa-qg5g-gv98-5ffh_advisory.json.sha512

3 directories, 4 files

Before requesting files for download, BOMnipotent Client makes an inventory of the CSAF documents already present in the folder, and downloads only the missing ones.

It is possible to only download a single file by providing the path as an additional argument:

Input
bomnipotent_client csaf download /home/csaf amber/2025/ghsa-qg5g-gv98-5ffh_advisory.json
Output
[INFO] Storing CSAF document under '/home/csaf'.

BOMnipotent does not automatically replace existing files, even if they have changed on the server. It instead prints a warning message:

Input
bomnipotent_client csaf download /home/csaf
Output
[INFO] Storing CSAF documents under '/home/csaf'.
[WARN] File '/home/csaf/amber/2025/ghsa-qg5g-gv98-5ffh_advisory.json' already exists.
The existing CSAF doc has ID 'GHSA-QG5G-GV98-5FFH%ADVISORY' while the new one has ID 'ghsa-qg5g-gv98-5ffh_advisory'.
Note that according to the OASIS standard, both IDs are mapped to the same filename 'ghsa-qg5g-gv98-5ffh_advisory.json'.
For more information, see Section 5.1 of
https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#51-filename
Skipping download to prevent data loss.

You can tell BOMnipotent that you really want this file overwritten by using the “overwrite” flag:

Input (long variant)
bomnipotent_client csaf download /home/csaf --overwrite
Input (short variant)
bomnipotent_client csaf download /home/csaf -o
Output
[INFO] Storing CSAF documents under '/home/csaf'.
[INFO] Overwriting existing CSAF document at '/home/csaf/amber/2025/ghsa-qg5g-gv98-5ffh_advisory.json'.

The download command accepts exactly the same filters as the list command does, allowing to only download those documents that are relevant to you.

Get

You can directly display the contents of a single CSAF doc to the consolte output by calling

Input
bomnipotent_client csaf get ghsa-qg5g-gv98-5ffh_advisory | tail -n 16
Output
          "your_project_1.1.0"
        ]
      },
      "remediations": [
        {
          "category": "vendor_fix",
          "date": "2025-01-01T11:00:00.000Z",
          "details": "Update to version 1.1.0.",
          "product_ids": [
            "your_project_1.0.0"
          ]
        }
      ]
    }
  ]
}

This is especially useful if you want to use the contents of this CSAF doc in a script.

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client csaf exist --year=2023
Input (short variant)
bomnipotent_client csaf exist -y 2023
Output
[INFO] The server does not contain any CSAF document(s) matching the filters.
Aug 13, 2025

Products

List

To see exactly which products are covered by which CSAF advisory, run:

Input
bomnipotent_client product list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Full Product Name          โ”‚ BOM Name     โ”‚ BOM Version โ”‚ Vulnerability              โ”‚ Status         โ”‚ CSAF ID                    โ”‚ TLP       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Vendor's Your Project โ”‚ Your Project โ”‚ 1.0.0       โ”‚ GHSA-qg5g-gv98-5ffh        โ”‚ known_affected โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ TLP:AMBER โ”‚
โ”‚  v1.0.0                    โ”‚              โ”‚             โ”‚ Rustls network-reachable p โ”‚                โ”‚ ry                         โ”‚           โ”‚
โ”‚                            โ”‚              โ”‚             โ”‚ anic                       โ”‚                โ”‚                            โ”‚           โ”‚
โ”‚ Best Vendor's Your Project โ”‚ Your Project โ”‚ 1.1.0       โ”‚ GHSA-qg5g-gv98-5ffh        โ”‚ fixed          โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ TLP:AMBER โ”‚
โ”‚  v1.1.0                    โ”‚              โ”‚             โ”‚ Rustls network-reachable p โ”‚                โ”‚ ry                         โ”‚           โ”‚
โ”‚                            โ”‚              โ”‚             โ”‚ anic                       โ”‚                โ”‚                            โ”‚           โ”‚
โ”‚ Best Vendor's Your Project โ”‚ Your Project โ”‚ 1.1.0       โ”‚ GHSA-qg5g-gv98-5ffh        โ”‚ recommended    โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ TLP:AMBER โ”‚
โ”‚  v1.1.0                    โ”‚              โ”‚             โ”‚ Rustls network-reachable p โ”‚                โ”‚ ry                         โ”‚           โ”‚
โ”‚                            โ”‚              โ”‚             โ”‚ anic                       โ”‚                โ”‚                            โ”‚           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The command accepts the optional filters “name”, “vulnerability”, “status” and “csaf”:

Input (long variant)
bomnipotent_client product list --status=known_affected --csaf="ghsa-qg5g-gv98-5ffh_advisory"
Input (short variant)
bomnipotent_client product list -s known_affected -c "ghsa-qg5g-gv98-5ffh_advisory"
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Full Product Name          โ”‚ BOM Name     โ”‚ BOM Version โ”‚ Vulnerability              โ”‚ Status         โ”‚ CSAF ID                    โ”‚ TLP       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Vendor's Your Project โ”‚ Your Project โ”‚ 1.0.0       โ”‚ GHSA-qg5g-gv98-5ffh        โ”‚ known_affected โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ TLP:AMBER โ”‚
โ”‚  v1.0.0                    โ”‚              โ”‚             โ”‚ Rustls network-reachable p โ”‚                โ”‚ ry                         โ”‚           โ”‚
โ”‚                            โ”‚              โ”‚             โ”‚ anic                       โ”‚                โ”‚                            โ”‚           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client product exist --status=known_affected
Input (short variant)
bomnipotent_client product exist -s known_affected
Output
[INFO] The server contains 1 product(s) matching the filters.
Jul 18, 2025

For Managers

This section is aimed at managers of some part of a BOMnipotent system. A manager in this context means a user account that has the permissions to upload or modify supply chain security documents, or to manage access permissions of other users.

Mar 22, 2025

Subsections of For Managers

Managing Subscriptions

Most actions that add data to your BOMnipotent database require an active subscription, while reading and removing data do not. This policy ensures that your users do not loose access to the existing data should you one day choose to stop paying for the product.

Commercial entities like companies can acquire a subscription on bomnipotent.de. If you are a non-commercial entity, you can use BOMnipotent without any charge. Request access by sending an email to info@wwh-soft.com.

This page describes how you can use BOMnipotent Client and your subscription key to (de)activate an instance of BOMnipotent Server. The subscription itself, meaning payment, validation and trialing are all handled by the external company Paddle. Describing the management of these aspects would be beyond the scope of this documentation. Please refer to their help page if you require assistance.

Shortly after you have acquired a subscription, you will receive an email containing your subscription key.

Subscriptions can only be managed by a user with the “admin” role.

Activating

To activate your new subscription, simply call:

Input
bomnipotent_client subscription activate your_subscription_key
Output
[INFO] Successfully stored subscription key.

The server will tell you if something goes wrong during activation:

Input
bomnipotent_client subscription activate wrong_subscription_key
Output
[ERROR] Received response:
404 Not Found
Failed to activate subscription key: The subscription is missing in the sever database, which most likely means that there was an error in the input.

Status

To get more information about your current subscription, call:

Input
bomnipotent_client subscription status
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Key      โ”‚ Product     โ”‚ Subscription Status โ”‚ Valid Until             โ”‚ Last Updated            โ”‚ Assessment                 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ***n_key โ”‚ BOMnipotent โ”‚ active              โ”‚ 2025-01-01 10:11:12 UTC โ”‚ 2025-01-01 10:11:12 UTC โ”‚ The subscription is valid. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

This output contains an obfuscated print of your key, a status, and some additional information.

Removing

If you want to remove your subscription from an instance of BOMnipotent Server (because you for example want to use it for another instance), call

Input
bomnipotent_client subscription remove your_subscription_key
Output
[INFO] Subscription key was removed.

To avoid accidently deactivating a BOMnipotent Server instance that you have admin access to, this requires the correct key as an argument.

Input
bomnipotent_client subscription remove wrong_subscription_key
Output
[ERROR] Received response:
403 Forbidden
Subscription key does not match stored key.
Jun 16, 2025

Document Management

BOMnipotent knows two types of supply chain security documents: Bills of Materials (BOMs) and Common Security Advisory Framework (CSAF) documents. In addition, it can host information on vulnerabilities associated with a BOM.

A typical document management workflow looks like this:

  1. A new version of a product is released, together with its corresponding BOM. The BOM may for example be generated with syft. This document is uploaded to the server. In contrast to the other documents, BOMs should be treated as static data. Modifying or deleting BOMs is possible, but rare.
  2. An automated tooling or script regularly downloads the BOMs, and checks them for vulnerabilities. This may for example be done with grype. The findings are updated on the server.
  3. Another tooling or script regularly checks the BOMnipotent Server for new vulnerabilities and sounds an alarm when it finds one. A human mind is needed!
  4. The human thoroughly analyses the vulnerability and determines if and how your customers have to react. They create a CSAF document, using for example secvisogram. The CSAF document is uploaded to BOMnipotent Server.
  5. Your consumers will now find the new CSAF document when they poll your instance of BOMnipotent Server.

Here you can see some exemplary interactions:

Aug 15, 2025

Subsections of Document Management

BOMs

Bills of Materials stand at the forefront of both BOMnipotents functionality and name. A BOM is a list of all components that make up a product. In the context of cybersecurity, the most prominent variant is the Software Bill of Materials (SBOM), but BOMs allow for more general considerations as well.

For BOM interactions beyond reading, you need the BOM_MANAGEMENT permission. The section about Access Management describes how it is granted.

Uploading

To upload a BOM, call:

Input
bomnipotent_client bom upload /home/your_project/sbom.cdx.json
Output
[INFO] Uploaded BOM 'Your Project:1.0.0'.

BOMnipotent expects its BOMs in the structured CycloneDX JSON format.

Consult the Syft tutorial to learn how to generate a BOM for your product.

The BOMnipotent Client will read the file at the provided path and upload its content. It can then be viewed by the consumers with appropriate permissions.

BOMs for Consumers describes how to list and download the BOMs on the server.

To add a BOM to the database, the BOMnipotent Client has to have some additional information: a name, a version, and optionally a TLP label. The identifiers name and version can either be inferred (recommended), or overwritten, as described below.

Name and Version

BOMnipotent uses name and version to identify a BOM. It tries to infer these from the provided CycloneDX JSON fields “metadata.component.name” and “metadata.component.version”. However, according to the CycloneDX specification, the metadata.component field is optional.

If no version is specified, BOMnipotent instead uses the date of “metadata.timestamp”, if available.

To avoid any complications, it is recommended that you specify a name and version when generating the BOM, as is shown in the Syft tutorial.

If for some reason your BOM lacks a name or version, or if it is incorrect, the BOMnipotent Client offers to remedy that via command line arguments:

Input (long variant)
bomnipotent_client bom upload /home/your_project/dev_env_sbom.cdx.json --name-overwrite="Other Project" --version-overwrite="2.7.1"
Input (short variant)
bomnipotent_client bom upload /home/your_project/dev_env_sbom.cdx.json -n "Other Project" -v "2.7.1"
Output
[WARN] Warning: Overwriting name with 'Other Project'. The data stored on the server will differ from the provided file.
[WARN] Warning: Overwriting version with '2.7.1'. The data stored on the server will differ from the provided file.
[INFO] Uploaded BOM 'Other Project:2.7.1'.

Important: The BOMnipotent Client will in this case modify the data before sending it to the server. It does not modify the local file, as that would be overstepping. This means that your local file and the data on the server are now out-of-sync. What’s maybe worse, if you signed your BOM, your signature is now invalid.

If you do use this option, it is thus recommended that you immediately download the BOM from the server (as described in BOMs for Consumers) and replace your local file with the result.

TLP Classification

For consumers, BOMnipotent manages access to data using the Traffic Light Protocol (TLP). The CycloneDX Format on the other hand does not currently support document classification.

To tell BOMnipotent how to classify a document, you have two options:

  1. Set a default TLP Label in the server config. This will then be used for all BOMs without further specifications.
  2. Provide a tlp classification via command line argument:
Input (long variant)
bomnipotent_client bom upload /home/your_project/container_sbom.cdx.json --tlp=WHITE # This makes the BOM public.
Input (short variant)
bomnipotent_client bom upload /home/your_project/container_sbom.cdx.json -t WHITE # This makes the BOM public.
Output
[INFO] Uploaded BOM 'Your Project Container:1.2.3'.

If you do neither, BOMnipotent will treat any unclassified documents as if they were labelled TLP:RED, and will log a warning every time it has to do that.

Conflict Handling

The combination of name and version of the main component of a BOM need to be unique. Trying to upload another document with the same combination results in an error.

Input
bomnipotent_client bom upload /home/your_project/sbom.cdx.json
Output
[ERROR] Received response:
409 Conflict
BOM 'Your Project:1.0.0' already exists in the database.

You can override this behaviour with the “on-existing” option, telling BOMnipotent to either skip or replace conflicting documents:

Input (long variant)
bomnipotent_client bom upload /home/your_project/sbom.cdx.json --on-existing=skip
Input (short variant)
bomnipotent_client bom upload /home/your_project/sbom.cdx.json -o skip
Output
[INFO] 
Input (long variant)
bomnipotent_client bom upload /home/your_project/sbom.cdx.json --on-existing=replace
Input (short variant)
bomnipotent_client bom upload /home/your_project/sbom.cdx.json -o replace
Output
[INFO] Modified BOM 'Your Project:1.0.0'.

Modifying

In the simplest case, modifying an existing BOM works very much like uploading a new one.

Input
bomnipotent_client bom modify /home/your_project/sbom.cdx.json
Output
[INFO] Modified BOM 'Your Project:1.0.0'.

This will infer the name and version from the document, and overwrite the existing content on the server. If the data does not exist on the server, it will return a 404 Not Found error.

Modifying TLP Label

If a TLP label had previously been assigned to the BOM, a modification of the contents will not automatically alter it.

If you want to specify a new TLP label, you can do so via argument:

Input (long variant)
bomnipotent_client bom modify /home/your_project/sbom.cdx.json --tlp=AMBER
Input (short variant)
bomnipotent_client bom modify /home/your_project/sbom.cdx.json -t AMBER
Output
[INFO] Modified BOM 'Your Project:1.0.0'.

If the contents of the BOM have not changed and you just want to modify the TLP label, you do not need to upload the document again. Instead of providing a path to a file, you can specify name and version of the BOM you want to reclassify:

Input (long variant)
bomnipotent_client bom modify --name="Other Project" --version="2.7.1" --tlp=GREEN
Input (short variant)
bomnipotent_client bom modify -n "Other Project" -v "2.7.1" -t GREEN
Output
[INFO] Modified BOM 'Other Project:2.7.1'.

If you specify “none”, “default” or “unlabelled” as the TLP label, any existing classification will be removed, and the server falls back to the default TLP Label of the server config:

Input (long variant)
bomnipotent_client bom modify /home/your_project/sbom.cdx.json --tlp=none
bomnipotent_client bom modify /home/your_project/sbom.cdx.json --tlp=default # Does the same
bomnipotent_client bom modify /home/your_project/sbom.cdx.json --tlp=unlabeled # Does the same
Input (short variant)
bomnipotent_client bom modify /home/your_project/sbom.cdx.json -t none
bomnipotent_client bom modify /home/your_project/sbom.cdx.json -t default # Does the same
bomnipotent_client bom modify /home/your_project/sbom.cdx.json -t unlabeled # Does the same
Output
[INFO] Modified BOM 'Your Project:1.0.0'.
[INFO] Modified BOM 'Your Project:1.0.0'.
[INFO] Modified BOM 'Your Project:1.0.0'.

Modifying Name or Version

If the document you are uploading has a different name or version than the data it shall modify, you need to provide that information to the BOMnipotent Client using command line arguments:

Input (long variant)
bomnipotent_client bom modify /home/your_project/dev_env_sbom.cdx.json --name="Other Project" --version="2.7.1"
Input (short variant)
bomnipotent_client bom modify /home/your_project/dev_env_sbom.cdx.json -n "Other Project" -v "2.7.1"
Output
[INFO] Modified BOM 'Your Development Environment:1.2.3'.

BOMnipotent will infer the new data from the document you provide and change the database entries accordingly.

As with uploading, it is possible to overwrite the name and/or version stored in the local document:

Input
bomnipotent_client bom modify /home/your_project/dev_env_sbom.cdx.json --name-overwrite="Fearsome Breadcrump" --version-overwrite="6.2.8"
Output
[WARN] Warning: Overwriting name with 'Fearsome Breadcrump'. The data stored on the server will differ from the provided file.
[WARN] Warning: Overwriting version with '6.2.8'. The data stored on the server will differ from the provided file.
[INFO] Modified BOM 'Fearsome Breadcrump:6.2.8'.

Important: As with uploading, this modifies the JSON data before uploading to the server! The same caveats apply.

If the data on the server has a different name and/or version than specified in the document, you can combine the specification with an overwrite of the data:

Input (long variant)
bomnipotent_client bom modify /home/your_project/dev_env_sbom.cdx.json --name="Fearsome Breadcrump" --version="6.2.8" --name-overwrite="Best Project" --version-overwrite="3.1.4"
Input (short variant)
bomnipotent_client bom modify /home/your_project/dev_env_sbom.cdx.json -n "Fearsome Breadcrump" -v "6.2.8" --name-overwrite="Best Project" --version-overwrite="3.1.4"
Output
[WARN] Warning: Overwriting name with 'Best Project'. The data stored on the server will differ from the provided file.
[WARN] Warning: Overwriting version with '3.1.4'. The data stored on the server will differ from the provided file.
[INFO] Modified BOM 'Best Project:3.1.4'.

Changing name and/or version without providing the complete document is not supported.

Deleting

Deleting a BOM is very straightforward:

Input
bomnipotent_client bom delete "Best Project" "3.1.4"
Output
[INFO] Successfully deleted BOM 'Best Project:3.1.4'.

If the BOM does not exist, the server will return 404 Not Found. If it does exists, it is removed from the database.

All components and vulnerabilities associated with the BOM are also deleted.

Jul 18, 2025

Vulnerabilities

An activity at the core of supply chain security is to compare the contents of a BOM, meaning all components of a product, to databases of known vulnerabilities.

For vulnerability interactions beyond reading, you need the VULN_MANAGEMENT permission. The section about Access Management describes how it is granted.

Detecting

BOMnipotent does not itself detect new vulnerabilities. One tool that can be used in combination with BOMnipotent is grype, which takes a BOM as input and produces a list of vulnerabilities as output. The grype tutorial contains some additional information on its usage. Other tools can be used as long as they provide output in CycloneDX JSON format.

Using the BOMnipotent Client, you can directly print the contents of a BOM and pipe it to grype.

Input (long variant)
bomnipotent_client bom get "Your Project" "1.0.0" | grype --output cyclonedx-json=/home/vuln.cdx.json
Input (short variant)
bomnipotent_client bom get "Your Project" "1.0.0" | grype -o cyclonedx-json=/home/vuln.cdx.json

This will check the software components agains several databases and add the result to the CycloneDX. It then stores all that in a file called “vuln.cdx.json” (or whichever other name you provide).

Grype currently has a small known bug that makes it forget the version of the main component when it adds the vulnerabilities. This is a bit problematic because BOMnipotent needs the version to uniquely identify a product. One possible workaround is to re-add the version to the document, for example via jq '.metadata.component.version = "<VERSION>"' "vuln.cdx.json" > "vuln_with_version.cdx.json". Starting with BOMnipotent v0.3.1 you can instead directly provide the version during the vulnerability upload, as described below.

Updating

The command to update the vulnerabilities associated with a BOM is:

Input
bomnipotent_client vulnerability update /home/your_project/vuln.cdx.json
Output
[INFO] Updated vulnerabilities of BOM 'Your Project:1.0.0'.

The “<VULNERABILITIES>” argument needs to be a path to a file in CycloneDX JSON format.

Ideally, this file contains the name and version of the associated BOM, in which case they will automatically be read. If one of the values is missing (due to a known bug in grype, for example), you can provide it with an optional argument:

Input (long variant)
bomnipotent_client vulnerability update /home/your_project/vuln_wrong_metadata.cdx.json --name="Your Project" --version="1.0.0"
Input (short variant)
bomnipotent_client vulnerability update /home/your_project/vuln_wrong_metadata.cdx.json -n "Your Project" -v "1.0.0"
Output
[INFO] Updated vulnerabilities of BOM 'Your Project:1.0.0'.

Vulnerabilities are meant to updated periodically. Doing so will completely replace any previous vulnerabilities associated a BOM. The uploaded CycloneDX document thus needs to contain a full list of all known vulnerabilities.

You can only update vulnerabilities for a BOM that exists on the server:

Input (long variant)
bomnipotent_client vulnerability update /home/your_project/vuln_wrong_metadata.cdx.json --name=Schlagsahne --version=2.7.1;
bomnipotent_client vulnerability update /home/your_project/vuln_wrong_metadata.cdx.json --version=1.0.1;
Input (short variant)
bomnipotent_client vulnerability update /home/your_project/vuln_wrong_metadata.cdx.json -n Schlagsahne -v 2.7.1;
bomnipotent_client vulnerability update /home/your_project/vuln_wrong_metadata.cdx.json -v 1.0.1;
Output
[ERROR] Received response:
404 Not Found
BOM 'Schlagsahne:2.7.1' not found in database.
[ERROR] Received response:
404 Not Found
BOM 'Your Project:1.0.1' not found in database.

Listing

The section about listing vulnerabilities in the documentation for consumers covers most aspects of listing vulnerabilities.

One aspect not mentioned there is the “unassessed” option. With it, BOMnipotent Client lists only those vulnerabilities that do not have a CSAF document with status “final” associated with it.

For this association to work, the CSAF document must contain product_name and product_version entries for the BOM in its branches.

Input (long variant)
bomnipotent_client vulnerability list --unassessed
Input (short variant)
bomnipotent_client vulnerability list -u
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Product Name โ”‚ Product Version โ”‚ Vulnerability       โ”‚ Description                โ”‚ Score โ”‚ Severity โ”‚ TLP       โ”‚ CSAF Assessments โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Best Project โ”‚ 3.1.4           โ”‚ GHSA-qg5g-gv98-5ffh โ”‚ rustls network-reachable p โ”‚       โ”‚ medium   โ”‚ TLP:GREEN โ”‚                  โ”‚
โ”‚              โ”‚                 โ”‚                     โ”‚ anic in `Acceptor::accept` โ”‚       โ”‚          โ”‚           โ”‚                  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
[ERROR] Found 1 unassessed vulnerabilities.

In this mode, BOMnipotent Client exits with a code indicating an error if and only if there are unassessed vulnerabilites. This makes it easy to integrate this call in your periodic CI/CD.

You can freely combine this option with specifying a product name or version:

Input (long variant)
bomnipotent_client vulnerability list --name="Your Project" --version="1.0.0" --unassessed
Input (short variant)
bomnipotent_client vulnerability list -n "Your Project" -v "1.0.0" -u
Output
[INFO] No unassessed vulnerabilities found
Aug 13, 2025

CSAF Documents

A Common Security Advisory Framework (CSAF) document is a vendor’s response to a newly discovered vulnerability. It is a machine-readable format to spread information on how a user of your product should react: Do they need to update to a newer version? Do they need to modify a configuration? Is your product even truly affected, or does it maybe never call the affected part of the vulnerable library?

For CSAF interactions beyond reading, you need the CSAF_MANAGEMENT permission. The sectino about Access Management describes how it is granted.

Uploading

To upload a CSAF document, call

Input
bomnipotent_client csaf upload /home/your_project/advisory.json
Output
[INFO] Uploaded CSAF with id 'ghsa-qg5g-gv98-5ffh_advisory'.

Before your CSAF document is uploaded, BOMnipotent Client checks that it is valid according to the OASIS CSAF Standard.

Conflict Handling

CSAF documents are identified by their, well, identifier, which needs to be unique. Trying to upload another document with the same id results in an error:

Input
bomnipotent_client csaf upload /home/your_project/advisory.json
Output
[ERROR] Received response:
409 Conflict
CSAF with id 'ghsa-qg5g-gv98-5ffh_advisory' already exists in the database.

You can override this behaviour with the “on-existing” option, telling BOMnipotent to either skip or replace conflicting documents:

Input (long variant)
bomnipotent_client csaf upload /home/your_project/advisory.json --on-existing=skip
Input (short variant)
bomnipotent_client csaf upload /home/your_project/advisory.json -o skip
Output
[INFO] 
Input (long variant)
bomnipotent_client csaf upload /home/your_project/advisory.json --on-existing=replace
Input (short variant)
bomnipotent_client csaf upload /home/your_project/advisory.json -o replace
Output
[INFO] Modified CSAF with id 'ghsa-qg5g-gv98-5ffh_advisory'.

Listing

You can view the result of the operation with

Input
bomnipotent_client csaf list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ID                         โ”‚ Title                      โ”‚ Initial Release         โ”‚ Current Release         โ”‚ Status โ”‚ TLP       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ghsa-qg5g-gv98-5ffh_adviso โ”‚ Network-reachable panic in โ”‚ 2025-01-01 10:11:12 UTC โ”‚ 2025-01-01 10:11:12 UTC โ”‚ final  โ”‚ TLP:AMBER โ”‚
โ”‚ ry                         โ”‚  Your Product              โ”‚                         โ”‚                         โ”‚        โ”‚           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

All data is taken from the CSAF document.

If the document does not have the optional TLP label entry, it is treated with the default tlp configured for the server.

...โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
...โ”‚ Status โ”‚ TLP     โ”‚
...โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
...โ”‚ final  โ”‚ Default โ”‚
...โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Modifying

When the status of your document changes, if you want to reclassify it, or if new information has come to light, you may want to modify your document. To upload the new version, call:

Input
bomnipotent_client csaf modify /home/your_project/advisory.json
Output
[INFO] Modified CSAF with id 'ghsa-qg5g-gv98-5ffh_advisory'.

The command can even modify the ID of the CSAF document. Because the old ID cannot be inferred from the new document in that case, it has to be provided as an optional argument:

Input (long variant)
bomnipotent_client csaf modify <PATH/TO/CSAF> --id=<OLD-ID>
Input (short variant)
bomnipotent_client csaf modify <PATH/TO/CSAF> -i <OLD-ID>

Deleting

To delete a CSAF document from your server (which you should really only do if something went completely wrong), simply call:

Input
bomnipotent_client csaf delete ghsa-qg5g-gv98-5ffh_advisory
Output
[INFO] Deleted CSAF with id 'ghsa-qg5g-gv98-5ffh_advisory'.
Jun 28, 2025

Access Management

Supply chain security documents are the what of BOMnipotent, users are the who. Unless you explicitly state otherwise, the hosted documents are only visible to those user accounts you grant access to.

BOMnipotent uses role-based access control (RBAC): Users have roles, and roles have permissions. After setup, BOMnipotent contains a few default roles. These are sufficient for managing the server, but to start accepting user request, you will probably want to create at least one new role.

Once that is done, a typical workflow for introducing a new user to your BOMnipotent system is as follows:

  1. A new user requests access to your server. During this step, BOMnipotent Client sends a public key associated with the account to your server, where it is stored and marked as “requested”.
  2. You approve the request. The new user account is now accepted as valid, but it does not have any permissions yet.
  3. You assign one or more roles to the new user account.

Here you can see some exemplary interactions:

Aug 15, 2025

Subsections of Access Management

Permissions

In BOMnipotent, permissions are not directly associated with user accounts, but rather with roles. The section about role management covers how this association is managed, and the section about role assignment explains how roles (and thus ultimately permissions) are assigned to users.

The server has several permissions embedded in its code, some of which are hardcoded, some of which are configurable, and all of which are explained here. To learn how to actually create a permission associated with a role, please refer to the section dedicated to exactly that topic.

The permissions can mentally be split into permissions associated with consumers, managers, and some special tasks reserved for admins.

Consumer Permissions

Your customers are typically associated with one or more of your products. They will want to view all types of documents and information for that particular product, but they are not automatically entitled to information about other products.

PRODUCT_ACCESS

A permission with the value “PRODUCT_ACCESS(<PRODUCT>)” grants read permissions to any document associated with “<PRODUCT>”. This includes any BOM for that product, any vulnerabilities associated with these BOMs, and any CSAF documents covering this product.

For example, a role with the “PRODUCT_ACCESS(BOMnipotent)” could view (and only view) all documents associated with BOMnipotent.

It is possible to use the asterisk operator “*” to glob product names. In that case, the asterisk matches an arbitrary number of symbols. For example, the permission “PRODUCT_ACCESS(BOM*ent)” would match “BOMnipotent” as well as the (fictional) products “BOMent” and “BOM-burรกrum-ent”, but not “BOMtastic” (because the latter does not end on “ent”).

Consequently, “PRODUCT_ACCESS(*)” allows the viewing of all documents.

Manager Permissions

For managers of documents, the situation is usually reversed: They need the permission to not only view but also modify the contents in the database. Their scope is typically not restricted to a specific product, but instead to a specific type of document. This is why the segregation of manager permissions takes another perspective.

BOM_MANAGEMENT

This permission allows the uploading, modifying and deleting of Bills of Materials (BOMs). It also automatically grants permission to view all hosted BOMs.

VULN_MANAGEMENT

This permission allows to update and view the list of vulnerabilities associated with any BOM.

CSAF_MANAGEMENT

Unsurprisingly, this permission allows the uploading, modifying and deleting of Common Security Advisory Framework (CSAF) documents. It also automatically grants view permissions to all hosted CSAF documents.

ROLE_MANAGEMENT

With this permission, a user can modify the permissions of roles, which can have far reaching consequences, because the changes potentially affect many users.

USER_MANAGEMENT

This permission is required to approve, deny or view users, or to individually assign roles to them.

Special Admin permissions

BOMnipotent knows one hardcoded special role called “admin”. This role always has all permissions that can be given to users. Additionally, there are some tasks that can only be done by a user with the admin role:

May 21, 2025

Role Management

BOMnipotent uses a role-based access model (RBAC), in which users are associated with roles, and roles with permissions. While permissions are largely hardcoded into BOMnipotent, roles can be managed (almost) freely. This section explains how to do that.

To modify or even view roles and their permissions, your user account needs the ROLE_MANAGEMENT permission.

Default Roles

When you spin up your BOMnipotent Server for the first time, it creates several colourfully named default roles in the database:

You can modify or delete these roles at will, they are merely suggestions.

If you do not like these roles, use the following calls to delete them:

Input
bomnipotent_client role-permission remove bom_manager BOM_MANAGEMENT;
bomnipotent_client role-permission remove csaf_manager CSAF_MANAGEMENT;
bomnipotent_client role-permission remove role_manager ROLE_MANAGEMENT;
bomnipotent_client role-permission remove user_manager USER_MANAGEMENT;
bomnipotent_client role-permission remove vuln_manager VULN_MANAGEMENT;
Output
[INFO] Removed permission BOM_MANAGEMENT from role bom_manager.
[INFO] Removed permission CSAF_MANAGEMENT from role csaf_manager.
[INFO] Removed permission ROLE_MANAGEMENT from role role_manager.
[INFO] Removed permission USER_MANAGEMENT from role user_manager.
[INFO] Removed permission VULN_MANAGEMENT from role vuln_manager.

Admin Role

There is a special role called “admin”, which is not listed among the other roles. The reason is that it is not part of the database, but of the BOMnipotent code itself. As such, it cannot be modified.

Input
bomnipotent_client role-permission remove admin BOM_MANAGEMENT
Output
[ERROR] Received response:
422 Unprocessable Entity
Cannot modify admin role permissions.

The admin role has all permissions that can be granted, and then some more.

List

To list all roles and their associated permissions, call:

Input
bomnipotent_client role-permission list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Role         โ”‚ Permission      โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ bom_manager  โ”‚ BOM_MANAGEMENT  โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ csaf_manager โ”‚ CSAF_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ role_manager โ”‚ ROLE_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ user_manager โ”‚ USER_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ vuln_manager โ”‚ VULN_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The output can be filtered by role or permission:

Input (long variant)
bomnipotent_client role-permission list --role=bom_manager --permission=BOM_MANAGEMENT
Input (short variant)
bomnipotent_client role-permission list -r bom_manager -p BOM_MANAGEMENT
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Role        โ”‚ Permission     โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ bom_manager โ”‚ BOM_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Add

Because roles without permissions are meaningless, the two always come in pairs. There is no dedicated mechanism to create a new role: rather, you add a permission to a role, and henceforth it exists.

The syntax to add a permission to a role is

Input
bomnipotent_client role-permission add rick_role "PRODUCT_ACCESS(Your Project)"
Output
[INFO] Added permission PRODUCT_ACCESS(Your Project) to role rick_role.

You could for example unify several permissions into the roles “doc_manager” and “access_manager”:

Input
bomnipotent_client role-permission add doc_manager BOM_MANAGEMENT;
bomnipotent_client role-permission add doc_manager CSAF_MANAGEMENT;
bomnipotent_client role-permission add doc_manager VULN_MANAGEMENT;
bomnipotent_client role-permission add access_manager ROLE_MANAGEMENT;
bomnipotent_client role-permission add access_manager USER_MANAGEMENT;
Output
[INFO] Added permission BOM_MANAGEMENT to role doc_manager.
[INFO] Added permission CSAF_MANAGEMENT to role doc_manager.
[INFO] Added permission VULN_MANAGEMENT to role doc_manager.
[INFO] Added permission ROLE_MANAGEMENT to role access_manager.
[INFO] Added permission USER_MANAGEMENT to role access_manager.

If you have removed the default roles as described above, this leaves you with:

Input
bomnipotent_client role-permission list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Role           โ”‚ Permission      โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ access_manager โ”‚ ROLE_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ access_manager โ”‚ USER_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ doc_manager    โ”‚ BOM_MANAGEMENT  โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ doc_manager    โ”‚ CSAF_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ doc_manager    โ”‚ VULN_MANAGEMENT โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

If the permission you want to add does not exist or is malformed, you will receive an error:

Input
bomnipotent_client role-permission add clam_manager CLAM_MANAGEMENT
Output
[ERROR] Received response:
422 Unprocessable Entity
Failed to parse permission: Invalid UserPermission string: CLAM_MANAGEMENT

Remove

To remove a permission from a role, simply call:

Input
bomnipotent_client role-permission remove rick_role "PRODUCT_ACCESS(Your Project)"
Output
[INFO] Removed permission PRODUCT_ACCESS(Your Project) from role rick_role.

Once you have removed the last role from a permission, that role does no longer exist.

To prevent oopsie-moments, BOMnipotent does not support deleting whole batches of role-permissions.

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client role-permission exist --role=bom_manager
Input (short variant)
bomnipotent_client role-permission exist -r bom_manager
Output
[INFO] The server contains 1 role permission(s) matching the filters.
Jul 18, 2025

User Management

The first step when creating a new user is to request a new account. This step is described elsewhere, because it is relevant for managers and consumers alike.

From BOMnipotent’s point of view, a user is associated with a unique email address or username, which is used as an identifier, and a public key, which is used for authentication. This is all the data sent during the creation of a new user account.

After a new account has been requested, it is up to a user manager to approve or deny the request.

For most user interactions, including listing, you need the USER_MANAGEMENT permission.

List

To list all users in your database, call

Input
bomnipotent_client user list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Username               โ”‚ Status    โ”‚ Expires                 โ”‚ User Type โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ admin@example.com      โ”‚ APPROVED  โ”‚ 2025-01-01 10:11:12 UTC โ”‚ HUMAN     โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ example_robot          โ”‚ REQUESTED โ”‚ 2025-01-01 10:11:12 UTC โ”‚ ROBOT     โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ other_user@example.com โ”‚ REQUESTED โ”‚ 2025-01-01 10:11:12 UTC โ”‚ HUMAN     โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ user@example.com       โ”‚ VERIFIED  โ”‚ 2025-01-01 10:11:12 UTC โ”‚ HUMAN     โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

You can see the email addresses or usernames of the users and their stati.

A user that does not have the status APPROVED has no special permissions, no matter which roles they have.

An expiration date is also associated with each user, which is the point in time at which the public key is considered invalid and has to be renewed. The period for which a key is considered valid can be freely configured in the server config.

The list of users can be filtered by username, approval status, and whether or not they are expired:

Input (long variant)
bomnipotent_client user list --user=admin@example.com --status=APPROVED --expired=false
Input (short variant)
bomnipotent_client user list -u admin@example.com -s APPROVED -e false
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Username          โ”‚ Status   โ”‚ Expires                 โ”‚ User Type โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ admin@example.com โ”‚ APPROVED โ”‚ 2025-01-01 10:11:12 UTC โ”‚ HUMAN     โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The “true” argument for the expired filter is optional:

Input (long variant)
bomnipotent_client user list --expired=true;
bomnipotent_client user list --expired # does the same
Input (short variant)
bomnipotent_client user list -e true;
bomnipotent_client user list -e # does the same
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Username โ”‚ Status โ”‚ Expires โ”‚ User Type โ”‚ Last Updated โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Username โ”‚ Status โ”‚ Expires โ”‚ User Type โ”‚ Last Updated โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค

Approve or Deny

If you were expecting the user request, you can approve it via

Input
bomnipotent_client user approve user@example.com
Output
[INFO] Changed status of user@example.com to APPROVED.

If the user has not yet verified their email address, the server denies the approval. If you are absolutely sure that you know what you are doing, you can overwrite this behaviour with the ‘allow-unverified’ option (there’s no short version for options that bypass security measures):

Input
bomnipotent_client user approve other_user@example.com --allow-unverified
Output
[INFO] Changed status of other_user@example.com to APPROVED.

Analogously, you can decide agains allowing this user any special access:

Input
bomnipotent_client user deny unwanted@example.com
Output
[INFO] Changed status of unwanted@example.com to DENIED.

Contrary to approval, this action does not care which status the user had before the denial.

It is possible to deny a user that has already been approved, effectively revoking the account.

A user whose previous request for an account was denied cannot request new user accounts.

Remove

If you want to get rid of a user account alltogether, call:

Input
bomnipotent_client user remove unwanted@example.com
Output
[INFO] Deleted user 'unwanted@example.com'.

This also removes all roles associated with the user.

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client user exist --status=APPROVED
Input (short variant)
bomnipotent_client user exist -s APPROVED
Output
[INFO] The server contains 4 user(s) matching the filters.
Aug 13, 2025

Role Assignment

Roles are what connects users to permissions. Adding or removing roles to and from users indirectly controls to what extend users can interact with your BOMnipotent Server instance.

For your convenience, several default roles are created upon starting BOMnipotent Server for the first time. In addition, BOMnipotent knows of the admin role, which receives some special treatment.

To modify or even view user roles, your user account needs the USER_MANAGEMENT permission.

List

To list all roles of all users, call

Input
bomnipotent_client user-role list
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Username          โ”‚ Role         โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ admin@example.com โ”‚ admin        โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ example_robot     โ”‚ bom_manager  โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ example_robot     โ”‚ vuln_manager โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ”‚ user@example.com  โ”‚ rick_role    โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The output can be filtered by user or role:

Input (long variant)
bomnipotent_client user-role list --user=admin@example.com --role=admin
Input (short variant)
bomnipotent_client user-role list -u admin@example.com -r admin
Output
[INFO] 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Username          โ”‚ Role  โ”‚ Last Updated            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ admin@example.com โ”‚ admin โ”‚ 2025-01-01 10:11:12 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Add

To add a new role to a user, call

Input
bomnipotent_client user-role add user@example.com rick_role
Output
[INFO] Added role to user.

The user account needs to exist on the server at this point, the role does not.

Only users with the admin role can add the admin role to other users.

Remove

To remove a role from a user, call:

Input
bomnipotent_client user-role remove user@example.com rick_role
Output
[INFO] Removed role rick_role from user user@example.com.

This will show an error if either does not exist:

Input
bomnipotent_client user-role remove admin@example.com wrong_role;
bomnipotent_client user-role remove wrong_user admin
Output
[ERROR] Received response:
404 Not Found
User with username 'admin@example.com' does not have role wrong_role.
[ERROR] Received response:
404 Not Found
No user with username 'wrong_user' was found: Record not found

Only users with the admin role can remove the admin role from other users.

Existence

The "exist" subcommand checks how many entries on the server match some filters. It is available for all commands that accept the "list" subcommand, and accepts the same filters.

Depending on the output mode, the client prints:

  • normal mode: a sentence including the number of found objects.
  • code: The string "200" if at least one item was found, or "404" if none were found.
  • raw: The number of entries that were found.
Input (long variant)
bomnipotent_client user-role exist --role=bom_manager
Input (short variant)
bomnipotent_client user-role exist -r bom_manager
Output
[INFO] The server contains 1 user role(s) matching the filters.
Jul 18, 2025

Robot Users

Not all accounts are necessarily associated with human users. BOMnipotent is built with pipeline integration in mind. To create an account to be used in automation, add the ‘robot’ option to the request:

Input (long variant)
bomnipotent_client user request example_robot --robot
Input (short variant)
bomnipotent_client user request example_robot -r
Output
[INFO] Generating new key pair.
[INFO] Storing secret key to '/root/.config/bomnipotent/secret_key.pem' and public key to '/root/.config/bomnipotent/public_key.pem'.
[INFO] Request for robot user submitted. It now needs to be confirmed by a user manager.

This request will mark the account as a robot, and not send a verification mail. To approve such an account, you have to provide the ‘robot’ option.

Input (long variant)
bomnipotent_client user approve example_robot --robot
Input (short variant)
bomnipotent_client user approve example_robot -r
Output
[INFO] Changed status of example_robot to APPROVED.
Note

Since robot users are not verified, and typically have elevated permissions, you should be absolutely certain that this is the account you want to approve.

A plausible setup is to give the robot user roles with the permissions BOM_MANAGEMENT and VULN_MANAGEMENT, enabling them to upload BOMs and update vulnerabilities:

Input
bomnipotent_client user-role add example_robot bom_manager;
bomnipotent_client user-role add example_robot vuln_manager;
Output
[INFO] Added role to user.
[INFO] Added role to user.

Now you can use your robot’s credentials in your CI/CD pipeline.