Safeguard
Software Supply Chain•

How do you generate an SBOM for an Elixir project?

Add the EEF-backed sbom Mix task as a dev dependency and run it to get CycloneDX output. Includes the dev-only rule, what it misses, and CI steps.

Safeguard Security Team
4 min read

For an Elixir project, add the sbom package from the Erlang Ecosystem Foundation's security working group as a development-only dependency, run its CycloneDX Mix task, and store the output with each release. Never run it under the production Mix environment, because the dependency is not installed there.

What does the tool do?

The mix_sbom project, hosted by the EEF, generates a Software Bill of Materials for Mix projects in CycloneDX format. It reads your project's dependencies, resolved through mix.lock, and writes a machine-readable inventory. Its README gives an example dependency entry with the only: :dev and runtime: false options.

Those options are there on purpose. The maintainers recommend them to keep the SBOM tooling out of production deployments, and warn against running the task with the production environment set, since the dependency will not be available there.

Where do packages come from?

Elixir dependencies mostly come from Hex, though a mix.exs file can also point at Git repositories and local paths. The SBOM should show each one with its resolved version. Git dependencies deserve attention: a branch reference is a moving target, so pin them to a commit.

The lock file matters as much here as in any language. mix.lock records exact versions, so commit it, and generate the SBOM after dependencies are fetched from it.

What does it miss?

An Elixir release bundles the Erlang runtime. The BEAM and OTP version that run your code carry their own advisories, and a dependency-level SBOM will not list them. Record the OTP and Elixir versions beside the SBOM, and scan the container image if you ship one.

Native extensions are another gap. A NIF written in C or Rust pulls code the Mix task may not describe in depth.

A constructed example

A team runs a Phoenix API. An advisory lands for a JSON library. The engineer opens the stored SBOM for the live release, finds the library at a vulnerable version as a transitive dependency of an HTTP client, and learns it arrived through a package nobody chose directly. Without the SBOM, that search is a manual walk through the lock file.

How do you use the SBOM once you have it?

Store the file with each release and run it through a vulnerability scan on every build. When an advisory names a Hex package, search your stored SBOMs for it. That answers which releases contain the package, in minutes, and tells you which deployed services need a patch. Keep the previous release's file too, because comparing two SBOMs shows exactly which packages a release added.

What about umbrella projects?

An umbrella project contains several applications with their own dependencies. Generate an SBOM per application you deploy, not only for the umbrella root, so each service's inventory matches what it ships.

How to check or apply this

  1. Add the sbom dependency to the dev environment only, with runtime set to false.
  2. Run mix deps.get from a committed mix.lock.
  3. Run the CycloneDX task in the dev environment and write the file to your build output.
  4. Pin any Git dependencies to a commit.
  5. Record Elixir and OTP versions with the SBOM, and scan the release image.
  6. Run the step in CI for every release and keep the file with the artifact.
  7. Scan the SBOM against vulnerability data and review new findings per release.

Safeguard ingests CycloneDX files and scans dependencies, so the output of this task can feed a policy check.

Quick check

Can I run the SBOM task in a production build?

Not in the production Mix environment. The maintainers advise dev-only installation, so run it in a dev build step.

Does the Mix task list the Erlang runtime?

Not as a dependency. Record the OTP and Elixir versions separately.

Sources

Last reviewed: 18 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.