rights-preflight

Catch missing and conflicting licenses in your fonts, images, audio, video and 3D files before you ship.

Install
$ pip install git+https://github.com/sohaibt/rights-preflight

Requires Python 3.9 or newer. Standard library only, so it installs no other packages. It is not on PyPI yet, so this installs straight from GitHub.

Then point it at your asset folder
$ rights-preflight check assets/ --commercial

What it does

Creative projects collect assets from everywhere: a font from a foundry, photos from a stock site, sound effects from Freesound, a model someone generated. By launch day nobody remembers which ones need credit, and which ones you can't use commercially.

rights-preflight is a rights gate for that folder. It lists every media file, finds the ones with missing or conflicting licenses, fails the build when something is wrong, and writes a ready-to-ship CREDITS.md.

CommandWhat it does
scanLists media files and writes rights-manifest.json, recording where each field came from
checkExits 1 on any rights problem. --commercial also fails on NC assets; --json for CI
creditsWrites CREDITS.md, grouped by license

It covers fonts, images, audio, video and 3D files. It runs locally or in CI, on any platform with Python.

Where rights come from

For each field (license, author, source) the first source that has a value wins:

  • 1. Sidecar. A <file>.rights.json next to the file, for example hero.png.rights.json.
  • 2. Project rules. A rights.json in the scanned folder. The first rule whose glob matches the file's path wins.
  • 3. Embedded metadata. The font name table for TTF, OTF, TTC and WOFF, and XMP in images.
{"rules": [
  {"glob": "fonts/*", "license": "OFL"},
  {"glob": "sfx/**", "license": "CC0", "author": "Freesound", "source": "https://freesound.org"}
]}

One rights.json covers a whole folder of sound effects or fonts. Sidecars handle the exceptions.

Built-in licenses

"Attribution required" means check fails unless both author and source are set.

IDAttribution requiredCommercial use
CC0NoYes
CC-BYYesYes
CC-BY-SAYesYes
CC-BY-NCYesNo
OFLNoYes
Apache-2.0YesYes
MITYesYes
public-domainNoYes
licensed-proprietaryNoYes
ai-generatedNoYes

IDs match case-insensitively and version suffixes are ignored (CC BY 4.0, OFL-1.1, Apache 2.0). License URLs and common license names are recognised too. Anything else, like CC-BY-ND, is reported as unknown-license.

What it looks like

A folder with problems

$ rights-preflight check assets/ --commercial
images/hero.png: missing-source: CC-BY requires attribution: add source
music/loop.mp3: unknown-license: unknown license: WTFPL
images/bg.png: non-commercial: CC-BY-NC does not allow commercial use
3 problems in 3 of 42 files

Exit codes: 0 clean, 1 problems found, 2 bad input (missing folder, invalid rights.json).

The credits it writes

# Credits

Generated by rights-preflight. Grouped by license.

## Creative Commons Attribution 4.0 (CC-BY)

License: https://creativecommons.org/licenses/by/4.0/

- `images/photo.png` by Jane Photo, source: https://example.com/photo

## SIL Open Font License 1.1 (OFL)

License: https://openfontlicense.org/

- `fonts/Demo.ttf` by Ada Demo, source: https://example.com/foundry

Files without resolved rights are listed last, so gaps stay visible.

What it checks

CodeMeaning
missing-licenseNo license from any source
unknown-licenseLicense text is not in the table
missing-author / missing-sourceThe license requires attribution
non-commercialNC license, when run with --commercial
bad-sidecarA .rights.json file is not a valid JSON object

Common questions

Is it legal advice?
No. It checks that every asset has a license and the attribution that license asks for, against a policy you choose. Whether a license fits your use is still your call.
Does it install other packages?
No. It uses the Python standard library only. The GitHub Action runs it with the runner's python3 and installs nothing.
My license isn't in the table. What happens?
check reports it as unknown-license. Custom license IDs in rights.json are not supported yet.
Does it read every file format's metadata?
Not yet. Compressed XMP in PNG text chunks and WOFF2 fonts are not read. Add a sidecar or a rights.json rule for those files.
How do I handle AI-generated assets?
Label them ai-generated in a sidecar or rule. They then appear in CREDITS.md under their own heading, so the list shows what was generated.
Is it free?
Yes. MIT license.

How it is different

ScanCode / REUSE
Detect source-code licenses and SPDX headers. They are weak on fonts and media and have no attribution rules.
License Keeper / AssetTrail
Desktop trackers with manual entry and no CI.
C2PA
Records where media came from. It does not enforce a rights policy.

rights-preflight is one cross-platform CLI that reads rights from sidecars, project rules and embedded metadata, enforces a policy that fails CI, and writes CREDITS.md plus a machine-readable manifest.

Want help shipping your next product? Get in touch.