#5129·syft

Add catalogers for Ansible collections and roles

Author: jrjsmrtnCreated Jul 30, 2026Updated Sep 14, 2026
Labelsneeds-proposal

What would you like to be added:

Catalogers for Ansible content — Galaxy collections and legacy roles.

Following the existing declared/installed convention, this would be up to three catalogers:

Cataloger Tags Source
ansible-collection-cataloger installed ansible_collections/<ns>/<name>/
ansible-role-cataloger installed roles directory
ansible-requirements-cataloger declared requirements.yml

Why is this needed:

Ansible is infrastructure-as-code with the same supply-chain obligations as any dependency graph, and it's currently invisible to syft — an Ansible control node's collections and roles don't appear in an SBOM at all. Teams shipping or operating infrastructure built with Ansible have a hole in their inventory that nothing fills today.

The closest precedents in syft are terraform-lock-cataloger and github-actions-usage-cataloger, so IaC content isn't new ground here.

One thing that makes this a better fit than it might look: installed collections carry per-file checksums. ansible-galaxy writes MANIFEST.json (namespace, name, version, dependencies, license) and FILES.json (sha256 for every regular file) into each installed collection — and it does so uniformly, because collections installed from a git source are built into an artifact before installation. In a sample I measured, community.general had sha256 for 3290/3290 regular files.

So an Ansible cataloger could populate both installed and declared sides, where terraform-lock-cataloger is declared-only. That's better coverage than the nearest precedent achieves.

Additional context:

Two things I'd want maintainer input on before writing code, because they affect the output contract:

1. Component identity — there's no registered purl type yet.

package-url/purl-spec#854 proposes pkg:ansible/<namespace>.<name>@<version> with repository_url / vcs_url / download_url / packaging qualifiers. It's open, with one approval and one changes-requested, and there's active disagreement about the vcs_url comma syntax and whether packaging=rpm|deb should defer to the existing rpm/deb types.

How does syft prefer to handle an ecosystem whose purl type is proposed but unmerged? Options I can see: emit the proposed form, wait for the type to land, or something else you've done before. I'd rather match your existing practice than invent one.

2. Roles carry no integrity data, and I don't want that to read as "verified".

Collections and roles are not equivalent:

Collections Roles
Manifest MANIFEST.json meta/main.yml (no version)
Install provenance MANIFEST.json + <ns>.<name>-<version>.info meta/.galaxy_install_info — version + a locale-formatted date; absent for locally-authored roles
File checksums sha256 on every file none — no equivalent file exists

A role's entire recorded identity is a version string written by the installer into a dotfile, editable by anyone with write access and verifiable against nothing.

My concern is that emitting both as ordinary components lets a consumer read "no hashes recorded" as a syft limitation rather than as "no hashes exist anywhere for this component type". Does syft have an established way to express that distinction, or would this be new?

Some smaller parsing notes, in case they're useful for scoping:

  • Author-supplied manifest fields are unreliable — I found a real collection shipping the unedited Galaxy skeleton placeholder (https://www.github.com/my_org/my_collection) as its repository. Only namespace/name/version look trustworthy for identity.
  • Role versions are inconsistently prefixed (v0.3.2 alongside 3.5.0 in one tree).
  • install_date in .galaxy_install_info is locale-formatted, so it's best treated as opaque.
  • Content installed from a git source records no commit — only the galaxy.yml version — so those components can't be pinned to a source state.

I'm building a standalone tool for the Ansible-workflow side of this (lockfile and drift against requirements.yml), which syft wouldn't want to host. The cataloging half seems to belong here rather than in yet another tool nobody has installed, so I'm happy to do the work and contribute it upstream if you're open to the ecosystem.

Is this something you'd accept? And if so, do you have a preference on the purl question above before I start?