# Share a Grype Report — Container CVEs Somewhere People Read Them

Canonical: https://commareports.com/share-grype-report
Published: 2026-09-08

> grype prints a table and writes JSON, neither of which survives a Slack paste. Render it to HTML and publish to Comma for a URL with a comment thread per CVE.

# Share a Grype report

Grype is fast and it is thorough, and those two facts combine into a delivery
problem: a scan of a normal application image produces hundreds of rows.

```
NAME             INSTALLED    FIXED-IN   TYPE  VULNERABILITY   SEVERITY
libcrypto3       3.1.4-r5     3.1.4-r6   apk   CVE-2024-2511   Medium
libssl3          3.1.4-r5     3.1.4-r6   apk   CVE-2024-2511   Medium
…
```

That table is fine in a terminal you can widen and unusable everywhere else.
Pasted into Slack it wraps, and once it wraps the CVE column and the severity
column no longer belong to the same row. So the scan gets summarized as "about
200 findings, mostly medium", which is not something anyone can act on.

## Get HTML out of Grype

Grype has no HTML writer, but it has a template writer, which is enough:

```bash
grype myapp:1.4.2 -o template -t html.tmpl > report.html
```

A minimal `html.tmpl` — the point is a real table with sortable severity, not
elaborate styling:

```gotemplate
<h1>{{.Source.Target.UserInput}}</h1>
<table>
<tr><th>Severity</th><th>CVE</th><th>Package</th><th>Installed</th><th>Fixed in</th></tr>
{{- range .Matches}}
<tr><td>{{.Vulnerability.Severity}}</td>
    <td><a href="{{.Vulnerability.DataSource}}">{{.Vulnerability.ID}}</a></td>
    <td>{{.Artifact.Name}}</td>
    <td>{{.Artifact.Version}}</td>
    <td>{{if .Vulnerability.Fix.Versions}}{{index .Vulnerability.Fix.Versions 0}}{{else}}—{{end}}</td></tr>
{{- end}}
</table>
```

The other route, if you already render SARIF for other scanners, is
`grype myapp:1.4.2 -o sarif > grype.sarif` and then
[sarif-tools](/share-sarif-report) — which has the advantage of putting Grype's
findings in the same report as everything else.

## Publish only what can be fixed

```bash
grype myapp:1.4.2 --only-fixed -o template -t html.tmpl > report.html
```

`--only-fixed` is the single most useful flag for a report meant to be read. A
list where every row has an available upgrade is a work queue. A list where 85%
of rows say "no fix" is a document people learn to skip.

## Publish it

Drag `report.html` into [the app](https://commareports.com/), or POST it:

```bash
curl -fsS -X POST "https://commareports.com/api/v1/reports" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html report.html \
        --arg t "Grype — myapp:1.4.2" '{title: $t, html: $html}')"
```

## Set the access first

A Grype report is a precise inventory of the unpatched vulnerabilities in an
image you are running, complete with versions. Reports are private by default;
keep this one on **team**, **domain-gated** or **named-reviewer** access. See
the [sharing model](/docs/sharing).

## From CI

```bash
grype "$IMAGE" --only-fixed --fail-on high -o template -t html.tmpl > report.html || SCAN_FAILED=1

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html report.html \
        --arg t "Grype — $IMAGE" '{title: $t, html: $html}')"

exit "${SCAN_FAILED:-0}"
```

Publish before you fail the build — a gate that fails without leaving the report
behind is a gate people work around. PATCHing one report id per image gives a
stable URL and a revision per scan, which is the remediation trend an auditor
will ask you for.

## What review adds

- **Anchored threads** per CVE, so "not exploitable, we do not call that code
  path" is recorded against the finding. See
  [commenting on HTML](/comment-on-html).
- **Revisions**, so the count going down is evidence.
- **Named reviewers** when security has to sign off before a release.

## Limits

- **Entry HTML: 5 MB.** A large base image with `--only-fixed` off can exceed
  it; scan with `--only-fixed`, or filter by severity in the template.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision
history.

**[Publish a scan →](https://commareports.com/)**

### Related

- [Share a Trivy report](/share-trivy-report) · [Share an SBOM](/share-sbom-report)
- [Share a SARIF report](/share-sarif-report) · [Share a security scan report](/share-security-scan-report)
- [Share a Snyk report](/share-snyk-report) · [Share an OSV-Scanner report](/share-osv-scanner-report)
