Safeguard
Supply Chain Security•

Swift 6.4 Ships SBOM Generation in SwiftPM: CycloneDX and SPDX

Swift 6.4, released 15 September, lets SwiftPM write CycloneDX 1.7 and SPDX 3.0 SBOMs. Here are the commands, what's included and what's still missing.

Safeguard Security Team
5 min read

On 15 September 2026 the Swift project released Swift 6.4. Among its package manager changes is SE-0509: Swift Package Manager can now generate software bills of materials in CycloneDX or SPDX format, either as part of swift build or from a new swift package generate-sbom subcommand.

Until now, Swift teams that needed an SBOM for a customer, a regulator or their own vulnerability tracking had to use third-party tools that parse Package.resolved. Having it in the toolchain means the SBOM comes from the same dependency graph the build used.

What's affected

Swift 6.4 and later toolchains. Nothing changes unless you ask for an SBOM.

Formats. cyclonedx (or cyclonedx1) maps to CycloneDX 1.7. spdx (or spdx3) maps to SPDX 3.0. Output is JSON only.

What goes in. Each component gets its type (application or library), name, version, Package URL, source repository URL and commit SHA, entity type (package or product) and scope (required or test). Dependencies cover package to package, package to product, and product to product relationships. Metadata records the SwiftPM version, timestamp and spec version.

Build graph or package graph. With --build-system swiftbuild, only components and dependencies actually used in the build are included. Without it, everything in the resolved package graph is included and SwiftPM warns that it used the package graph only. The generate-sbom subcommand always works from the module graph and warns accordingly.

What's not there yet. The proposal lists these as future work: license detection, file hashes, signing, per-target SBOMs, XML or YAML output, and merging SBOMs. SDKs, frameworks, precompiled headers and vendored binaries aren't included.

How to check if you're exposed

Here, "exposed" means shipping Swift software without an inventory you can hand to someone. Start by checking the toolchain:

swift --version

If it reports 6.4 or later, generate a first SBOM from the package graph without building:

swift package generate-sbom --sbom-spec cyclonedx

For an SBOM that reflects what was actually compiled, generate it during the build:

swift build --build-system swiftbuild --sbom-spec cyclonedx --sbom-spec spdx \
  --sbom-output-dir ./sbom

Then look at what you got. List the CycloneDX components and confirm every dependency you expect is there with a Package URL:

ls sbom/
for f in sbom/*.json; do
  jq -r 'select(.bomFormat == "CycloneDX") | .components[] | "\(.name) \(.version) \(.purl)"' "$f"
done

SwiftPM doesn't overwrite earlier SBOMs; it appends a timestamp to each file name, so clear the directory between runs if you only want the latest. Anything missing is a gap to note, especially binary targets and vendored code, which the proposal says aren't covered.

What to do now

  1. Add SBOM generation to release builds. Use the build-integrated form so the SBOM matches the build:
    swift build -c release --build-system swiftbuild --sbom-spec cyclonedx --sbom-output-dir ./sbom
    
    Or set it through the environment in CI: SWIFTPM_BUILD_SBOM_SPEC=cyclonedx and SWIFTPM_BUILD_SBOM_OUTPUT_DIR=./sbom.
  2. Decide whether a failed SBOM should fail the build. By default it does. --sbom-warning-only makes it a warning, which is fine while you adopt it but worth removing once it's stable.
  3. Keep Package.resolved current. For generate-sbom, --disable-automatic-resolution makes the command fail when the resolved file is out of date, so the SBOM can't drift from the lockfile.
  4. Fill the known gaps yourself. List XCFrameworks, binary targets and vendored code separately, and add license data from another tool until SwiftPM supports it.
  5. Feed the SBOM to vulnerability tracking. A CycloneDX file with Package URLs can be imported by most SCA tools and matched against advisories.
  6. Don't run with --target. The proposal says --sbom-spec can't be combined with it and the build will error. Use --product to scope instead.

Why it matters

SBOM requests now arrive from customers and through procurement rules, and for many ecosystems the answer has been "we'll use a third-party tool." Native generation means the SBOM is produced by the component that resolves dependencies, which removes a whole class of parsing mismatches.

It also moves Swift closer to the inventory-first model other ecosystems are adopting. An inventory is what turns a new advisory into a quick question with a quick answer: do we ship that version, and where? The missing pieces, especially hashes and licenses, matter for some compliance uses, so treat Swift 6.4's SBOM as a solid start rather than the whole job.

Try it yourself

Generate both formats for one Swift package, once with swift package generate-sbom and once with swift build --build-system swiftbuild. Compare the component counts. Any difference shows packages that are resolved but not built, which is useful to know when you decide what to report.

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

The free scan at gold.safeguard.sh/scan accepts CycloneDX and SPDX SBOMs, runs in your browser without a login, and keeps the file on your machine. It handles up to 100 dependencies per scan.

Quick check

Which CycloneDX and SPDX versions does SwiftPM in Swift 6.4 produce?

CycloneDX 1.7 and SPDX 3.0, in JSON.

Does the SwiftPM SBOM include license information or file hashes?

Not yet. SE-0509 lists license detection, hashes and signing as future work.

Why might swift build with swiftbuild produce fewer components than generate-sbom?

With the Swift Build backend, only components and dependencies used in the build are included. The subcommand uses the full resolved package graph.

Sources

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.