The Manifest CLI is a cross-platform application and supports both amd and arm architectures. Using various methods, you can install it on Linux, Windows, or Mac (OSX).
You can use the CLI to
- generate SBOMs (via the
sbomcommand) from specific manifest files, local filesystems (e.g. a python project), and containers (e.g. alpine:latest). - merge two or more SBOMs (of the same format) together into one SBOM, with the
mergecommand
Install script (Recommended)
curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -s-b: sets bindir or installation directory, Defaults to ./bin.
-d: turns on debug logging.
Use a positional argument to pass a specific release.
curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -s -- -b /usr/local/bin v0.14.8Note: This command pipes to sh, so it requires a POSIX shell -- Linux, macOS, or Windows under WSL or Git Bash. It will not run in a native PowerShell or Command Prompt session. On native Windows, see Windows below instead.
Aptitude (apt)
echo "deb [trusted=yes] https://repo.fury.io/manifest/ /" > /etc/apt/sources.list.d/fury.list
sudo apt update
sudo apt install manifest-cliHomebrew (tap)
brew install manifest-cyber/tap/manifest-cliYum
echo '[fury]
name=Manifest Cyber
baseurl=https://repo.fury.io/manifest/
enabled=1
gpgcheck=0' | sudo tee /etc/yum.repos.d/manifest-cyber.repo
sudo yum install manifest-cli- if running as admin, you can omit
sudo.
Windows
No WSL, Git Bash, or other POSIX shell required -- pick one of the methods below.
Scoop
scoop bucket add manifest-cli https://github.com/manifest-cyber/scoop-bucket.git
scoop install manifest-cliRequires Scoop itself to be installed first.
PowerShell or Command Prompt
curl.exe and tar ship with Windows 10/11, so you can download and extract the binary directly from Command Prompt or PowerShell:
curl.exe -sSfLo manifest-cli.zip https://github.com/manifest-cyber/cli/releases/latest/download/manifest-cli_windows_x86_64.zip
tar -xf manifest-cli.zipThis extracts manifest-cli.exe into the current folder. Move it to a folder on your PATH, or add the folder to PATH (see Adding a Folder to the Path (Windows) below).
To install a specific version instead of the latest, replace latest/download with download/vX.Y.Z (see releases for available tags).
Direct Download
If you prefer, pick a version from the releases page, download manifest-cli_windows_x86_64.zip from its assets, then extract it and follow the same PATH steps above.
Installing generators (syft, trivy, cdxgen, etc.) on Windows is a separate step -- see Windows Installation (--native, No WSL Required) below.
Manual Installation
Download the pre-compiled binaries, .deb, .rpm, .apk, or .zip, from the releases page.
Copy them to the desired location or install them with the appropriate tools.
For Mac users, please note that the current release is not yet signed by Apple Developer. Therefore, you must enable it under Privacy & Security > Security > Open Anyway > Open.
For Windows users, follow the instructions in the Windows section instead.
Install script (Recommended)
To update to the latest version, simply run the install script again:
curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -sThe install script will automatically update your existing installation to the latest version.
To update to a specific version:
curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -s -- -b /usr/local/bin v0.14.8Note: This command pipes to sh, so it requires a POSIX shell (Linux, macOS, or Windows under WSL/Git Bash) -- it will not run in native PowerShell or Command Prompt. On native Windows, see Windows below instead.
Aptitude (apt)
sudo apt update
sudo apt upgrade manifest-cliHomebrew (tap)
brew upgrade manifest-cyber/tap/manifest-cliYum
sudo yum update manifest-cli- if running as admin, you can omit
sudo.
Windows
No WSL, Git Bash, or other POSIX shell required -- pick one of the methods below.
Scoop
scoop update manifest-cliPowerShell or Command Prompt
curl.exe -sSfLo manifest-cli.zip https://github.com/manifest-cyber/cli/releases/latest/download/manifest-cli_windows_x86_64.zip
tar -xf manifest-cli.zipReplace the existing manifest-cli.exe on your PATH with the extracted one.
To update to a specific version instead of the latest, replace latest/download with download/vX.Y.Z (see releases for available tags).
Direct Download
If you prefer, pick a version from the releases page, download manifest-cli_windows_x86_64.zip from its assets, then extract it and replace your existing manifest-cli.exe.
Manual Installation
Download the latest pre-compiled binaries, .deb, .rpm, .apk, or .zip, from the releases page.
Replace your existing installation with the new binaries or install them with the appropriate tools.
For Windows users, follow the instructions in the Windows section instead.
The install command can help you install supported generators that are required for generating SBOM with this tool
NOTE: On Windows, install uses a shell script by default and requires WSL or bash on the path. To install generators without WSL or a Unix shell, use --native -- see Windows Installation (--native, No WSL Required) below.
For an exhaustive list of arguments, see ARGUMENTS.md.
-d, --destination: Installation destination string (default "/usr/local/bin"; on Windows with --native, defaults to the directory containing manifest-cli.exe instead)
-g, --generator: Name of generator to install. Supported options: [syft|csbom|trivy|cdxgen|docker-sbom|spdx-sbom-generator|sigstore-bom] (default "syft")
--version: Installs specific version of the generator
--native: Install using a built-in Go downloader instead of a shell script. Available on all platforms; removes the WSL/Bash requirement on Windows.
Note: On Linux/macOS, the default destination (/usr/local/bin) is often owned by root. If it's not writable by your user, either run the command with sudo (a command that temporarily grants administrator-level permissions), or pass -d to a directory you own (e.g. -d ~/.local/bin, making sure it's on your PATH).
This command installs the generator globally.
manifest-cli install -g cdxgenInstalling generators on a machine without internet access
install downloads generators over the network, so it fails on a machine without internet access. You don't need it there: generate runs whichever generator binary it finds on your PATH, however it got there. To install a generator offline, copy its binary to the offline machine and put it in a folder on the PATH (see Adding a Folder to the Path (Mac/Linux)). Once it's there, generate has nothing to download for it, with or without --install-dependencies.
To install manifest-cli itself offline, see Manual Installation under Installation above.
Option 1: install on a connected machine, then copy. On a machine with internet access and the same OS and architecture as the offline machine, install each generator into a folder of its own:
manifest-cli install -g csbom -d ./offline-bin
manifest-cli install -g syft -d ./offline-binCopy the files in ./offline-bin to a folder on the offline machine's PATH (for example /usr/local/bin). This works for generators that install places in the -d folder, such as csbom, syft, and trivy. cdxgen installs through npm instead, so it doesn't end up in -d.
Option 2: download the release archive. On a connected machine, download the generator's release archive for the offline machine's platform, copy it over, extract the binary, and put it in a folder on the PATH.
For csbom, the archives on the csbom releases page are:
| Platform | Archive |
|---|---|
| Linux x86_64 | csbom_cli_manylinux_x86.tar.gz |
| macOS arm64 | csbom_cli_osx_arm64.tar.gz |
| Windows x86_64 | csbom_cli_windows_x64.zip |
# On the offline machine, in the folder you copied the archive to
tar -xzf csbom_cli_manylinux_x86.tar.gz
sudo cp bin/csbom /usr/local/bin/For syft, download the archive for your platform from the syft releases page and extract the syft binary the same way.
Generator versions: generate checks the installed version of syft, trivy, and cdxgen, and fails with an error such as syft version X is not supported, must be <= Y if it's newer than manifest-cli supports. When you download an archive yourself, pick a version no newer than that. Option 1 avoids the problem, because without --version, install picks a supported version of syft and trivy.
Installing generators on Windows without WSL (--native)
This section covers installing SBOM generators (syft, trivy, cdxgen, etc.) on Windows. To install manifest-cli itself on native Windows, see Manual Installation under Installation above.
By default, install downloads generators with a shell script, which requires WSL or bash. Pass --native to install using a built-in Go downloader instead -- no WSL, Bash, or other Unix shell required.
# Installs syft.exe next to manifest-cli.exe -- already on PATH, no extra setup
manifest-cli install -g syft --nativeIf you omit -d/--destination, the generator installs into the same directory as manifest-cli.exe, which is already on your PATH since that's where you're running manifest-cli from. If you pass a custom -d, add that directory to your Windows PATH manually before running generate.
By default, --native installs a supported version of each generator: syft, trivy, and cdxgen install a version manifest-cli has validated; spdx-sbom-generator, docker-sbom, and sigstore-bom fetch the latest release. To pin an exact version, add --version:
manifest-cli install -g syft -d .\bin --native --version v1.44.0Pass --native to generate as well, so it can find natively-installed generators on PATH automatically:
manifest-cli generate --generator syft --native ./my-projectGenerator support on Windows:
| Generator | --native |
Prerequisites | Notes |
|---|---|---|---|
| syft | Yes | None | |
| trivy | Yes | None | |
| spdx-sbom-generator | Yes | None | |
| docker-sbom | Yes | Docker Desktop | Always installs to %USERPROFILE%\.docker\cli-plugins\, regardless of -d |
| csbom | Always native | None | No --native flag needed |
| cdxgen | Yes (via npm) | Node.js and npm on PATH |
Runs npm install -g @cyclonedx/cdxgen |
| sigstore-bom | Install only | None | generate does not yet work on Windows -- see below |
sigstore-bom limitation: install --native works for sigstore-bom, but running generate --generator sigstore-bom currently fails on Windows due to a known upstream issue. Use WSL for sigstore-bom generation only, until it's fixed upstream.
The sbom command generates an SBOM on any number of targets (paths to source code, containers, etc.), using a specified open-source SBOM generator (our default is Syft). Make sure to install the relevant generators first before using them in the CLI (see the Generators section below).
It is essential that the generator installation location is part of the OS execution path.
To add a folder to the path in OSX or Linux, you can follow these steps:
- Open a terminal.
- Locate the folder you want to add to the path.
- Copy the path of the folder.
- Open the
.bashrcor.bash_profilefile in a text editor. This file is usually located in your home directory. - Add the following line at the end of the file, replacing
/path/to/folderwith the actual path of the folder you want to add:
export PATH="/path/to/folder:$PATH"- Save the file and exit the text editor.
- Restart your terminal or run the following command to apply the changes:
source ~/.bashrcTo add a folder to the path in Windows, you can follow these steps:
- Open the Start menu and search for "Environment Variables".
- Click on "Edit the system environment variables".
- In the System Properties window, click on the "Environment Variables" button.
- In the "System Variables" section, scroll down and select the "Path" variable.
- Click on the "Edit" button.
- Click on the "New" button and enter the path of the folder you want to add.
- Click "OK" to save the changes.
- Restart your terminal or any open command prompt windows for the changes to take effect.
Remember to replace /path/to/folder with the actual path of the folder you want to add.
For an exhaustive list of arguments, see ARGUMENTS.md.
-g, --generator: the generator to use (syft, csbom, trivy, cdxgen, docker-sbom, spdx-sbom-generator, sigstore-bom).
-p, --paths: [DEPRECATED: use positional arguments instead] the paths to local repositories, or name:version of a container, to scan.
-f, --file: filename for the output file.
-h, --help: Get help on how to use the cli.
-k, --api-key: Manifest API key, if publish is set to true.
-o, --output: SBOM format to use. Either cyclonedx-json or spdx-json.
-n, --name: Name of the generated SBOM. Overrides any existing version info.
--label: [DEPRECATED] use --asset-label instead. One or more labels to add to the SBOM. If the label does not exist, it will be created then applied to the SBOM. Use a single --label flag with comma delimited values, or multiple --label flag instances.
--product-id: Assign an SBOM to a product by providing a product ID. You may create products through the Manifest UI. To find a product's ID, open the product in the Manifest app and copy the identifier from the page URL: it is the segment between /product/ and /overview (for example, in https://app.manifestcyber.com/product/64b8f0a2e1d3c5a7b9f2e4d6/overview the product ID is 64b8f0a2e1d3c5a7b9f2e4d6). Only takes effect together with --publish, and requires a token carrying the product permissions listed under API Tokens for Publishing SBOMs.
--active={true|false}: Whether this SBOM should be marked as Active when uploading, if not present the default of your organization's setting will be used (which is typically true).
--asset-label: One or more labels to add to the SBOM's asset. If the label does not exist, it will be created. Use a single --asset-label flag with comma delimited values, or multiple --asset-label flag instances to add multiple labels to an asset.
--product-label: One or more labels to add to the product. If the label does not exist, it will be created. Use a single --product-label flag with comma delimited values, or multiple --product-label flag instances to add multiple labels to a product. You must send a valid --product-id in order for the --product-label values to be assigned properly.
--publish: true/false, whether to send the SBOM to your Manifest app tenant. This requires an API token (see more below). Default: false.
--enrich: none / ecosystems (case insensitive) Overrides your organization settings to force the SBOM to be enriched (ecosystems) or to skip enrichment (none)
--generator-preset: set generator config preset. (recommended, none)
--generator-config: set path to generator config file (if applicable)
--supplier: Supplier (organization) name to set on the root SBOM component (metadata.component.supplier) and the BOM metadata (metadata.supplier). For SPDX output this sets the package supplier, falling back to --group when unset.
--version: Version of the generated SBOM. Overrides any existing version info.
--: to pass through additional arguments to specific generators, use the -- separator at the end of the command, followed by any additional arguments.
To enable full visibility into software dependencies and vulnerabilities, we recommend integrators implement SBOM generation following the build stage of a CI/CD pipeline. However, if there are dependencies that are pulled in during runtime, then SBOM generation should follow after the testing stage. Doing so ensures that all dependent software and artifacts are properly captured in the resulting SBOM.
An example of a dependency that is pulled in during runtime would be Docker containers. These containers are referenced with static blueprints (Dockerfile and docker-compose) in the source code. However, to get visibility into those containers, they would first need to be built or already exist within a container registry. For working with containers, store the image name and tag of the containers used within a variable so they can be referenced in the sbom command. See the examples below for more details.
A general rule of thumb is that properly implemented SBOM generation within a CI/CD pipeline will almost always be more complete and accurate compared to an SBOM generated statically. In the cases where that is not true, the SBOMs are equivalent.
Regardless of whether or not the SBOM generation is implemented within a CI/CD pipeline, it is strongly recommended to use paths instead of specific files.
manifest-cli sbom ./manifest-cli sbom --asset-label=production --asset-label=java --generator=cdxgen --name=java-sbom --output=cyclonedx-json ./path/to/repo alpine:latest -- --type javamanifest-cli sbom --product-id=MY_PRODUCT_ID --product-label=production --product-label=golang --name=my-sbom --version=v1.0.0 --output=spdx-json --publish ./path/to/repoBe aware: Generating an SBOM by pointing to specific files is not recommended. Doing so may result in an incomplete SBOM.
manifest-cli sbom --generator=trivy ./route-to-file ./go.mod ./go.sum alpine:latestcsbom is a generator purpose-built for C and C++ projects. It works at the build-system and
source level to surface components that were compiled into a binary — including vendored
libraries, statically linked dependencies, and third-party SDKs that leave no trace in a
package manager.
Install csbom and run it against your project:
manifest-cli install -g csbom
manifest-cli generate --generator csbom -f sbom.json ./my-cpp-projectFor full details, flag reference, and workflow integration, see docs/csbom.md.
Use the merge command to merge two or more SBOMs of the same format.
For an exhaustive list of arguments, see ARGUMENTS.md.
The same arguments available for the sbom command are available for merge.
-i, --input-format: SBOM format of the inputs, either cyclonedx or spdx.
manifest-cli merge --input-format=cyclonedx --name=my-app scm-sbom.json image-scm.jsonThe workflow command executes a sequence of manifest-cli commands defined in a JSON file or
via a built-in preset. Each step maps to an existing command (generate, merge, publish,
install) using the same flags as the CLI — no new syntax to learn.
Use the built-in cpp preset for C/C++ projects with no configuration needed. It runs syft
and csbom against the same input path, then merges both results into a single CycloneDX 1.6
SBOM — giving you broad package detection and deep build-system analysis in one command:
manifest-cli workflow --preset cpp -f merged.json ./my-projectOr bring your own workflow file for full control over every step:
manifest-cli workflow --workflow-file workflow.json ./my-projectFor full details, all flags, and ready-to-use example files, see docs/workflow/WORKFLOW_FEATURE.md.
When you publish a new version of an asset, the previous versions stay active by default. Add --deactivate-older (-d) to mark prior versions of the same asset inactive as part of the same publish, so your inventory reflects only the version you just shipped:
export MANIFEST_API_KEY=your-api-token
manifest-cli publish sbom.json --deactivate-older--deactivate-older only affects other versions of the asset. The platform identifies an asset by its name and version, so publishing the same name and version again updates the existing asset instead of creating a new one, and the SBOMs already published for that version stay active alongside the new one. To have a republish replace what's active, give it a new version, for example with --version. If an SBOM has no version, Manifest uses a checksum of the file, so republishing an unchanged file counts as the same version.
By default this deactivates every older version of the asset. To narrow it to older versions carrying specific labels, add --deactivate-label (repeatable). Each value is matched against the asset's labels, and only matching older versions are deactivated. --deactivate-label requires --deactivate-older:
# Only deactivate older versions labeled "production" or "java"
manifest-cli publish sbom.json \
--deactivate-older \
--deactivate-label production \
--deactivate-label javaThese flags are available on the publish, sbom --publish, and merge --publish commands.
When an asset belongs to a product's inventory, --replace-in-product swaps the asset's prior version out of that product and puts the version you are publishing in its place, after the upload and vulnerability scan complete. This is useful when a product should track exactly one version of an asset. It requires --product-id to identify which product's inventory to update:
export MANIFEST_API_KEY=your-api-token
manifest-cli publish sbom.json \
--product-id YOUR_PRODUCT_ID \
--replace-in-productA snapshot tells the Manifest platform that a group of SBOMs represents the complete state of an environment or product at a single point in time. When you publish in snapshot mode, the platform runs a deactivation sweep on each upload: every asset in your organization that carries the snapshot label and was created before the snapshot timestamp is marked inactive. Assets left out of the snapshot, such as a retired service, are deactivated along with older versions. This keeps your inventory in sync with what is actually deployed, without you having to deactivate stale assets by hand.
Warning: The sweep matches assets by label name across your whole organization, not just one product, and it decides what is stale by when each asset record was first created. A pipeline that breaks the snapshot pipeline rules can silently deactivate current assets (including assets in other products) or leave old assets active indefinitely. Read those rules before wiring snapshots into CI.
Common uses are reconciling the live contents of a product or environment (e.g. payments-platform-prod) on each deploy or on a schedule, and retiring assets for services that have been removed from that product or environment.
Snapshot mode is enabled by passing both of these flags together:
--snapshot-label <label>: identifies the pipeline the SBOM belongs to. Use a name that is unique to one product's pipeline and will never change (e.g.payments-platform-prod). The label is also attached to each published asset.--snapshot-timestamp <timestamp>: an RFC3339 timestamp with an explicit UTC offset (e.g.2024-01-15T10:00:00Z). This is the start of the snapshot pass and the boundary the deactivation sweep uses. Compute it once per pass (see snapshot pipeline rules).
The CLI validates the timestamp before making any API call. It must be RFC3339 with an explicit UTC offset (a trailing Z for UTC, or an offset like -05:00), must not be in the future, and must not be more than 7 days in the past. Because of the 7-day limit, a pass can only be retried with its original timestamp within 7 days of that timestamp; after that, run a fresh pass. Passing one flag without the other fails validation; passing neither publishes the SBOM normally with no sweep.
These flags are available on the publish, sbom --publish, and merge --publish commands.
# Publish an existing SBOM as part of the payments-platform-prod snapshot
manifest-cli publish sbom.json \
--snapshot-label payments-platform-prod \
--snapshot-timestamp 2024-01-15T10:00:00Z
# Generate and publish in one step
manifest-cli sbom ./ -f sbom.json --publish \
--snapshot-label payments-platform-prod \
--snapshot-timestamp 2024-01-15T10:00:00ZIn CI, compute the timestamp once at the start of the pass and reuse it for every publish in that pass:
export MANIFEST_API_KEY=your-api-token
# Once, at the start of the pass. Persist this value (for example, as a
# pipeline output) so that a retry of this pass reuses it instead of
# generating a new one.
SNAPSHOT_TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
for sbom in sboms/*.json; do
manifest-cli publish "$sbom" \
--snapshot-label payments-platform-prod \
--snapshot-timestamp "$SNAPSHOT_TS" \
--version "$SNAPSHOT_TS"
doneDrop --version only if each SBOM's own version already changes on every build.
Note: The deactivation sweep only runs when snapshot mode is enabled. Snapshot mode and
--deactivate-olderserve different purposes:--deactivate-olderdeactivates prior versions of the same asset, while snapshots reconcile an entire environment or product against a point in time.
Follow all of these. Breaking any of them fails silently: the CLI reports success, and the damage shows up later as missing or duplicate active assets.
- Use one snapshot label per product pipeline, and never share it. The sweep deactivates matching assets across your whole organization;
--product-iddoes not narrow it. If two products publish with the same snapshot label, each product's run deactivates the other product's assets. Snapshot labels and asset labels share one set of label names, so don't use a snapshot label's name with--asset-labelor on assets in any other product. - Never rename the snapshot label. Label matching is exact and case-sensitive:
UAT,uat, andUatare three different labels (only leading and trailing spaces are ignored). After a rename, the first run finds nothing to deactivate under the new label, and assets from runs under the old label stay active permanently because no future run will carry that label again. If you must rename, contact Manifest support to clean up the previous generation. - Compute
--snapshot-timestamponce per pass, before the first upload, and pass the same value to every publish in the pass. Reuse that value on any retry of the pass. Generating a new timestamp for each publish (for example,$(date ...)inline in each command) makes each publish deactivate the assets that the earlier publishes in the same pass just created. - Give every asset a new version on every pass. The platform identifies an asset by its name and version. Publishing the same name and version again updates the existing asset instead of creating a new one, and that asset keeps its original creation time, which is before the new pass's timestamp. Every later publish in the pass then deactivates it (and, with
--update-product, removes it from the product) even though it is part of the current snapshot, so of the assets affected this way only the one published last stays active. If the version inside each SBOM already changes on every build (for example, a commit SHA or build number), this is handled. Otherwise, pass--versionwith a value unique to the pass, such as the snapshot timestamp itself. Don't rely on stable version strings (such as1.4.0for a service that hasn't changed) in a snapshot pipeline. If an SBOM has no version, Manifest uses a checksum of the file, so republishing an unchanged file counts as the same version. - Include every SBOM in every pass. Any asset under the label that isn't republished in a pass is treated as stale and deactivated. This is how retired services drop out, but it also means a pass that skips an SBOM deactivates that asset.
- Expect the previous generation to go inactive as soon as the pass starts. The sweep runs on each upload, before the platform has processed it, so the first upload of a pass deactivates the entire previous generation. Until the pass finishes, only the assets published so far are active. If a pass stops partway, it stays that way until you retry with the same timestamp.
- Don't run two passes with the same snapshot label at the same time. Overlapping passes race each other's sweeps, and which assets end up active depends on timing.
--asset-label has no effect on the sweep. It is a tag for filtering in the Manifest app, and only the snapshot label decides what gets deactivated. An asset published in snapshot mode carries both its asset labels and the snapshot label.
While snapshot mode reconciles your organization's asset inventory, --update-product reconciles a specific product's inventory to the same snapshot. After the upload completes, it removes from the product every asset that carries the snapshot label and was created before the snapshot timestamp, then adds the asset you are publishing. This keeps a product's inventory in sync with exactly what a given environment or product contains.
--update-product requires --product-id, --snapshot-label, and --snapshot-timestamp, and is mutually exclusive with --replace-in-product (use --replace-in-product for a single per-asset version swap, and --update-product for a full snapshot reconciliation).
When every asset in the pass carries a new version (see rule 4 in snapshot pipeline rules), only the first call removes anything, and later calls just add their asset. Without a new version, each call can remove assets that earlier calls in the same pass just added. To loop over every service in a deploy, compute the timestamp once and pass a per-pass --version:
export MANIFEST_API_KEY=your-api-token
# Compute the timestamp once for the whole pass, never inside the loop.
SNAPSHOT_TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
for sbom in service-a.json service-b.json service-c.json; do
manifest-cli publish "$sbom" \
--product-id YOUR_PRODUCT_ID \
--update-product \
--snapshot-label payments-platform-prod \
--snapshot-timestamp "$SNAPSHOT_TS" \
--version "$SNAPSHOT_TS"
doneThe removal deletes the product's inventory rows for the stale assets, so the previous generation disappears from the product view rather than appearing as inactive. The assets themselves stay in your organization's asset list, marked inactive by the snapshot's deactivation sweep. If you want previous versions to remain listed in the product as inactive, publish with --product-id and the snapshot flags but without --update-product.
Only assets whose record was created at or after the snapshot timestamp are safe from the removal. Publishing an SBOM with the same name and version as an existing asset updates that asset instead of creating a new one, and the asset keeps its original creation time, so later publishes in the same snapshot remove it. This is why the example passes a per-pass --version; see snapshot pipeline rules. Assets that don't carry the snapshot label are left untouched.
You will need cosign installed to proceed. Click here to get started.
Run the following command to generate a public-private key pair. Users will be prompted for a password which will be required for all attestations with this key.
This will result in two files being created: cosign.key and cosign.pub generated in the user's home directory.
cosign generate-key-pair --output-key-prefix ~/cosignTo generate a public-private key pair with a specific filename prefix:
cosign generate-key-pair --output-key-prefix=~/my-secret-keyIn this example, two files will be created: my-secret-key.key and my-secret-key.pub in the user's home directory.
To generate an SBOM with attestation using this key pair, two flags will need to be added: --attest and --key.
Simply include these two flags in any of the examples found in Quickstart to generate attestations.
manifest-cli sbom --attest --key my-secret-key.key ./This is also supported for merging SBOMs.
manifest-cli merge --attest --key my-secret-key.key sbom1.json sbom2.jsonGenerators must be installed in order for the cli to use them. Syft is the default generator. Keep in mind that not all generators work the same or create the same outputs, we will add more information here later on that.
Supported generators:
- syft
- csbom — C/C++ SBOM generator with static analysis across 19+ build system file types (CMake, Conan v1+v2, vcpkg, Meson, pkg-config, BitBake/Yocto, Makefile, VS linker maps, and more); enriches components with CPEs, PURLs, and licenses; outputs CycloneDX 1.6 or native csbom JSON
- trivy
- cdxgen
- docker-sbom
- spdx-sbom-generator
- kubernetes sigstore-bom (
sigstore-bom)
To create a new token:
-
In the Manifest App, go to the Settings page and click on the "API Tokens" section under "Account":

-
Fill out the form, add the required scope permissions, and then click "Create":

-
Once you have successfully created your key, copy it and save it in a secure location:

Remember to protect your API key! Avoid committing it to your source code or printing it as plain text. Instead, use secrets management tools to keep it secure 🧙.
The scopes you enable in step 2 must cover the flags you intend to use. Enable the scope(s) below for each operation (names match the checkboxes on the token creation screen):
| Flag / operation | Scope(s) to enable |
|---|---|
--publish (upload an SBOM) |
Manage SBOMs and VEX |
--product-id (assign an SBOM to a product) |
Manage products, Manage assets, and View all pages and data |
--replace-in-product |
Manage products, Manage assets, and View all pages and data |
--update-product (reconcile a product to a snapshot) |
Manage products, Manage assets, and View all pages and data |
--download-vdr |
View all pages and data |
Note: Use a user API token created from the API Tokens page on your profile (the flow shown above). The product operations (
--product-id,--replace-in-product,--update-product) wait for the upload's vulnerability scan to finish before attaching the asset, so they need View all pages and data (the read scope) in addition to Manage products and Manage assets. View all pages and data is also what covers--download-vdr.
The recommended way to use the API Key is via the MANIFEST_API_KEY environment variable. The -f flag is required in this case to ensure the file being uploaded has the correct .json file extension that is supported by the api.
export MANIFEST_API_KEY=your-api-token
manifest-cli sbom ./ -f sbom.json --publishHave any questions or need help? Don't hesitate to reach out: info@manifestcyber.com!