# Share a License Report — The Answer Legal Keeps Asking For

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

> license-checker, pip-licenses and cargo-about all dump a list nobody outside engineering can read. Render it and publish to Comma so legal gets a URL that stays current.

# Share a license report

The request comes from legal or from a customer's procurement questionnaire and
it is deceptively simple: *"What open-source licenses are in the product?"*

Every ecosystem has an answer:

```bash
# Node
npx license-checker --production --out licenses.html

# Python
pip-licenses --format=html --with-license-file --with-urls > licenses.html

# Rust
cargo about generate about.hbs > licenses.html

# Ruby / Java / multi-language
license_finder report --format html > licenses.html

# Go
go-licenses report ./... --template licenses.tpl > licenses.html
```

And then the answer gets pasted into a spreadsheet, emailed, and is wrong within
a sprint. Which is why the request comes back every quarter.

## Flag, don't just list

A report that lists 1,400 dependencies alphabetically technically answers the
question and practically answers nothing. The reader is looking for four things:

- **Copyleft** — GPL, AGPL, LGPL, SSPL. These are the ones with obligations that
  can reach your own source.
- **Unknown / no license detected**. Usually a packaging bug, occasionally a
  genuine problem, always worth resolving before shipping.
- **Non-standard or custom licenses**, which need a human to read them.
- **Changes since last time**, which is the only part that needs attention on a
  recurring basis.

`license-checker` supports this directly:

```bash
npx license-checker --production \
  --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause;CC0-1.0;Unlicense' \
  --out licenses.html
```

which exits non-zero on anything outside the allowlist — so the report has a
gate behind it rather than being a document that is generated and never read.

## Publish it

Drag `licenses.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 licenses.html \
        --arg t "Licenses — myapp 1.4.2" '{title: $t, html: $html}')"
```

## The part that saves the recurring request

Generate it in the release pipeline and PATCH the same report id:

```bash
npx license-checker --production --out licenses.html

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 licenses.html \
        --arg t "Licenses — myapp $VERSION" '{title: $t, html: $html}')"
```

The URL you gave legal in Q1 still resolves to the current dependency tree in
Q4. The revision list answers "what were we shipping when we signed that
contract?", which is the question that actually matters in a dispute and which
a spreadsheet cannot answer at all.

## Attribution pages are the same artifact

Most permissive licenses require the license text and copyright notice to travel
with your distribution. That obligation and this report are the same document —
generate it with the full text included:

```bash
pip-licenses --format=html --with-license-file --with-notice-file > licenses.html
```

and the published URL can be the attribution page you link from your app's
about screen. Public access is appropriate here; it is the case where the
report is *meant* to be world-readable.

For an internal audit that names unreleased components, use team or
domain-gated access instead. See the [sharing model](/docs/sharing).

## What review adds

- **Anchored threads** on a specific dependency — "AGPL, but we only use it as
  a separate process over HTTP; legal signed off, see CONTRACT-118".
- **Revisions**, which are the dependency-tree history.
- **Domain-gated access**, so a customer's counsel can read it without an
  account.

See [commenting on HTML](/comment-on-html).

## Limits

- **Entry HTML: 5 MB.** Including full license text for a large tree is what
  pushes past it — publish the summary as the report body and attach the
  full-text bundle as an asset.
- **60 requests/minute per token.**

## Try it

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

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

### Related

- [Share an SBOM](/share-sbom-report) · [Share a dependency-check report](/share-dependency-check-report)
- [Share an npm audit report](/share-npm-audit-report) · [Share a security scan report](/share-security-scan-report)
- [Share a report with a client](/share-html-file-with-client) · [Monthly compliance digest](/features/routines/monthly-compliance-digest)
