Quick start
Install licence_audit, inspect your locked dependencies, create a policy, and enforce the policy.
licence_audit is a small CLI that audits the licences used by your Gleam
project’s locked dependencies. It reads manifest.toml and gets licence
metadata from Hex. It reports the resolved dependency tree, creates a
CycloneDX SBOM, and checks for known vulnerabilities.
Install
Download the self-contained archive for your platform from the
releases page. Extract the archive and put licence_audit on your
PATH. These Queso-built executables include the Erlang runtime. You do not
have to install Erlang/OTP on the target machine. Use these native binaries
for CI to avoid a separate OTP requirement.
The release also provides an escript for compatibility. The escript needs
Erlang/OTP 28 or later for all commands. On OTP 27, the VM can fail to load
it with corrupt atom table and exit 127, before any command runs. This
unsupported-runtime failure is outside the
CLI exit-code contract.
With mise, install directly from the github: provider:
mise use -g github:tylerbutler/licence_audit@latestTo pin a version, replace latest with an exact release tag (vX.Y.Z).
Choose a tag from the latest published release. mise selects
the self-contained archive for your operating system and architecture.
You do not need Erlang/OTP. For source build instructions, refer to DEV.md.
Standard workflow
Inspect the dependencies, create a policy, and enforce the policy.
# 1. Create manifest.toml and report the dependency treegleam deps downloadlicence_audit
# 2. Select the licences to allow or denylicence_audit update
# 3. Return a failure if the policy has a violationlicence_audit checkThe licence_audit command reports policy findings without enforcing them and
returns exit code 0 when the scan completes. An incomplete licence report
caused by unavailable or invalid package metadata returns 2. The check
command also returns 1 when it finds a policy violation.
See configuration discovery for how the manifest selects the project and policy file.
Optional GitHub Actions usage
Use mise in GitHub Actions to install the same native binary as a local
install. We recommend native binaries for CI because they include the Erlang
runtime. For a Gleam project, set up Gleam first so manifest.toml exists.
The example selects OTP 28 for the job instead of relying on the project’s
OTP version.
Replace vX.Y.Z below with the tag from the
latest published release.
Keep an exact tag in CI and update it after testing a newer release. mise’s
GitHub backend
checks release digests or published checksums and verifies available GitHub
artifact attestations. It does not require a release to have attestations.
name: licence audit
on: pull_request: push: branches: [main]
jobs: licence-audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: tylerbutler/actions/setup-gleam@v1 - uses: erlef/setup-beam@v1 with: otp-version: "28" - uses: jdx/mise-action@v3 with: install: false - run: mise exec github:tylerbutler/licence_audit@vX.Y.Z -- licence_audit check env: MISE_GITHUB_TOKEN: ${{ github.token }}Commands
| Command | What it does |
|---|---|
check |
Report metadata and enforce the licence policy. Returns a nonzero exit code for violations. |
notices |
Create a third-party licence notices file for a release. Does not evaluate policy. |
sbom |
Create a CycloneDX 1.6 JSON SBOM. Does not evaluate policy. |
update |
Select licences and write a policy to gleam.toml. |
vulns |
Report known vulnerabilities from OSV.dev. Does not evaluate policy. |
Output, colours, and exit codes
Reports and gate verdicts go to stdout. Progress, warnings, and operational
errors go to stderr. --quiet hides INFO and WARN messages, but never errors.
Rows use indentation to show the dependency tree. Each row starts with a
status symbol:
| Glyph | Meaning |
|---|---|
✓ |
Policy permits the licence (check only) |
✗ |
Policy denies the licence (check only) |
? |
No policy evaluated, or status unknown |
~ |
Finding accepted by a scoped policy exception |
· |
Command skips the package (non-Hex source) |
Use --color or --colour to control colour. The permitted values are auto,
always, and never. The auto value uses NO_COLOR, FORCE_COLOR, TERM,
CI, and COLORTERM, and detects terminal support separately for stdout and
stderr. Explicit always and never values override environment settings for
report colours and stderr progress messages, including warnings and deferred
errors, on every command.
SBOM JSON and notice payloads stay plain in every color mode, including
always. Use --help or -h with any command. --version is available only
at the root.
The command uses these exit codes:
| Code | Meaning |
|---|---|
0 |
Successful completion. Report-only policy violations and vulnerabilities do not fail the command. |
1 |
Enforced check failure, invalid usage, or non-interactive use of update. |
2 |
Input, config, manifest, network, decode, or artifact-generation error that prevents completion, including incomplete licence metadata and update edit/write failures. |
130 |
update cancelled by the user. |
Individual advisory details and default SBOM dependency enrichment are optional:
their failures warn but can still exit 0. Required metadata and OSV batch
failures exit 2. See the partial-result rules
for the command-specific exceptions and release impact.
Compatibility
From version 1.0.0, the CLI and configuration follow the compatibility policy. Read it for versioning rules, stable interfaces, output guarantees, and exceptions for correctness fixes. Gleam modules and human-readable report formatting are not supported integration interfaces.
Caching
licence_audit caches Hex licence metadata on disk between runs in the
${XDG_CACHE_HOME:-$HOME/.cache}/licence_audit/hex-v2/ directory. Override it
with --cache-path=DIR, or bypass the caches with --no-cache.
When neither XDG_CACHE_HOME nor HOME has a nonempty value on Windows,
the default is %LOCALAPPDATA%\licence_audit\Cache\hex-v2\, as resolved
by Erlang/OTP’s user cache directory. A nonempty XDG_CACHE_HOME takes
precedence over HOME on all platforms.
licence_audit reuses Hex API entries for 7 days, so metadata changes on Hex
can take up to 7 days to appear. Use --no-cache when you need fresh data.
The cache is shared across projects and commands for each package name and
version. Concurrent commands can share the cache. In CI, restore and save the
cache directory between jobs, for example with actions/cache,
--cache-path=.hex-cache/hex-v2, and .hex-cache/ as the path to save. Use
--verbose to see cache hits and misses.
The cache directory contains one JSON file for each entry. A command writes each entry to a temporary file and then renames it, so other commands never read a partial entry. You can copy the cache directory at any time. To clear the cache, delete the directory.
The cache fills on first use. licence_audit does not read or change old
.dets or .sqlite3 cache files. You can delete them. If --cache-path
points to a file, the command warns and continues without caching.
licence_audit caches each successful lookup when it completes. A later
lookup failure keeps earlier entries, and the audit continues with the
remaining packages. The cache excludes failed lookups. If a refresh fails
and an older entry exists, the audit uses that entry and warns.
If a cache operation fails, licence_audit continues the audit and writes a
warning to stderr. It does not cache OSV advisories.
Hex network errors include the request URL and available DNS, connection, or TLS details for IPv4 and IPv6. Request timeout errors include the 5000 ms limit. When the HTTP client does not identify the failed stage, the message says so.
Set up with an AI agent
Install the setup skill with APM:
apm install tylerbutler/licence_audit/.apm/skills/setup-licence-auditThis installs the setup skill, not the executable or repository development skills. Ask your agent:
Set up licence_audit for local licence and vulnerability checks in this project. Preserve the existing policy and tool versions. Do not change CI.
To include CI, add:
Also enforce the same licence policy and vulnerability threshold in CI.
The skill adds CI only when requested. You make the licence approval decisions.
For manual CI setup, install a fixed release and run licence_audit check
against a policy committed to version control.
Troubleshooting
- Manifest not found: run
gleam deps downloadto createmanifest.toml. - Hex request fails: retry or reuse cached entries without
--no-cache. Required metadata failures still make a licence report incomplete. - Unsupported SBOM source:
sbomrequires a valid purl for every dependency;--offlinedoes not bypass source validation. - OSV.dev unavailable: vulnerability commands need access to
api.osv.dev. Advisory responses are not cached. - No colours in automated output: use
--color=alwaysto force ANSI codes or--color=neverfor plain text.--colouris an alias.
Licence audits cover locked Hex packages. Non-Hex sources remain in the tree and are identified as skipped. Hex licence metadata is package-level data, not a source inspection or a per-release licence conclusion.
Root usage and flags
This section is generated from the CLI. Use licence_audit --help for the
options available in your installed version.
--help and -h show help for the root command or a subcommand, for example
licence_audit sbom -h. --version belongs to the root command:
use licence_audit --version, not licence_audit sbom --version.
Reports Hex package licence metadata. It displays a summary of the licences for the project’s dependencies. Use the check subcommand to enforce a licence policy, and the update subcommand to create a policy.
Usage:
licence_audit (check | notices | sbom | update | vulns) [--flags]Flags:
| Name | Type | Default | Description |
|---|---|---|---|
--allow |
STRING_LIST |
`` | Allow licences, comma-separated |
--cache-path |
STRING |
Override the licence metadata cache directory | |
--color |
STRING |
auto |
Colorize output: auto|always|never (default auto; alias: –colour) |
--config |
STRING |
Read configuration from PATH | |
--deny |
STRING_LIST |
`` | Deny licences, comma-separated |
--ignore-config |
BOOL |
false |
Ignore configuration files |
--manifest |
STRING |
Read manifest from PATH | |
--no-cache |
BOOL |
false |
Bypass the on-disk caches |
--prod-only |
BOOL |
false |
Only scan production dependencies; exclude dev dependencies |
--quiet |
BOOL |
false |
Suppress progress output (alias: -q) |
--verbose |
BOOL |
false |
Show detailed progress output (alias: -v) |
--version |
BOOL |
false |
Print the installed version |