Japanese README is available at README.ja.md.
depaudit-license is a Go CLI that builds OSS license inventory and distribution notice outputs from either a repository scan or an existing SBOM.
When building applications that rely on OSS, teams need to organize dependency license information and present it appropriately.
SBOM is an effective mechanism, but in many cases it is not sufficient on its own as the final artifact presented to end users.
At the same time, publishing an application often requires preparing a license page (notice) that satisfies the obligations of each OSS license, and it is important to present that information in a form people can actually understand.
Existing tools can extract license information and generate SBOMs, but they do not consistently produce artifacts that are already formatted for distribution. In many cases, the final output still needs manual processing before it can be published.
There is also a process problem: even though the license page is important, it is easy for this work to be postponed until late in development, which increases the risk of omissions.
depaudit-license was built to address this by automating license compliance all the way through artifact generation.
It accepts repository scans and SBOMs as inputs, merges them into a normalized inventory, and generates a distributable license page (legal notice).
This makes it practical to incorporate license compliance into CI, reduce dependence on manual work, and handle it reliably and continuously over time.
It can:
- scan a repository directly
- import
CycloneDX JSONorSPDX JSON - merge multiple inputs into one inventory
- enrich package metadata from package ecosystems
- render report HTML, legal notice HTML, and JSON outputs
- optionally build vulnerability checklist outputs from the same normalized inventory
repository-scan=<path>cyclonedx-json=<path>spdx-json=<path>
You can specify -input multiple times to merge sources into one normalized inventory.
Repository scan currently recognizes these package ecosystems directly:
Node.js / npm / pnpm / Yarn.NET / NuGet
SBOM inputs can also carry packages that are normalized as:
generic
In practice this means:
- repository scan is designed around Node.js manifests and lockfiles (
package.json,pnpm-lock.yaml,yarn.lock) and .NET / NuGet manifests and metadata - NuGet enrichment can resolve embedded file-based licenses from either the local global-packages cache or the remote package archive when registration metadata alone is insufficient
- CycloneDX / SPDX inputs can bring in packages from other ecosystems, but metadata enrichment and ecosystem-specific behavior may be more limited when the package is only represented as generic SBOM data
- report and legal notice outputs work across the normalized inventory, while enrichment and vulnerability matching quality can vary by ecosystem and available identifiers
By default the CLI writes:
dist/depaudit-license.htmldist/depaudit-license.jsondist/depaudit-license-legal-notice.html
Optional vulnerability outputs:
-output-vuln-html-output-vuln-json
Download the release archive for your platform from GitHub Releases, then extract it to a local folder.
The release archive includes:
- the platform-specific binary
templates/for the default HTML/CSS assetsconfigs/for the default license catalog and locale bundle- a Syft-generated SPDX JSON SBOM for the packaged distribution
README.md,README.ja.md,LICENSE, andTHIRD-PARTY-NOTICES.md
Run the binary from the extracted folder.
Windows:
.\depaudit-license-windows-amd64.exeLinux:
./depaudit-license-linux-amd64macOS:
./depaudit-license-darwin-arm64Example: scan a local repository:
.\depaudit-license-windows-amd64.exe `
-input repository-scan=.\my-repository `
-output-html dist\report.html `
-output-json dist\report.json `
-output-legal-html dist\legal-notice.htmlExample: run from a CycloneDX SBOM:
.\depaudit-license-windows-amd64.exe `
-input cyclonedx-json=.\sbom\app.cyclonedx.json `
-output-html dist\cyclonedx-report.html `
-output-json dist\cyclonedx-report.json `
-output-legal-html dist\cyclonedx-legal-notice.htmlExample: run with vulnerability outputs:
.\depaudit-license-windows-amd64.exe `
-input repository-scan=.\my-repository `
-output-html dist\report.html `
-output-json dist\report.json `
-output-legal-html dist\legal-notice.html `
-output-vuln-html dist\vulnerability.html `
-output-vuln-json dist\vulnerability.json `
-vuln-mode fullExample: load runtime defaults from a config file and override only the repository path:
.\depaudit-license-windows-amd64.exe `
-config .\configs\depaudit-license.config.json `
-input repository-scan=.\my-repositoryLicense definitions and descriptions:
-license-catalogaccepts local file paths andhttps://URLs- later
-license-catalogvalues override earlier sources -localeselectsconfigs/license-texts.<locale>.json-license-text-bundleoverrides locale-based bundle resolution-license-override-fileloads a package-level override JSON for manually resolving licenses such asUnknown-exclude-policyloads versioned shallow/subgraph exclude policy JSON
The built-in catalog now also includes review-only definitions for common source-available and proprietary-adjacent licenses. When a package matches one of these definitions, it can resolve out of Unknown, but the matched license still carries requires_manual_review: true and should not be treated as pre-approved OSS without policy review.
Package-level license override:
{
"version": "v1alpha1",
"licenseOverrides": [
{
"id": "left-pad-1.3.0-mit",
"reason": "Upstream metadata is missing and the package LICENSE file was manually reviewed.",
"match": {
"ecosystems": ["node"],
"names": ["left-pad"],
"versions": ["1.3.0"],
"purls": ["pkg:npm/left-pad@1.3.0"]
},
"licenseKey": "MIT",
"mode": "ifMissing",
"evidence": {
"url": "https://github.com/example/left-pad/blob/v1.3.0/LICENSE",
"reviewedBy": "manual",
"reviewedAt": "2026-04-10",
"note": "LICENSE text matches MIT."
}
}
]
}.\depaudit-license-windows-amd64.exe `
-input repository-scan=.\my-repository `
-license-override-file .\configs\license-overrides.json `
-output-html dist\report.html `
-output-json dist\report.json `
-output-legal-html dist\legal-notice.htmlUse -license-catalog when a raw license string or URL should normalize to a catalog definition across matching packages. Use -license-override-file when only a selected package should be manually resolved. The default mode is ifMissing, which applies only when licenseKey is blank or the fallback (Unknown). Use mode: "force" to intentionally replace an existing non-fallback license.
Examples of built-in review-only keys include Microsoft-Software-License-Terms, BUSL-1.1, Elastic-2.0, SSPL-1.0, Commons-Clause, PolyForm-Noncommercial-1.0.0, FSL-1.1-MIT, Confluent-Community-License, Timescale-License, and CockroachDB-Community-License.
Presentation:
-template,-theme-css-legal-template,-legal-theme-css-vuln-template,-vuln-theme-css-config/--configloads a versioned runtime config JSON for CLI defaults
Runtime config:
-config <path>,--config <path>, or--config=<path>loads runtime defaults from JSON- precedence is
CLI > env > runtime config > built-in default - local paths inside the runtime config are resolved relative to the config file itself
inputsandlicenseCatalogsare list settings, so any CLI-inputor-license-catalogreplaces the runtime-config list instead of appending to it- runtime config schema and sample are available at:
When package-local embedded license text is discovered, the CLI copies that raw text next to the legal notice output under license-texts/... and links it from the legal notice HTML / JSON via copiedFilePath.
Report / legal notice custom templates can use these helpers:
slugecosystemLabeldependencyTypeLabelprettyJSON
slug, ecosystemLabel, and dependencyTypeLabel are presentation helpers for report / legal notice templates.
prettyJSON is a debug/convenience helper for custom templates. It renders structured values as indented JSON text so template authors can inspect nested data or expose raw view data in a <pre> block. Because the report and legal notice renderers use html/template, the output is HTML-escaped unless the template explicitly wraps it in a safe HTML construct such as <pre>.
Remote catalog behavior:
-remote-catalog-mode fail-fast-remote-catalog-mode stale-fallback-remote-catalog-cache-dir <path>
External metadata / vulnerability API behavior:
-http-cache-mode off|use|refresh|cache-only-http-cache-dir <path>-http-cache-ttl 24h-max-package-artifact-bytes 268435456-max-package-metadata-bytes 1048576-max-embedded-license-bytes 4194304-max-package-archive-entries 10000-npm-registry-base-url <url>-nuget-registration-base-url <url>-osv-base-url <url>-github-advisory-base-url <url>-github-advisory-token <token>-nvd-base-url <url>-nvd-api-key <key>
For secret-like settings, the effective precedence is:
- CLI flag
- environment variable
- runtime config
- built-in default
-http-cache-* applies to package metadata enrichment and vulnerability APIs. Remote license catalog URLs continue to use -remote-catalog-mode / -remote-catalog-cache-dir so stale-fallback behavior remains catalog-specific. Cached HTTP responses are also bounded by the same request-specific metadata and package-content size limits before they are buffered or written to disk.
Artifact-backed license resolution also enforces explicit safety limits for package artifacts, package metadata files, embedded license files, and package archive entry counts. The same limits apply to local package-manager artifacts and remote package-content fallback. When one of these limits is exceeded, the run fails with an error instead of falling back to review-only output.
The external metadata and vulnerability endpoints actually used during the run are recorded in report JSON and vulnerability JSON as provenance.externalSources. Remote license catalog URLs continue to appear in provenance.catalogSources.
Package-level provenance can also record provenance.artifactResolution. Local package-manager artifacts such as node_modules or NuGet global-packages are preferred and can be recorded even when enrichment does not need to overwrite any package fields. The remote enrichment phase skips packages that already carry local package-manager artifact evidence so redundant external lookups are avoided. When no local package-manager artifact is available and the resolver has to rely on a remote source, the package is marked with reviewRequired: true, a warning is emitted to stderr, and report JSON includes a remote_resolution_fallback_used diagnostic so the result can be reviewed separately from local-artifact-backed evidence.
Recommended patterns:
- use
-http-cache-mode use -http-cache-ttl 24hfor normal CI or local runs - use
-http-cache-mode cache-only -http-cache-ttl 0when repeatedly adjusting output presentation and you want to avoid new external requests - use
-http-cache-mode refreshwhen you need to repopulate cache from upstream APIs - use
-http-cache-mode offwhen cache must be bypassed completely
This CLI can access external services when metadata enrichment, remote catalogs, or vulnerability reporting are enabled.
- npm metadata enrichment:
default
https://registry.npmjs.orgoverride-npm-registry-base-url - NuGet metadata enrichment:
default
https://api.nuget.org/v3/registration5-gz-semver2package archive fallback uses thepackageContentURL returned by the selected registration service override-nuget-registration-base-url - Remote license catalogs:
any
http://orhttps://URL passed to-license-catalogcache controls:-remote-catalog-mode,-remote-catalog-cache-dir - OSV vulnerability queries:
default
https://api.osv.devoverride-osv-base-url - GitHub Advisory queries:
default
https://api.github.comoverride-github-advisory-base-urlauth:-github-advisory-tokenorDEPAUDIT_LICENSE_GITHUB_ADVISORY_TOKEN,GITHUB_TOKEN,GH_TOKEN - NVD vulnerability enrichment:
default
https://services.nvd.nist.govoverride-nvd-base-urlauth:-nvd-api-keyorDEPAUDIT_LICENSE_NVD_API_KEY,NVD_API_KEY
Rate-limit notes:
- GitHub raises REST API limits when authenticated
- NVD raises API limits when an API key is provided
- OSV does not currently require authentication
- npm registry and NuGet public-read metadata requests are better handled through cache or an internal mirror/proxy than through per-request credentials
When endpoint overrides are used, the selected mirror or proxy becomes part of the tool's evidence path and should be managed as an operational dependency.
depaudit-license supports two different exclusion layers.
shallow exclude: post-merge output filtering. This applies to the final normalized inventory regardless of whether packages came fromrepository-scan, CycloneDX, or SPDX input.subgraph exclude: source-local dependency graph filtering. This currently applies only to.NET / NuGetpackages collected fromrepository-scanwhen a package graph is available fromobj/project.assets.json.
Use shallow exclude when you want to hide packages from the rendered report / legal notice output but still keep an audit trail in JSON output. Excluded packages are removed from visible package lists, license groups, production inventory, and legal notice evidence, but remain visible in excludedPackages with rule metadata.
Use subgraph exclude when you want to remove a matched root package and dependencies that are reachable only from that root before merge. Shared dependencies are preserved if another non-excluded root still reaches them. If graph support is unavailable, onUnsupported controls whether the policy should warn, error, or ignore.
Minimal example:
{
"version": "v1alpha1",
"shallowExcludes": [
{
"id": "omit-test-tooling",
"reason": "hide development-only tooling from rendered outputs",
"match": {
"ecosystems": ["npm", "nuget"],
"dependencyTypes": ["devDependency", "devTransitiveDependency"],
"nameGlobs": ["eslint*", "xunit*"]
}
}
],
"subgraphExcludes": [
{
"id": "omit-analyzer-subgraph",
"reason": "drop analyzer-only dependency branches from repository scan",
"onUnsupported": "warn",
"match": {
"ecosystems": ["nuget"],
"projects": ["src/server/App.csproj"],
"hasRuntimeAssets": false
}
}
]
}Example invocation:
.\depaudit-license-windows-amd64.exe `
-input repository-scan=.\my-repository `
-exclude-policy .\configs\exclude-policy.json `
-output-html dist\report.html `
-output-json dist\report.json `
-output-legal-html dist\legal-notice.htmlSee also:
- configs/exclude-policy.sample.json
- configs/exclude-policy.schema.json
- configs/license-overrides.sample.json
- configs/license-overrides.schema.json
Public OSS releases start at 1.0.0.
1.xreleases should preserve documented CLI and output contracts unless a change is intentionally released as breaking- breaking changes should be called out explicitly in release notes and repository documentation
- experimental or provisional behavior should be labeled as such in the relevant document before release
- README.ja.md
- docs/ARCHITECTURE.md
- CHANGELOG.md
- RELEASE.md
- configs/README.md
- LICENSE
- THIRD-PARTY-NOTICES.md
- CONTRIBUTING.md
- SECURITY.md
- SECURITY.ja.md
- .github/SUPPORT.md
- .github/SUPPORT.ja.md
- CODE_OF_CONDUCT.md
- This is an independent OSS tool for license inventory, notice generation, and supplemental vulnerability reporting.
- It is not affiliated with OSV, GitHub Advisory Database, NVD, SPDX, or the CycloneDX project.
- It can access external package metadata, license catalog, and vulnerability APIs depending on the selected inputs and flags.
- It is intended to assist and streamline license inventory, notice generation, and review workflows, not to conclusively resolve licensing issues.
- It does not provide legal advice, legal opinions, or a guarantee of license compliance.
- License classification, metadata enrichment, and generated notice outputs can be incomplete, outdated, or incorrect depending on upstream package metadata and available evidence.
- Final interpretation of license obligations, policy decisions, and release approval remains the responsibility of the user and, where appropriate, legal counsel or internal compliance review.