Skip to content

feat(release): generate SBOMs with real crate dependencies#98

Merged
ben-miru merged 1 commit into
mainfrom
feat/auditable-sboms
Jun 29, 2026
Merged

feat(release): generate SBOMs with real crate dependencies#98
ben-miru merged 1 commit into
mainfrom
feat/auditable-sboms

Conversation

@ben-miru

@ben-miru ben-miru commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Why

Release SBOMs list only the top-level package — no dependency inventory — making them useless for vulnerability scanning. Follow-up to #97, which added cargo-auditable + a wrapper to the builder image. This PR wires it into the release and fixes what syft scans.

What

  • builds.agent.tool: cargo-auditable-zigbuild — the wrapper baked into the builder image (feat(builder): add cargo-auditable to the builder image #97). With command: zigbuild, goreleaser runs cargo-auditable-zigbuild zigbuild --target=… --release -p=miru-agent, i.e. cargo auditable zigbuild …. Each binary then embeds its full dependency tree in a .dep-v0 ELF section.
  • sboms: scan binary + archive, not package. syft reads the .dep-v0 section straight out of the binary, and recurses into the tar.gz to find it — both list every linked crate. A .deb scan only reads DPKG control metadata and never inspects the nested binary, so it could never enumerate dependencies.
  • build/Dockerfile: bump the pinned builder image to 43e2c5b — the image published after feat(builder): add cargo-auditable to the builder image #97 merged (verified to contain cargo-auditable and the wrapper).

Why drop the .deb SBOM

I tested this empirically in the builder image. syft scanning an auditable binary inside a .deb returns only the package record (2 entries, no crates); the same binary scanned directly, or inside a tar.gz, returns the full crate list. So the SBOM source has to be the binary/archive. The published SBOMs now cover the binaries (the exact bits shipped inside both the archives and the .debs) and the archives.

Note

If a downstream consumer specifically needs a *.deb-named SBOM file, say so and I'll keep a package entry but repoint its syft invocation at the binary instead of dropping it.

Validation

  • goreleaser check passes against the new pinned image (43e2c5b).
  • Confirmed the published agent-builder:43e2c5b image contains cargo-auditable and the wrapper.
  • End-to-end in that image: the wrapper, invoked exactly as goreleaser assembles it (cargo-auditable-zigbuild zigbuild --target=… --release), produces a binary with a .dep-v0 section, and syft surfaces the embedded crate (itoa) from both the raw binary and a tar.gz of it — but not from a .deb.

The first real release tag after this merges will be the live confirmation; the SBOM that previously showed one package should then list the agent's crates.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

Build release binaries through cargo-auditable and point syft at content it
can actually read, so the published SBOMs enumerate every linked crate
instead of just the top-level package.

- builds.agent.tool: cargo-auditable-zigbuild — the wrapper baked into the
  builder image, which runs `cargo auditable zigbuild ...`. Each binary then
  carries its dependency tree in a `.dep-v0` ELF section.
- sboms: scan `binary` and `archive` instead of `package`. syft reads the
  `.dep-v0` section out of the binary (and recurses into the tar.gz to find
  it). A .deb scan only reads DPKG control metadata and never inspects the
  nested binary, so it could never list dependencies — verified empirically.
- build/Dockerfile: bump the pinned builder image to 43e2c5b, the image
  published after #97 added cargo-auditable and the wrapper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ben-miru ben-miru merged commit 1e2501f into main Jun 29, 2026
3 checks passed
@ben-miru ben-miru deleted the feat/auditable-sboms branch June 29, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant