Add catalogers for Ansible collections and roles
- Dominant language
- Go
- Stars
- 9.6k
- Forks
- 954
- Avg merge
- 23h 27m
- Merged PRs (30d)
- 48
Description
**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///` |
| `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](https://github.com/package-url/purl-spec/pull/854) proposes `pkg:ansible/.@` 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` + `.-.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?
Contributor guide
Research direction
Start by reading the existing terraform-lock-cataloger and github-actions-usage-cataloger implementations, then review the proposed Ansible purl discussion. Ask maintainers to settle component identity and how to distinguish roles without integrity data before implementing catalogers for installed collections, roles, and requirements.yml. Done means the accepted catalogers produce the agreed SBOM components and coverage is tested.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ansible, go
- Domain
- devops, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100