Safeguard
Supply Chain Security•

Generate and share an SBOM with customers using Safeguard

Generate an SPDX SBOM with safeguard sbom, validate it, scan it, then share it from Safeguard with view or download access, expiring links and VEX notes.

Safeguard Security Team
19 min read

To share an SBOM with a customer, generate it for the release they run with safeguard sbom, check it with safeguard validate --strict and scan it, then share it from Safeguard with view or download access, an expiring link or a customer portal. Add a VEX document for findings that do not affect them.

The assistant that helps you do this can run on the plan you already have. Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. You can also connect Claude or ChatGPT to the Safeguard MCP server and ask about your SBOMs from the chat you already use.

This guide uses a sample service called payments-api at version 1.8.0 and walks through every step, from the first command to the email your customer receives.

What you will have at the end:

  • An SPDX JSON SBOM for one named release, generated on your own machine.
  • A validation report that shows the file meets its format specification.
  • A vulnerability and licence picture of that SBOM, so nothing in it surprises you after you send it.
  • A shared copy in Safeguard with the right permission level, expiry and access controls, and a record of who opened it.
  • A VEX document that tells the customer which findings do not affect your product, and why.
  • A routine to repeat on every release.

What a customer expects from an SBOM

Most requests come from a security or procurement team that wants to answer two questions: what is inside the software they are buying, and are they exposed when the next advisory lands. An SBOM answers the first. A scan of the SBOM and a VEX document help with the second.

The common reference point in the US is the 2021 NTIA report, The Minimum Elements for a Software Bill of Materials. It lists seven data fields for each component:

Data fieldWhat the NTIA report means
Supplier nameThe entity that creates, defines and identifies the component
Component nameThe name the original supplier gives the unit of software
Version of the componentThe supplier's identifier for a change from a previous version
Other unique identifiersIdentifiers such as CPE, SWID tags or Package URLs (PURLs)
Dependency relationshipThat an upstream component X is included in software Y
Author of SBOM dataWho created the SBOM data for this component
TimestampWhen the SBOM data was assembled

The same report names three formats for automation: SPDX, CycloneDX and SWID tags. It also sets out practices that shape how you share, and three of them matter most here:

  • Frequency. A new build or release needs a new SBOM, and if you find an error you should issue a revised one.
  • Distribution and delivery. SBOMs "should be available in a timely fashion to those who need them and must have appropriate access permissions and roles in place."
  • Access control. Some suppliers publish SBOMs openly; others "may wish to keep this data confidential, and limit access to specific customers or users."

CISA has since published 2026 Updates to Minimum Elements for a Software Bill of Materials (SBOM), which adds data fields, practices and processes. If a customer cites it, read their exact requirement before you generate anything.

The two formats you will meet most often are SPDX and CycloneDX:

SPDXCycloneDX
StandardISO/IEC 5962:2021ECMA-424
Maintained byThe SPDX projectOWASP Foundation, standardised through Ecma TC54
SerialisationsJSON, YAML, tag-value and RDFJSON, XML and Protocol Buffers
VEXPaired with a separate VEX document, such as OpenVEX or CSAFSupports VEX use cases in the format itself
Safeguard CLIsafeguard sbom writes SPDX JSON; validate checks JSON, YAML, tag-value and RDFvalidate checks JSON and XML
Safeguard platformDownload as SPDX JSONDownload as CycloneDX JSON

If a customer does not name a format, ask. If they still do not mind, SPDX JSON from the CLI is a sound default, and the platform can give you CycloneDX JSON from the same SBOM.

Before you start

Install the Safeguard CLI. It is one static binary for macOS, Linux and Windows, x86_64 or arm64 (Windows is x86_64 only), with no Node, Python or JVM needed.

# macOS and Linux
curl -fsSL https://cli.safeguard.sh/install | bash

# Windows PowerShell
irm https://cli.safeguard.sh/install.ps1 | iex

Run safeguard, type /login and finish in the browser. On a server, our guide to installing the CLI on Linux covers the details.

Then make three decisions before you run a single command:

  1. What are you describing? A customer who runs your container needs an SBOM of the image, which includes operating system packages. A customer who embeds your library needs an SBOM of the source tree. Pick the artifact they actually receive.
  2. Which version? Check out the release tag, not your working branch. An SBOM for code the customer never received helps nobody.
  3. Who gets it? One contact, a whole security team, or every customer on a plan. That decides whether you share directly, by link or through a portal.

Step by step: generate, check and share

Step 1. Check out the release

cd ~/code/payments-api
git fetch --tags
git checkout v1.8.0

Make sure dependencies are locked. An SBOM built from a project without a lockfile can list ranges instead of the versions you shipped.

Step 2. Generate the SBOM

For the source tree:

safeguard sbom --dir . --output payments-api-1.8.0.spdx.json

For the container image you ship:

safeguard sbom --image registry.example.com/team/payments-api:1.8.0 \
  --output payments-api-1.8.0-image.spdx.json

safeguard sbom writes an SPDX JSON SBOM using the same Syft based path the scanner uses, and stops before vulnerability analysis. With no flags it describes the current folder and writes NAME-sbom.json next to you. For a private registry, add --registry-username and --registry-password, read from environment variables.

Put the version in the file name; it is often the only context that travels with the file.

Step 3. Validate the file

safeguard validate payments-api-1.8.0.spdx.json --strict -o validation-report.json

safeguard validate checks CycloneDX (JSON and XML), SPDX (JSON, YAML, tag-value and RDF) and VEX (CSAF and OpenVEX) documents against their specifications. --strict treats warnings as errors, which is what you want for anything leaving the company. -o writes the report to a file you can keep with the release. If you have a folder of SBOMs for several services:

safeguard validate ./sboms --recursive --strict --report-format text

Step 4. Scan the SBOM before it leaves

Your customer will almost certainly run the SBOM through a scanner. Do it first.

safeguard scan --sbom payments-api-1.8.0.spdx.json

safeguard scan --sbom detects SPDX or CycloneDX automatically, matches components against vulnerability databases and writes results under ./output, in a folder per scan. vuln.json holds the vulnerabilities and license.json the licences. When you are signed in, the SBOM and findings are uploaded to your Safeguard project; your source code is not.

Then ask the assistant for a summary you can act on:

safeguard
Read the latest scan of payments-api-1.8.0.spdx.json. List high and
critical findings with the fixed version, and list any licences that
need attribution in our customer notice.

If the scan turns up something you can fix quickly, fix it and cut a patch release before you share, rather than sending an SBOM with a known problem. The recorded session below shows that loop on this sample project: the assistant reads the finding, the files and the advisory, asks before each command, edits package.json, runs npm install and npm test with your approval, and prints a summary with a suggested commit message. It pushes nothing.

Click through it at your own pace, or open it full screen.

After a fix, go back to step 2 for the new version. Every release gets its own SBOM.

Step 5. Review the SBOM in Safeguard

Open the SBOM in the Safeguard platform. A signed in scan puts it in your project; you can also upload a file manually to the SBOM repository and choose its format. The review page gives you what a customer's security team will look at:

  • Compliance. EO 14028 status and NTIA elements.
  • Components. The full list with versions, package URLs and supplier data.
  • Vulnerabilities. CVEs with severity, CVSS scores, fix availability and exploitation status.
  • Licenses. Licence types, compatibility analysis and attribution requirements.
  • Quality. A completeness score, missing fields and data quality issues.

Read the Quality tab twice. Missing supplier names and missing versions are the gaps customers notice first, and they are much easier to fix before you share than after.

Step 6. Choose the format your customer asked for

From the platform you can download the SBOM as the original file, as CycloneDX JSON or SPDX JSON (converted if needed), as a CSV component list, or as a formatted PDF report. Select several SBOMs and use Export Selected to download them together as an archive.

Send the machine readable file the customer asked for, and add the PDF only when a person will read it.

Step 7. Share it with the right access

The sharing options in the Safeguard portal cover three cases.

One contact or a small team. Select the SBOM, click Share, enter the recipients' emails, choose a permission level, add a message and send. Recipients get an email invitation. The permission levels are:

  • View. View the SBOM online only.
  • Download. View and download.
  • Full. View, download and re-share.

Start with View or Download. Full lets the recipient pass it on, which is rarely what an NDA intends.

A wider group. Select the SBOM and click Create Link. Set an expiration date, a download limit, password protection and format restrictions, then generate the link and send it. Expiring links suit a procurement review that has a deadline.

Many customers over time. In Settings, Customer Portal, configure branding and your domain, assign the SBOMs to publish, and invite customers to register. Each customer then finds the current SBOM in one place instead of searching old email threads.

Tighten the defaults once at the organisation level: require authentication, restrict sharing to approved domains, set a default expiry, and turn link sharing on or off. Per SBOM, you can override those defaults, require NDA acceptance and turn on download notifications.

Safeguard records who accessed which SBOM, download history and link usage. If a contract ends, open the SBOM's sharing settings, find the user or link and click Revoke; access ends immediately. To send a set of SBOMs at once, select them in the repository and use Share Selected.

Step 8. Add a VEX document

A raw SBOM scan will list vulnerabilities in components your product includes but never uses in a way that matters. Without context, your customer's team has to ask about each one. A VEX document answers in advance. CISA describes VEX as "an attestation, a form of a security advisory" that says whether a product is affected by known vulnerabilities.

OpenVEX is one of the simplest formats to write by hand. Its specification defines four statuses: not_affected, affected, fixed and under_investigation. A not_affected statement needs a justification or an impact statement, and the justifications are component_not_present, vulnerable_code_not_present, vulnerable_code_not_in_execute_path, vulnerable_code_cannot_be_controlled_by_adversary and inline_mitigations_already_exist.

A minimal document looks like this. Replace the placeholders with the vulnerability ID from your scan and the package URL from your SBOM:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://example.com/vex/payments-api-1.8.0-001",
  "author": "Example Corp Product Security",
  "timestamp": "2026-10-21T09:00:00Z",
  "version": 1,
  "statements": [
    {
      "vulnerability": { "name": "VULNERABILITY-ID-FROM-YOUR-SCAN" },
      "products": [
        { "@id": "pkg:npm/payments-api@1.8.0" }
      ],
      "status": "not_affected",
      "justification": "vulnerable_code_not_in_execute_path"
    }
  ]
}

Validate it the same way as the SBOM:

safeguard validate payments-api-1.8.0.vex.json --strict

Then upload it in Safeguard under Integrations, filtered by Upload, on the Upload CSAF/VEX card. The upload accepts CSAF 2.0, CycloneDX VEX, OpenVEX and the CSAF VEX profile, and the file is validated on upload. Set the project name and version to match the SBOM so the two stay together.

Only mark something not_affected when you can explain why. If the platform shows reachability analysis for your project, use it as evidence, and write a short impact statement a reviewer can check. If you are not sure yet, under_investigation is an honest answer.

Step 9. Repeat on every release

The NTIA report is plain about frequency: a new build or release needs a new SBOM. Make it part of the release job rather than a task someone remembers.

safeguard ci scan --local --wait --fail-on high
safeguard sbom --dir . --output "payments-api-${VERSION}.spdx.json"
safeguard validate "payments-api-${VERSION}.spdx.json" --strict

safeguard ci scan --local scans the checkout on the CI runner and uploads only the results, never the source, with no SCM integration needed. With --wait --fail-on high the job stops on a high or critical finding before you publish anything. In CI, authenticate with a secret key that has the scans:trigger scope (and scans:read for --wait), stored as SAFEGUARD_API_KEY. Our guide to running the CLI in CI with safeguard exec shows full pipeline examples.

Do the work properly with the Safeguard CLI

Generating an SBOM is one command. The work around it, fixing what the scan finds, writing the customer note, checking licences, answering follow-up questions, is where an assistant that knows your Safeguard data earns its place.

Install and first session

Install with the command for your platform, run safeguard, then /login. /scan . scans the folder you started in. Type @ to attach a file from that folder, for example @payments-api-1.8.0.spdx.json, so the assistant reads exactly the SBOM you mean. /resume picks up the last session in the folder tomorrow.

Writing and fixing code

The assistant has tools for your local files and for your Safeguard data. It can write files, edit code and run commands, so it can bump a dependency, run the tests, regenerate the SBOM and draft the VEX statement. When the local runner runs platform scan jobs, your source code never leaves the machine; only SBOMs and findings are uploaded.

Use your Claude, ChatGPT or Codex plan

Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. /model shows or switches the model, and the CLI docs cover connecting one.

Approvals

Tools that change things ask before they act, according to /permissions:

  • Ask. Reads run; edits and commands ask first.
  • Accept edits. Edits in this folder and read only commands run; other commands ask.
  • Plan. Read and plan only. Good for "explain what this SBOM contains" sessions.
  • Auto. Read only commands and what the policy allows run; anything else asks. The default.
  • Strict. Pre-approved actions only, for CI.

A --yolo flag approves everything; keep it for throwaway sandboxes.

CI with safeguard exec

safeguard exec runs one assistant turn with no prompts and exits, in strict mode by default, and only inside a git repository. A release job can use it to draft the customer note:

safeguard exec "Summarise the high and critical findings for this release \
and the licences that need attribution, in plain English for a customer."

Add --output-format json when another step needs to read the result.

Hand the work to your computer from the desktop app

You do not have to sit at the terminal for any of this. A CLI session is live: it shows in the web app, the desktop app and the phone app, and those apps can send work to a computer running the CLI. The recorded desktop session below shows the CLI session in the desktop app's conversation list, "2 connected" for the computer, the browser and Safeguard cloud, a request for work on your computer that asks which computer and folder, and Approve or Deny on each command and file edit, ending with the upgrade done and tests passing.

Click through it at your own pace, or open it full screen.

The desktop app runs on Windows, macOS and Linux, and the download page also lists iOS and Android apps, IDE extensions and a browser extension. See our desktop app guide for setup. When a customer's follow-up questions arrive while you are away from your desk, you can connect ChatGPT to the Safeguard MCP server and ask about the SBOM from there.

Troubleshooting

The SBOM lists fewer components than expected. Check that you generated it from the release tag with dependencies locked and, for containers, from the image rather than the source. An SBOM of the source will not include operating system packages from the base image.

safeguard validate reports errors on a file from another tool. Run it without --strict to see which messages are errors and which are warnings, then fix the generator settings. Force the format with -f if detection guesses wrong, for example -f cyclonedx-xml.

The customer's tool rejects the file. Ask which format and version it expects. Download the matching format from the platform, then validate it before you send it.

The VEX upload fails. The upload page lists three causes: invalid JSON, a schema validation failure from missing fields, or an unsupported VEX format. Run safeguard validate on the file first; it checks OpenVEX and CSAF.

The image SBOM fails on a private registry. Pass --registry-username and --registry-password, and check that the token can pull.

Common mistakes

  • Sending an SBOM of main. Generate it from the release the customer actually runs, and put the version in the file name.
  • Skipping your own scan. The customer will scan it. Know what they will see before they see it.
  • Granting Full access by default. Full lets the recipient re-share. View or Download fits most NDAs.
  • Sharing links with no expiry. Set a date and a download limit. Revoke links when a review ends.
  • Marking findings not_affected without evidence. A VEX statement is an attestation. Use a justification you can defend and an impact statement a reviewer can check.
  • Generating once and forgetting. A new release needs a new SBOM. Put generation and validation in the release job.
  • Ignoring licence findings. Customers' legal teams read SBOMs too. Check license.json and the Licenses tab for attribution requirements before you send.

FAQ

Which SBOM format should I send?

The one the customer asks for. If they have no preference, SPDX JSON from safeguard sbom is a sound default, and the platform can give you CycloneDX JSON or SPDX JSON from the same SBOM, plus CSV and a PDF report.

Does generating an SBOM upload my source code?

No. safeguard sbom writes a file on your machine. A signed in safeguard scan uploads the SBOM and findings to your project, and when the local runner runs platform scan jobs, your source code never leaves the machine.

Can I keep using my Claude, ChatGPT or Codex subscription for this?

Yes. Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. You can also connect Claude or ChatGPT to the Safeguard MCP server and ask about your SBOMs from that chat.

How do I stop a customer from forwarding the SBOM?

Share with View or Download permission rather than Full, require authentication, require NDA acceptance for that SBOM, and turn on download notifications. Access tracking shows who opened it.

What happens when a customer contract ends?

Open the SBOM's sharing settings, find the user or link and click Revoke. Access ends immediately.

Do I need a VEX document as well?

It is not required by the NTIA minimum elements, but it saves a lot of back and forth. A VEX statement tells the customer which listed vulnerabilities do not affect your product and why, so their team does not have to ask about each one.

How often should I regenerate the SBOM?

For every new build or release you ship, and whenever you find an error in one you already sent. That is the NTIA frequency practice.

Can I share SBOMs for many products at once?

Yes. Select them in the repository and use Share Selected to share them together, or Export Selected to download them as one archive.

Try it yourself

Set up the runner on your own machine, pick the platform, start it, approve it with its device code, then use the same CLI to scan from the terminal:

Click through it at your own pace, or open it full screen.

Then download the Safeguard CLI, generate an SBOM for your latest release, validate it and scan it before your next customer asks. Every command is in the CLI docs.

Quick check

Which command checks an SBOM or VEX file against its specification?

safeguard validate. It checks CycloneDX, SPDX and VEX (CSAF and OpenVEX) documents, and --strict treats warnings as errors.

Which permission level lets a recipient re-share your SBOM?

Full. View allows online viewing only, and Download allows viewing and downloading.

Name two of the seven NTIA minimum data fields.

Any two of supplier name, component name, version of the component, other unique identifiers, dependency relationship, author of SBOM data and timestamp.

Sources

Last reviewed: 21 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.