Home

Awesome

lichen 🍃

Go binary license checker. Extracts module usage information from binaries and analyses their licenses.

Features

Improvements over existing tooling

Install

go install github.com/uw-labs/lichen@latest

Note that Go must be installed wherever lichen is intended to be run, as lichen executes various Go commands (as discussed in the previous section).

Usage

By default lichen simply prints each module with its respective license. A path to at least one Go compiled binary must be supplied. Permitted licenses can be configured, along with overrides and exceptions (see Config).

lichen --config=path/to/lichen.yaml [binary ...]

Run lichen --help for further information on flags.

Note that the where lichen runs the Go executable, the process is created with the same environment as lichen itself - therefore you can set Go related environment variables (e.g. GOPRIVATE) and these will be respected.

Example

We can run lichen on itself:

$ lichen $GOPATH/bin/lichen
github.com/cpuguy83/go-md2man/v2@v2.0.0-20190314233015-f79a8a8ca69d: MIT (allowed)
github.com/google/goterm@v0.0.0-20190703233501-fc88cf888a3f: BSD-3-Clause (allowed)
github.com/google/licenseclassifier@v0.0.0-20200402202327-879cb1424de0: Apache-2.0 (allowed)
github.com/hashicorp/errwrap@v1.0.0: MPL-2.0 (allowed)
github.com/hashicorp/go-multierror@v1.1.0: MPL-2.0 (allowed)
github.com/lucasb-eyer/go-colorful@v1.0.3: MIT (allowed)
github.com/mattn/go-isatty@v0.0.12: MIT (allowed)
github.com/muesli/termenv@v0.5.2: MIT (allowed)
github.com/russross/blackfriday/v2@v2.0.1: BSD-2-Clause (allowed)
github.com/sergi/go-diff@v1.0.0: MIT (allowed)
github.com/shurcooL/sanitized_anchor_name@v1.0.0: MIT (allowed)
github.com/urfave/cli/v2@v2.2.0: MIT (allowed)
golang.org/x/sys@v0.0.0-20200116001909-b77594299b42: BSD-3-Clause (allowed)
gopkg.in/yaml.v2@v2.3.0: Apache-2.0, MIT (allowed)

...and using a custom template:

$ lichen --template="{{range .Modules}}{{range .Module.Licenses}}{{.Name | printf \"%s\n\"}}{{end}}{{end}}" $GOPATH/bin/lichen | sort | uniq -c | sort -nr
   8 MIT
   2 MPL-2.0
   2 BSD-3-Clause
   2 Apache-2.0
   1 BSD-2-Clause

Config

Configuration is entirely optional. If you wish to use lichen to ensure only permitted licenses are in use, you can use the configuration to specify these. You can also override certain defaults or force a license if lichen cannot detect one.

Example:

# minimum confidence percentage used during license classification
threshold: .80

# all permitted licenses - if no list is specified, all licenses are assumed to be allowed
allow:
  - "MIT"
  - "Apache-2.0"
  - "0BSD"
  - "BSD-3-Clause"
  - "BSD-2-Clause"
  - "BSD-2-Clause-FreeBSD"
  - "MPL-2.0"
  - "ISC"
  - "PostgreSQL"

# overrides for cases where a license cannot be detected, but the software is licensed
override:
  - path: "github.com/abc/xyz"
    version: "v0.1.0" # version is optional - if specified, the override will only apply for the configured version
    licenses: ["MIT"] # specify licenses

# exceptions for violations
exceptions:
  # exceptions for "license not permitted" type violations
  licenseNotPermitted:
    - path: "github.com/foo/bar"
      version: "v0.1.0" # version is optional - if specified, the exception will only apply to the configured version
      licenses: ["LGPL-3.0"] # licenses is optional - if specified only violations in relation to the listed licenses will be ignored
    - path: "github.com/baz/xyz"
  # exceptions for "unresolvable license" type violations
  unresolvableLicense:
    - path: "github.com/test/foo"
      version: "v1.0.1" # version is optional - if unspecified, the exception will apply to all versions

Credit

This project was very much inspired by mitchellh/golicense

Caveat emptor

Just as a linter cannot guarantee working and correct code, this tool cannot guarantee dependencies and their licenses are determined with absolute correctness. lichen is designed to help catch cases that might fall through the net, but it is by no means a replacement for manual inspection and evaluation of dependencies.