Feluda · Open Source India, 2026
Licenses Are
for Everyone,
Not Just Lawyers
Kumar Anirudha
x.com/kranirudha · github.com/anistark
github.com/anistark/feluda
**
Every install is a contract you didn't read.
Licenses 101
Code is “all rights reserved” by default
Copyright
Applies automatically the moment someone writes the code.
License
The author's written permission, with conditions attached.
You
May use, change and share it, as long as you meet those conditions.
No LICENSE file doesn't mean free to use. It means ask first.
Licenses 101
A spectrum, not a yes or no
← fewer obligations
more obligations →
Permissive
MIT · BSD · Apache-2.0 · ISC
Do almost anything. Keep the copyright notice.
Weak copyleft
LGPL · MPL-2.0 · EPL-2.0
Share your changes to the library or files you modified.
Strong copyleft
GPL-2.0 · GPL-3.0
Distribute a derived work and all of it goes out under the GPL.
Network copyleft
AGPL-3.0
People using it over a network are owed the source too.
Unknown
None · custom · “see LICENSE”
Treat as all rights reserved until someone reads it.
Licenses 101
What each one asks of you
License
Keep notices
Share changes
What must stay open
Patent grant
MIT
Yes
No
Nothing
Not explicit
Apache-2.0
Yes + NOTICE file
No
Nothing (mark changes)
Yes
MPL-2.0
Yes
Yes
The files you modified
Yes
LGPL-3.0
Yes
Yes
The library itself
Yes
GPL-3.0
Yes
Yes
Whole work, if distributed
Yes
AGPL-3.0
Yes
Yes
Whole work + network users
Yes
Every license asks for credit. They differ on what must stay open, and when that kicks in.
Simplified for a slide. Not legal advice: the license text is the source of truth.
Licenses 101
Licenses have to get along
MIT · BSD
Apache-2.0
LGPL · MPL
GPL-3.0
AGPL-3.0
Code can usually flow toward more obligations. Rarely back.
MIT app + GPL-3.0 dependency
Ship it as a binary and the combined work goes out under GPL-3.0 terms. Fine if you meant it; a surprise if you didn't.
Apache-2.0 + GPL-2.0-only
Incompatible: Apache's patent terms add conditions GPL-2.0 doesn't allow. GPL-3.0 fixed that.
Licenses 101
Four things we tell ourselves
“It's on GitHub, so it's free.”
Public isn't licensed. No license means all rights reserved.
“We only use it internally.”
Until you ship an app, a binary or a container. AGPL counts network users too.
“I checked my dependencies.”
The direct ones. Transitive dependencies bring their own licenses.
“Legal will catch it.”
Usually at release, fundraising or acquisition: the most expensive moment to find out.
Why you should care
If you ship code, licenses are your job too
Maintainers
Choose your license on purpose, and check your dependencies allow it.
Engineers
“No AGPL” is company policy. You're the one typing the install command.
Founders
Due diligence asks for a license inventory, usually at fundraising or acquisition.
Students
Attribution is how open source pays its people. Keep the notices.
Whoever adds the dependency owns the license question. Legal only sees it later.
Why you should care
What you declare isn't what you ship
Transitive
Dependencies of your dependencies bring their own licenses.
Vendored
Code copied into vendor/ or third_party/ that no manifest mentions.
Pasted
A snippet from a forum or an AI assistant, still carrying someone else's license header.
Shipped
OS packages and runtimes inside the container image you deploy.
your manifest
what you ship
So
License checks belong where dependencies change.
Terminal
Commits
CI
Images
Meet Feluda
A detective for your dependency tree
A Rust CLI that reads your dependencies, notes each license, and flags anything restrictive or incompatible with your project's license. MIT licensed, v1.16.
# install · also on AUR, pkgsrc, .deb, .rpm
$ cargo install feluda
$ brew install feluda
# then, inside your project
$ feluda
Meet Feluda
How Feluda solves the case
Detect
Finds the manifests and lockfiles in your project.
Read locally
node_modules, Cargo.toml and package caches first.
Ask upstream
Registries and the GitHub API, cached for 30 days.
Fill gaps
Unresolved ones go to ClearlyDefined in one batch.
Judge
Restrictive list, compatibility matrix and OSI status.
Then it reports: a table, JSON, YAML, SARIF, or a non-zero exit code that fails the build.
Meet Feluda
Many ecosystems, one command
Rust
Cargo.lock
Node.js
npm pnpm yarn bun
Python
pyproject Pipfile
Go
go.mod go.work
Java
Maven Gradle
C / C++
Conan
Ruby
Gemfile.lock
R
DESCRIPTION renv
.NET
csproj fsproj
Mixed?
scans them all
Force one with feluda --language rust, or let it detect every ecosystem in a polyglot repo.
Meet Feluda
It looks past your manifests
In your repo
own source
Your files carrying a foreign SPDX header: the copy-paste and AI-paste case.
vendored
Packages inside vendor/, third_party/ or external/.
unmanaged
A LICENSE or COPYING file that no manifest accounts for.
In what you ship
--image-archive
A docker save tarball or OCI layout. No registry, no credentials.
--filesystem
apk, dpkg and rpm databases, plus Python, Node and Go binaries.
--sbom-input
An SPDX or CycloneDX document from syft, Trivy, cdxgen or a vendor.
Meet Feluda
Reports for people, pipelines and auditors
For you
- A table by default
- --gist for one screen
- --verbose adds OSI status
- --gui opens a terminal UI
For pipelines
- --json and --yaml
- --ci-format github, jenkins or sarif
- --fail-on-restrictive
- --fail-on-incompatible
For auditors
- NOTICE file
- THIRD_PARTY_LICENSES with full texts
- SBOMs in SPDX 2.3 and CycloneDX 1.5
- feluda sbom validate
Use it · 1 of 4
Start on your laptop
$ feluda
Scan the current project
$ feluda --gist
A one-screen summary
$ feluda --restrictive
Only the risky ones
$ feluda --project-license MIT --incompatible
What can't live inside MIT
$ feluda --gui
Browse in the terminal UI
$ feluda --repo <git-url>
Check a repo before you adopt it
$ feluda watch
Re-scan when a manifest changes
Use it · 2 of 4
Write your policy down, once
feluda init writes a .feluda.toml and a pre-commit hook.
- Defaults flag GPL, AGPL, LGPL-3.0, MPL-2.0, EPL-2.0 and CC-BY-SA-4.0
- Override that list, ignore licenses, or skip whole dependencies
- Custom rules name bespoke license texts
- Environment variables beat the file; the file beats defaults
# .feluda.toml
[licenses]
restrictive = ["GPL-3.0", "AGPL-3.0"]
ignore = ["MIT", "Apache-2.0"]
[[licenses.custom]]
id = "LicenseRef-acme-internal"
match_all = ["ACME CONFIDENTIAL"]
restrictive = true
Use it · 3 of 4
Gate every pull request
# .github/workflows/license.yml
- name: Scan licenses
uses: anistark/feluda@v1
with:
fail-on-restrictive: true
fail-on-incompatible: true
project-license: 'MIT'
GitHub Action
Feluda License Scanner on the Marketplace. No install step.
SARIF
Findings in GitHub's Security tab: restrictive as warnings, incompatible as errors.
Jenkins
JUnit XML for test reports; a sample Jenkinsfile in examples/ci.
PR #42
✓ build
✓ tests
✗ licenses: GPL-3.0 in a transitive dependency, merge blocked
Use it · 4 of 4
Scan what you actually ship
# a saved image: layers squashed for you, no registry needed
$ docker save app:latest > app.tar
$ feluda --image-archive app.tar --fail-on-restrictive
# an SBOM from syft, Trivy or cdxgen
$ syft nginx:latest -o spdx-json | feluda --sbom-input - --fail-on-restrictive
# and write your own
$ feluda sbom spdx --image-archive app.tar --output app.spdx.json
Agent Native
Let your coding agent check first
Agents add dependencies faster than people do. Feluda plugs into them, so the scan runs when a manifest changes, before you commit.
# Claude Code skill
/plugin install feluda@agenthub
# pi extension
pi install npm:feluda-pi-extension
farhaanbukhsh/feluda-pi-extension
github.com · pi extension by Farhaan Bukhsh
It's open source · MIT licensed
Come build Feluda with us
github.com/anistark/feluda
feluda.readthedocs.io
discord.gg/AJMEeFXxXy
Scan to open the repo
Star it, fork it, file an issue.
Good places to start
Add a language
There's a step-by-step guide in the docs
Tune the license matrix
It's a TOML file, no Rust needed
Report a license it gets wrong
An issue is a real contribution
Thank you
Questions?
Kumar Anirudha
x.com/kranirudha
fosstodon.com/@ani