SIGIL vs Anchore Syft

Syft 1.38 added a GGUF cataloger that emits CycloneDX ML-BOM components — the closest mainstream tool to SIGIL on the AI-BOM axis. This is what each tool covers, where they overlap, and where they don't.

Pick Syft when

You need general-purpose SBOM coverage across packages, OS layers, language ecosystems, container images, and now GGUF model files. CycloneDX 1.6 is a hard requirement. Your AI artifacts live as standalone .gguf files on disk or inside vnd.docker.ai.gguf.v3 OCI layers.

Pick SIGIL when

Your local AI runs through Ollama (~/.ollama/models/), you need every blob's SHA-256 verified against the manifest digest, you want the runtime's listening sockets attributed from /proc, you need SPDX from the Ollama license layer, and you want a deterministic PASS/WARN/FAIL verdict from a policy, with a completeness that says whether everything required was seen — no LLM in the path.

Axis-by-axis

Each row is a piece of evidence that ends up — or doesn't — in the resulting BOM artifact.

AxisSyft 1.45 (gguf-cataloger)SIGIL
Output formatCycloneDX 1.6 / 1.7, SPDXThe session (sigil-session/1) and AI-BOM v2 (sigil-aibom/2), JSON with JSON Schemas, plus Markdown
Local sourceFilesystem walk for .gguf files~/.ollama/models/ manifest walk
OCI sourceapplication/vnd.docker.ai.gguf.v3Ollama manifest layers (model / config / params / license)
Integrity checkGGUF header magic + format versionStreaming SHA-256 of every blob vs. manifest digest
License detectionLicense field from GGUF metadata when presentSPDX id from Ollama license layer — 10 families by shortname or body match
ProvenanceGGUF metadata fields (name, source URL)registry / namespace / model / tag tuple parsed from manifest path
Runtime exposureOut of scopeObserve mode: the listener held by ollama serve, found through its fd table; bind class from the address (loopback / wildcard / private / global)
Native binary capabilityOut of scopePlanned: call-site evidence in the runtime's binaries (M1)
VerdictNone (inventory-first)PASS / WARN / FAIL from findings and a TOML policy, with completeness (COMPLETE / INCOMPLETE) beside it; no LLM
Subprocess spawnYes for some catalogersNone — /proc parsed directly
Network egressYes when pulling OCI / matching vulnsNone, unless the active API probe is asked for (one request to a literal address)
Language / distributionGo, single static binaryRust, a single CLI binary

The gap that matters: Ollama OCI manifests

Syft's OCI AI source resolves layers tagged application/vnd.docker.ai.gguf.v3 — Docker's AI image format. Ollama ships a different OCI layer schema (application/vnd.ollama.image.model, application/vnd.ollama.image.license, and friends) and a different on-disk layout (~/.ollama/models/manifests/<registry>/<namespace>/<model>/<tag>). Syft as of 1.45 does not parse it.

SIGIL parses the Ollama manifest, walks each referenced blob, streams SHA-256, and reports any digest mismatch as a FAIL finding tied to the model and tag.

Specification example (golden example 14, tool.version 0.0.0-example), not a real system. An excerpt of SIGIL's AI-BOM v2 Markdown, as it is written:

# SIGIL AI-BOM

| AI\-BOM |  |
|---|---|
| Schema | sigil\-aibom\/2 |
| Mode | observe |

## Outcome

**Verdict:** PASS · **Completeness:** COMPLETE

## Listeners

| Listener | Address | Port | Owner |
|---|---|---|---|
| listener\:tcp\/127\.0\.0\.1\:11434\#7001 | 127\.0\.0\.1 | 11434 | process 4242 \(start 1000\) |

## Models

| Model | Name | Provenance | Layers | License |
|---|---|---|---|---|
| model\:models\/registry\.ollama\.ai\/library\/m\/latest | m\:latest | registry\.ollama\.ai\/library\/m\:latest | 3 \(found 3\, absent 0\, unresolved 0\, not looked up 0\) | MIT |

Standard schema vs. versioned schemas

CycloneDX gives Syft broad ecosystem interop — vulnerability scanners, viewers, registries, and policy engines speak it. That is real value.

SIGIL writes its own versioned formats: the session (sigil-session/1) and the AI-BOM v2 (sigil-aibom/2), each with a JSON Schema in the repository. The session is canonical JSON, so the same input gives the same bytes, and the Markdown and the AI-BOM are rendered from it. The tradeoff is narrower interop today; the upside is a format small enough to review end-to-end and stable enough to diff across review cycles.

Verdict path vs. inventory

Syft answers "what is here". SIGIL also answers "and is it acceptable, right now", and "was everything required actually seen". Findings come from deterministic analyzers, and each is decided by a policy (TOML) — never by an LLM, never by a remote service.

Use both

They are complementary, not exclusive.

When SIGIL is the wrong choice

If you are not running a local LLM runtime, or your AI runs entirely against hosted APIs (OpenAI / Bedrock / Vertex), SIGIL has nothing to inspect today. If you need CycloneDX output for a downstream tool, run Syft and revisit SIGIL when the CycloneDX export path lands. If your model store is plain .gguf files outside of any Ollama install, Syft is the right tool right now.

Sources

Facts above are checked against the linked code and releases.