APACHE 2.0 open-source license & SBOM scanner

License compliance,
in your shell.

A standalone CLI that scans Go, Node, PHP, Python, Ruby, Rust and Java projects for license risk, generates CycloneDX and SPDX SBOMs, and ships an EU CRA-compliant PDF report in one command. licscan scan . — that's it.

$brew install codelake-dev/tap/licscan
No account, no telemetry · Runs 100% locally · Deterministic, $0 / scan
Package managers
7
go · node · php · py · ruby · rust · java
Output formats
9
table · json · html · md · cdx · spdx · CRA · sarif · junit
SPDX families
20+
MIT · Apache · BSD · GPL · MPL · LGPL …
Risk levels
5
permissive → viral · all configurable
Runtime cost
$0
no LLM · no network · deterministic
Why licscan

Built like a Unix tool. Free like one, too.

Most license scanners are SaaS dashboards that need a login, hit network APIs and cost per scan. licscan ships as a single binary, reads your local package caches and produces output you can pipe straight into your CI.

Local-only

No backend connection, no telemetry, no phone-home. Reads from go.mod, node_modules, vendor/ and friends — exactly what's on your disk.

Deterministic

Same inputs, same outputs, every time. No LLM, no flakiness, no surprise CVE feed. Reproducible from a CI cache.

Apache 2.0

Open source. Fork it, ship it inside your product, run it offline behind your firewall. No vendor lock-in, no contract.

CRA-ready

The only OSS scanner that emits an EU Cyber Resilience Act-compliant PDF + SBOM out-of-the-box. --cra, done.

Package managers

Seven ecosystems. One binary.

Every detector walks the real manifests and lockfiles your project ships with — not just package.json, but package-lock.json v1, v2 and v3. Lockfile-first means actual versions, actual licenses, no resolver guesswork.

Go modulesgo 1.22+
go.mod · go.sum
local module cache
Nodenpm · yarn · pnpm
package.json + lockfile
v1 · v2 · v3
PHPcomposer
composer.json
composer.lock · vendor/
Rustcargo
Cargo.toml · Cargo.lock
~/.cargo/registry
Rubybundler
Gemfile.lock
vendor/bundle · $GEM_HOME
Pythonpip · poetry · pipenv
poetry.lock · Pipfile.lock
requirements.txt · pyproject.toml
Javamaven
pom.xml
~/.m2/repository
Roadmapcocoapods · pub · …
5-level risk model

From safe to ship to denied at CI.

Every license gets one of five risk labels based on its SPDX identifier. Configure which levels are deny, warn or allow_exceptions in a single .licscan.yml.

PERMISSIVE
Permissive MIT · Apache-2.0 · BSD-3 · ISC · 0BSD
SHIP
WEAK COPYLEFT
Weak copyleft LGPL · MPL-2.0 · EPL · CDDL
WARN
STRONG COPYLEFT
Strong copyleft GPL-2.0 · GPL-3.0 · EUPL
REVIEW
VIRAL / NETWORK
Viral AGPL-3.0 · SSPL · BUSL · custom-restrictive
DENY
UNKNOWN
Unknown no SPDX match found — needs review
FLAG
.licscan.yml
# Project license policy
deny:
  - GPL-3.0-or-later
  - AGPL-3.0-or-later
  - SSPL-1.0
  - BUSL-1.1

warn:
  - LGPL-3.0-or-later
  - MPL-2.0
  - EPL-2.0

allow_exceptions:
  - name:     "github.com/foo/legacy-lib"
    license:  "GPL-2.0"
    reason:   "vendored, isolated by ADR-019"

manufacturer: "Acme GmbH"
product:      "acme-api"
Output formats

Pipe it. Render it. Submit it.

One scan, nine outputs. Same data, every format. Pick what you need — the CI gate, the PR comment, the security review, the auditor PDF.

--format table

Terminal table

The default. Colorised, sortable summary. Perfect for local runs and CI logs.

--format json

JSON

Strict schema. Pipe into jq, store in object storage, diff against last week.

--format html

HTML report

Dark-theme, XSS-safe, single file. Drop on S3 for the security team to read.

--format markdown

Markdown

GitHub-flavoured, PR-comment-ready, auto-collapses past 30 dependencies. Verdict column.

--format cyclonedx

CycloneDX 1.5

Industry-standard SBOM with canonical PURLs per dependency. ECMA-404 JSON.

--format spdx

SPDX 2.3

The other industry SBOM standard. Mandated by NTIA, US-EO 14028 and procurement.

--format sarif

SARIF 2.1.0

Upload to GitHub Code Scanning via upload-sarif. License violations surface in the Security tab.

--format junit

JUnit XML

Jenkins, GitLab CI, Azure DevOps — any CI that ingests xUnit reports. Each dep is a testcase.

licscan notice

NOTICE file

Auto-generated THIRD_PARTY_LICENSES with every dependency and its license. Ship it with your binary.

DIFFERENTIATOR

EU Cyber Resilience Act,
in one flag.

The CRA hits in 2027. Every vendor of digital products in the EU needs to ship a software bill of materials with their releases, mapped to a manufacturer and a product. Most license scanners can't do that.

licscan emits an auditor-grade PDF and a CRA-extended CycloneDX JSON in one command — with manufacturer metadata, product metadata, scan timestamp and policy verdict already baked in.

  • Native Go PDF rendering — no headless Chromium, no LaTeX, no Pandoc dependency
  • CycloneDX 1.5 + CRA fields — manufacturer · product · supplier · auditTrail
  • Reproducible builds — same scan, same hash, every time
  • Self-contained — runs on an air-gapped machine, behind your firewall
$licscan scan . --cra --cra-output ./compliance/
★ EU CRA Software Compliance Report licscan v0.15.0

acme-api · v3.2.1

Generated 2026-05-25 · licscan-cra-export

Manufacturer · Product

Manufacturer
Acme GmbH
Product
acme-api
Version
3.2.1
CRA Article
Art. 13 · Annex I

Dependencies · 337 total · 0 unknowns

github.com/spf13/cobrav1.8.0Apache-2.0
golang.org/x/modv0.23.0BSD-3
npm:lodash4.17.21MIT
npm:react18.3.1MIT
…and 333 more
Policy: deny GPL/AGPL/SSPL/BUSL ✓ PASS · CRA-READY
CI integration

Gate every PR. One step.

The official GitHub Action runs licscan against your repo on every pull request, comments the verdict inline, fails the build on a deny, and uploads the SBOM artefact. No JS runtime, just YAML and shell.

.github/workflows/licscan.yml YAML
name: License compliance

on:
  pull_request:
  push:
    branches: [main]

jobs:
  licscan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: codelake-dev/licscan-action@v1
        with:
          format:              sarif
          fail-on-violation:   true
          pr-comment:          true
          cra:                 true
          upload-artifact:     true

      # Upload SARIF to GitHub Security tab
      - run: licscan scan . --format sarif > results.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Run your first scan in two minutes.

One binary. Seven package managers. Nine output formats. Apache 2.0, no account, no telemetry.

$ brew install codelake-dev/tap/licscan
Get in touch hello@licscan.dev
For bugs, please open an issue on GitHub.