Open-Source Wikis

/

Grype

/

Systems

/

Presenters

anchore/grype

Presenters

Active contributors: Alex Goodman, Will Murphy, Keith Zantow

Purpose

Presenters render the result of a Grype scan in one of several formats. They are the boundary between the matcher pipeline (which produces typed Go values) and the bytes the user actually sees.

Directory layout

grype/presenter/
├── presenter.go         # GetPresenter shim (deprecated)
├── models/              # JSON model — the shared serialization types
├── table/               # default human-readable table output
├── json/                # JSON output (the schema source of truth)
├── cyclonedx/           # CycloneDX (JSON + XML, plus embedded-VEX variants)
├── sarif/               # SARIF for code-scanning integrations
├── template/            # arbitrary user-supplied Go template
├── explain/             # explain subcommand renderer (post-scan)
└── internal/            # shared rendering helpers

internal/format/
└── format.go            # format name → presenter mapping (the modern entry point)

How presenters are selected

internal/format is the modern entry point. cmd/grype/cli/commands/root.go::runGrype builds a format.MakeScanResultWriter that fans output to one or more Outputs:

writer, err := format.MakeScanResultWriter(opts.Outputs, opts.File, format.PresentationConfig{
    TemplateFilePath: opts.OutputTemplateFile,
    ShowSuppressed:   opts.ShowSuppressed,
    Pretty:           opts.Pretty,
})

opts.Outputs is a slice of <format>=<destination> strings (json=report.json, table, sarif=findings.sarif, etc.). format.GetPresenter picks the right presenter.Presenter per format. The legacy grype/presenter/presenter.go::GetPresenter is a thin shim and is annotated // Deprecated: this will be removed in v1.0.

Available formats

Format name Path Notes
table (default) grype/presenter/table/ Human-readable table with optional color.
json grype/presenter/json/ The canonical machine-readable format; schema is generated.
cyclonedx-json, cyclonedx-xml grype/presenter/cyclonedx/ CycloneDX 1.5+.
embedded-cyclonedx-vex-json, embedded-cyclonedx-vex-xml grype/presenter/cyclonedx/ CycloneDX with vulnerabilities embedded as VEX statements.
sarif grype/presenter/sarif/ For GitHub code scanning, etc.
template grype/presenter/template/ User-supplied Go text/template.

The shared model

grype/presenter/models/ defines the JSON-shaped types every presenter starts from:

  • Document — top-level wrapper.
  • Match — a flattened, presentation-friendly version of match.Match.
  • Source — the scan target description.
  • Distro — distro fields.
  • Configuration, DBStatus, Provenance — context fields.

PresenterConfig carries everything a presenter needs:

  • The matched match.Matches, []match.IgnoredMatch, and []pkg.Package.
  • The original *sbom.SBOM (for CycloneDX presenters that want to emit a complete BOM).
  • pkg.Context, DB status, applied VEX rules.

Most presenters operate on the models.Document after a one-time conversion via models.NewDocument.

CycloneDX peculiarities

CycloneDX has two modes:

  • Plain CycloneDX — emit a SBOM plus a vulnerabilities array.
  • Embedded VEX — emit each vulnerability as a CycloneDX VEX statement so that the resulting BOM can be both consumed as a SBOM and as a VEX document.

Both share machinery in grype/presenter/cyclonedx/. The embedded-VEX variants are why Grype keeps the original SBOM around end-to-end — the presenter needs the unmodified BOM contents to stitch in vulnerability findings.

SARIF

SARIF output (for GitHub code scanning) is generated via owenrumney/go-sarif. Each match becomes a SARIF result; severities map to SARIF levels. The presenter emits a single SARIF run per scan.

Template presenter

grype/presenter/template/ exposes the canonical model to a user-supplied text/template. Helper functions come from Masterminds/sprig. Example templates can be found in templates/.

The template presenter is the escape hatch for one-off output formats; users who need stable, structured output should prefer json.

Explain (post-scan)

grype/presenter/explain/ is different from the other presenters: it does not run as part of grype <target>. Instead, it powers the grype explain subcommand, which reads a JSON document on stdin and produces a per-match natural-language rationale.

This split keeps the explain logic away from the hot scan path and lets users re-explain old reports without re-scanning.

JSON schema

The JSON presenter's shape is the public API of Grype's machine-readable output. A separate generator under cmd/grype/cli/commands/internal/jsonschema/ produces a JSON Schema from the model types; task check-json-schema-drift fails the build if the committed schema and the regenerated one disagree.

Key abstractions

Symbol Where Description
format.PresentationConfig internal/format/ Per-output format configuration.
format.MakeScanResultWriter internal/format/ Creates a multi-format io.Writer.
format.GetPresenter(format, cfg, pcfg) internal/format/ Resolves a format name to a presenter.
models.PresenterConfig grype/presenter/models/ Bundle of inputs every presenter needs.
models.Document grype/presenter/models/ The canonical JSON-shaped document.

Key source files

File Purpose
internal/format/format.go Format-name → presenter dispatch (modern entry).
grype/presenter/models/ Shared serialization types.
grype/presenter/json/presenter.go JSON output (source of the public schema).
grype/presenter/cyclonedx/presenter.go CycloneDX + embedded-VEX.
grype/presenter/sarif/presenter.go SARIF.
grype/presenter/template/presenter.go Go-template-based output.
grype/presenter/table/presenter.go Default table renderer.

Entry points for modification

  • Add a new format — create a sibling directory under grype/presenter/, implement presenter.Presenter, register the format in internal/format/format.go.
  • Change JSON shape — modify grype/presenter/models/, regenerate the schema with task generate-json-schema, and bump the schema version. The drift checker will fail the build until both are consistent.
  • Add a new column to the table presenter — modify grype/presenter/table/. Snapshot tests (under __snapshots__/) need updating with task unit -update-snaps.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Presenters – Grype wiki | Factory