# Audit Open Source Licenses in a Go Project

Yes. An agent resolves your Go module graph in a sandbox and writes licenses.csv plus licenses.md flagging GPL, AGPL, LGPL, SSPL or unknown licenses.

[Run this on Rush](https://cloud.getrush.ai/run/license-audit/go/).

## What the agent does

The agent clones the module into its sandbox. On a repository like pocketbase/pocketbase it finds `go.mod` declaring `module github.com/pocketbase/pocketbase` with `go 1.27`, a `go.sum` of about 150 lines, and direct requirements such as `modernc.org/sqlite v1.60.1`, `github.com/dop251/goja`, `github.com/golang-jwt/jwt/v5 v5.3.1`, `github.com/spf13/cobra v1.10.2`, `github.com/ganigeorgiev/fexpr v0.6.0`, and `golang.org/x/crypto`. The tree also lists indirects (`github.com/google/uuid`, `modernc.org` helpers, and others). The project itself is MIT (`LICENSE.md`).

In the sandbox it runs `go mod download` (and a license inventory tool such as `go-licenses` or an equivalent that reads module zip LICENSE files) so every module in the graph is present. For each module it records path, version, license SPDX or LICENSE file text classification, whether it appears in the top-level `require` block without `// indirect` (direct) or only as transitive, and a path from a direct require to that module using `go mod graph`.

PocketBase's SQLite stack via `modernc.org/sqlite` brings a cluster of `modernc.org/*` modules; the agent expands that subgraph so a license on a transitive modernc package is not hidden under the direct sqlite require. Similarly, `goja` and `goja_nodejs` are listed with their own license rows because the JS hooks runtime is a distinct dependency from the HTTP API surface in `apis/` and `core/`.

It writes `licenses.csv` with those columns and `licenses.md` calling out GPL, AGPL, LGPL, SSPL and unknown licenses. For each flagged module the Markdown names the direct import that pulls it in (for example a `modernc.org/sqlite` transitive or a `cobra` dependency) so replacing or isolating that direct require is actionable. Modules whose LICENSE is only a notice file without a clear SPDX id are listed as unknown rather than guessed.

No Go source is edited, no `replace` directives are added, and nothing is pushed. The CSV and Markdown are the only deliverables.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Clone https://github.com/pocketbase/pocketbase, resolve its full dependency tree from the lockfile, and write licenses.csv (package, version, license, direct or transitive, path from the root) plus licenses.md summarizing any GPL, AGPL, LGPL, SSPL or unknown license and which top-level dependency brings it in."
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is `licenses.csv` and `licenses.md` as artifacts on the session. The CSV covers the module graph from `go.mod` / `go.sum`; the Markdown lists flagged licenses with the direct require that introduces each one.

Before a release, a reviewer sorts the CSV by license, checks each flagged path with `go mod why`, and decides whether a replace or a different library is needed. The transcript retains the download and license-scan commands.

## Run it on every go.mod or go.sum change on main

A GitHub `push` webhook on those files starts this request against the new commit. Each run rebuilds the inventory from the updated graph so a transitive copyleft dependency cannot land unnoticed.

On `run.completed`, post the `licenses.md` summary to the PR or a compliance channel when the flagged section is non-empty.

## Why run it on Rush?

A Go license pass on a laptop means installing module sources into the local cache and running a scanner that shares that cache with other work. Rush runs the same graph resolve in a disposable sandbox and returns files you can archive with the release.

Several modules can be audited in parallel without cross-contaminating `GOPATH` or the module cache on your machine. Proof is the transcript plus the CSV, not a screenshot of a terminal.

Binary-distribution products like PocketBase need a clear answer about every module linked into the release artifact. The CSV is that answer for one commit of `go.mod` / `go.sum`, reproducible from the session transcript.

## Frequently asked questions

### Does it follow replace and exclude directives?

Yes. It uses the same `go.mod` the build uses, so `replace` and `exclude` lines shape the graph it inventories. The CSV versions match what `go list -m all` would show for that module.

### Are test-only dependencies included?

Modules that appear only in tests still show up in the module graph when they are required. If you want main-package dependencies only, say so in the prompt and the agent filters with `go list` build constraints.

### Will it modify go.mod?

No. It downloads modules and writes report files. `go.mod` and `go.sum` in your repository are not changed.

### What about cgo or system libraries?

Only Go modules in the graph are listed. System libraries linked through cgo are out of scope unless you extend the prompt; the report says so when it detects cgo files.

### Does it scan the JavaScript UI assets in the repo?

No. This job covers the Go module graph. Frontend package licenses would be a separate prompt against any npm lockfile the repository carries.
