원클릭으로
license-scanner
Scans dependencies for license compliance, attribution gaps, and copyleft conflicts.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Scans dependencies for license compliance, attribution gaps, and copyleft conflicts.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Reference copy of the operating contract for the defense lens at a human gate — input binding, the six sources of the case for crossing, the untrusted-input and exhibit-marker rules, the evidence whitelist, the degraded-input table, the severity/confidence/variance scales, the output contract, and the escalation table. NOT preloaded into any agent. agents/iron-loop/advocate-critic.md carries this contract in its own body; this file is loadable on demand through the Skill tool by any agent that needs to read the same rules.
Reviews AI-generated code for common pitfalls — over-engineering, missing edge cases, fabricated patterns, hallucinated imports, stale framework idioms, vacuous tests.
Detects AI-generated code that references non-existent packages, APIs, methods, or fabricated patterns.
Paranoid LLM red-team analyst — scans applications that call LLMs for OWASP LLM Top 10 v2 (2025) findings and maps them to MITRE ATLAS v5.4.0 adversary tactics.
Builds the import graph and detects circular dependencies, layer violations, instability mismatches, and cross-module coupling.
Detects which architecture pattern a codebase follows (Layered, Hexagonal, Clean, Onion, CQRS, DDD, Vertical Slice, Modular Monolith, Microservices) with confidence scoring across 7 languages.
| name | license-scanner |
| description | Scans dependencies for license compliance, attribution gaps, and copyleft conflicts. |
| type | skill |
| when_to_load | ["license scan","OSS licenses","license compatibility","license compliance","license check","license audit"] |
| related_skills | ["compliance/gdpr-compliance-checker","security/dependency-auditor","security/dependency-checker"] |
| effort_level | medium |
| tools | Bash, Read |
| model | sonnet |
| tier | 2 |
| dispatch_protocol | v1 |
| confidence_calibration | enabled |
| parallel_safe | true |
| effort_budget | {"max_subagents":0} |
Converted from agents/compliance/license-scanner.md as part of CTOC v7 B2 leaf-node sweep. Auto-loaded when the user prompt matches a when_to_load trigger.
You are a license-compliance analyst. You scan the dependency graph (direct + transitive) for problematic licenses, license drift across upgrades, missing attribution, and conflicts with the host project's own license. You treat license risk the same way SAST treats vulnerabilities: every finding ships as severity: critical on the wire (warnings-are-bugs), with internal triage tiers used only in the human-readable report.
MIT, Apache-2.0, BSD-3-Clause, ISC, Apache-2.0 OR MIT). Anything outside the allowlist → review queue. Blocklist-style policies miss dual-licensed packages whose effective license drifts on upgrade.WITH for exceptions, AND/OR for compounds). Free-text license strings ("Apache style") do not survive automated review — coerce to SPDX or mark unknown.(package, version, license_spdx) so the second PR with the same dep passes silently.commercial-licenses.yaml ledger with renewal date, scope, and contract reference — not in the OSS scanner output. Mixing them produces noise.critical letter. License drift on a transitive dep can silently change the host product's obligations.These map to the letter kind field.
| Kind | Example | Action |
|---|---|---|
agpl_in_saas_tree | AGPL-3.0 dep reachable from a SaaS backend | Block; legal review required |
gpl_incompatible_with_product | GPL-3.0 dep in a proprietary or MIT-licensed library distributed to users | Block; replace or relicense product |
missing_license_field | Own package's package.json / pyproject.toml / Cargo.toml has no SPDX license field | Add field; default-deny consumers |
dual_license_unclear_default | Dep declares MIT OR GPL-2.0 and the build doesn't pin the effective choice | Pin chosen license in policy file |
license_drift_after_upgrade | Dep x@2.x was MIT, x@3.x is BSL — upgrade introduces new obligation | Block upgrade; legal review |
copyright_notice_missing | Apache-2.0 dep present but NOTICE file not bundled in release artifact | Regenerate attribution bundle |
unknown_license_dep | Dep ships no LICENSE file, registry metadata says UNLICENSED or empty | Manual review; do not assume permissive |
sspl_or_bsl_in_oss_product | SSPL/BSL dep in a product the company markets as open source | Block; SSPL/BSL are not OSI-approved |
commercial_license_unbooked | Commercial dep present but not in commercial-licenses.yaml ledger | Add ledger entry with contract ref |
| License (SPDX) | Commercial Use | Notes |
|---|---|---|
MIT | Yes | Copyright notice required |
BSD-2-Clause / BSD-3-Clause | Yes | Copyright + notice; BSD-3 adds non-endorsement |
Apache-2.0 | Yes | NOTICE preservation + patent grant + state-of-changes |
ISC | Yes | Equivalent to simplified BSD |
0BSD / Unlicense / CC0-1.0 | Yes | Public-domain-equivalent; verify legality in your jurisdiction |
| License (SPDX) | Trigger | Notes |
|---|---|---|
LGPL-2.1-only / LGPL-3.0-only | Distribution; modification of LGPL code itself | Dynamic-link usage is generally OK; static link or modification triggers source-disclosure |
MPL-2.0 | File-level | Modified MPL files must be released; unmodified consumption is fine |
EPL-2.0 | Distribution | Reciprocal at the file level |
| License (SPDX) | Trigger | Why blocked |
|---|---|---|
GPL-2.0-only / GPL-2.0-or-later | Distribution | Whole-program copyleft on distributed binary |
GPL-3.0-only / GPL-3.0-or-later | Distribution | Adds patent + anti-tivoization clauses; incompatible with Apache-2.0 patent-grant nuances for some combinations |
AGPL-3.0-only / AGPL-3.0-or-later | Network use | The SaaS killer — backend exposure to a user over a network is a trigger |
| License | Issue |
|---|---|
SSPL-1.0 | Server-side public license — MongoDB, Elastic; not OSI-approved; viral to "management software" |
BUSL-1.1 (BSL) | Time-delayed open source; converts to a permissive license after N years but is proprietary until then |
Commons-Clause | Bolted onto an OSS license to forbid selling — not OSI; effectively commercial |
Custom / Proprietary | Requires paid license; track in commercial ledger |
NOASSERTION / Unknown | Cannot verify compliance — manual review only |
MIT -> GPL-2.0 : Compatible (MIT code can be combined into a GPL project)
GPL-2.0 -> MIT : NOT compatible (resulting work must be GPL)
Apache-2 -> GPL-3.0 : Compatible (FSF-confirmed)
Apache-2 -> GPL-2.0 : NOT compatible (Apache-2 patent termination clash with GPL-2-only)
GPL-2-only -> GPL-3 : NOT compatible (only-clause forbids upgrade)
MPL-2.0 -> GPL/LGPL : Compatible via MPL-2.0 secondary-license clause
AGPL-3.0 -> GPL-3.0 : Network-use clause survives — host product becomes AGPL-bound on SaaS
When in doubt, mark unknown and route to legal. The scanner does not invent compatibility judgments.
The scanner runs the per-ecosystem command, parses output to SPDX, joins against the allowlist, then emits letters. Each command below is what the skill executes (or instructs CI to execute) for that ecosystem.
# license-checker — broadest coverage, JSON for piping
npx license-checker --production --json --excludePrivatePackages > licenses-js.json
# Block on disallowed licenses in CI:
npx license-checker --production --failOn "GPL;AGPL;SSPL;BUSL;Commons-Clause;UNLICENSED;UNKNOWN"
# Generate attribution bundle (CSV) for release artifact:
npx license-checker --production --csv --customPath license-customformat.json > NOTICE.csv
# pip-licenses — JSON for the pipeline, allowlist enforcement on the build
pip-licenses --format=json --with-urls --with-license-file > licenses-py.json
pip-licenses --allow-only="MIT;BSD;BSD-2-Clause;BSD-3-Clause;Apache-2.0;ISC;Python-2.0;PSF-2.0"
# Poetry users: poetry export then pip-licenses against the venv
poetry export -f requirements.txt --output requirements.txt
pip install -r requirements.txt && pip-licenses --format=json
# Maven — licensescan-maven-plugin asserts and fails the build
mvn org.carlomorelli:licensescan-maven-plugin:audit -DfailBuildOnViolation=true
# Alternative: license-maven-plugin (chonton) for compliance check + report
mvn org.honton.chas:license-maven-plugin:check
# Gradle — com.github.jk1.dependency-license-report
./gradlew generateLicenseReport
# License scan — nuget-license: prints and validates licenses for .NET / .NET Core / Standard
dotnet tool install --global nuget-license
nuget-license --input <Solution.sln> --output JsonPretty > licenses-nuget.json
# Allowlist enforcement (this is the license gate):
nuget-license --input <Solution.sln> --allowed-license-types allowed-licenses.json
# Separately — vulnerability + transitive scan (a different lens; owned by [[dependency-auditor]]).
# Listed here only because the .NET workflow commonly runs both side-by-side:
dotnet list package --vulnerable --include-transitive
# cargo-license — flat list, JSON output
cargo install cargo-license
cargo license --json > licenses-rust.json
# cargo-deny — policy-driven gate, the production choice
cargo install cargo-deny
cargo deny check licenses # uses deny.toml allow/deny lists
Example deny.toml skeleton:
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "Apache-2.0 WITH LLVM-exception"]
deny = ["GPL-2.0", "GPL-3.0", "AGPL-3.0", "SSPL-1.0", "BUSL-1.1"]
confidence-threshold = 0.93
# go-licenses (Google) — report and verify
go install github.com/google/go-licenses@latest
go-licenses report ./... --template '{{range .}}{{.Name}},{{.LicenseName}},{{.LicenseURL}}{{"\n"}}{{end}}' > licenses-go.csv
# Fail build on disallowed:
go-licenses check ./... --disallowed_types=forbidden,restricted,unknown
# Alternative: OSV-Scanner now ships license scanning alongside vuln scanning
osv-scanner --licenses --format json ./...
vcpkg and Conan ship per-port license metadata but no canonical scanner. The minimal viable path:
# vcpkg — license is in each port's vcpkg.json "license" field (SPDX)
jq -r '.name + "," + (.license // "UNKNOWN")' vcpkg_installed/*/share/*/vcpkg.json > licenses-vcpkg.csv
# Conan 2.x — license is in each package's recipe metadata
conan list --format=json '*' | jq -r '.[] | [.ref, .license] | @csv' > licenses-conan.csv
# Or escalate to ScanCode Toolkit on the vendored source tree:
scancode --license --json licenses-cpp.json vendor/
For C/C++ the realistic recommendation is to escalate to ScanCode Toolkit or FOSSology against the vendored/built tree — package-manager metadata in this ecosystem is thinner than in npm/pip/cargo.
fossa analyze && fossa report licenses --format spdx > sbom-licenses.spdx.json
snyk test --print-deps --json-file-output=snyk-licenses.json
ort analyze -i . -o ort-results && ort evaluate -i ort-results --license-classifications-file classifications.yml
scancode --license --copyright --package --json scancode-results.json .
Three tiers — pick by deployment posture, not by feature checklist alone.
| Tool | Posture | Strengths | Trade-offs |
|---|---|---|---|
| FOSSA | Audit-grade SaaS | Strong license-detection accuracy across many languages and build systems; SBOM (SPDX + CycloneDX) generation; policy engine; pull-request gates | SaaS-only for the managed tier; team/enterprise pricing; some telemetry from CI runners |
| Snyk License | Developer-first SaaS | Same UI as Snyk Open Source (SCA) and Snyk Code; fast PR fixes; license + vulns in one report | License engine narrower than FOSSA/Black Duck on edge cases (custom licenses, exotic dual-licensing) |
| Black Duck | Enterprise / regulated | Deep license + IP knowledge base; binary scanning (third-party libs without source); policy engine for hundreds of projects; audit-acceptable for M&A | Heavy install; commercial; orientation toward enterprise compliance, not dev workflow |
| ScanCode Toolkit | OSS, self-hosted | License + copyright + package detection from raw source trees; SPDX output; no telemetry | Slower than registry-metadata scanners; requires source, not just lockfiles |
| FOSSology | OSS, self-hosted workflow | Full audit workflow: scan → review → clear → report. Used by Linux Foundation projects | Operational overhead — needs a server, a DB, and reviewers |
| SPDX validator | Spec compliance | Validates an SBOM is a well-formed SPDX 2.3 / 3.0 document | Spec validation only; no license-policy enforcement |
| license-checker / pip-licenses / cargo-license / go-licenses / nuget-license | OSS, per-ecosystem CLI | Fast, free, lockfile-driven; perfect for PR-gate diff-mode | Per-ecosystem — no cross-language aggregation; weaker on dual-license disambiguation |
| OSV-Scanner | OSS, Google-maintained | License scanning ships alongside vuln scanning since the 2024 license-mode release; one tool, two lenses | License coverage narrower than dedicated scanners; pair with one of the above |
Recommended baseline: per-ecosystem CLI on every PR (diff-mode, fast) + a SaaS or OSS audit-grade scanner (FOSSA / Black Duck / FOSSology / ScanCode) nightly or pre-release.
## License Compliance Report
### Summary
| Category | Count |
|---|---|
| Permissive (allowlist) | 145 |
| Weak copyleft (review) | 3 |
| Strong copyleft (BLOCK) | 1 |
| SSPL / BSL / commercial | 0 |
| Unknown / NOASSERTION | 2 |
| **Total** | **151** |
### Critical
1. **AGPL-3.0 dep reachable from SaaS backend** (`agpl_in_saas_tree`)
- Package: `example-agpl-lib@4.2.0`
- Required by: `web-server-runtime`
- Impact: Network-use trigger; obligates server-source disclosure under AGPL-3.0
- Fix: Replace with MIT/Apache-2.0 alternative OR scope legal review with written sign-off
2. **Unknown license** (`unknown_license_dep`)
- Package: `internal-utils@1.0.0`
- Registry metadata: empty `license` field; no LICENSE file in artifact
- Fix: Contact maintainer; do not assume permissive
3. **License drift after upgrade** (`license_drift_after_upgrade`)
- Package: `state-store@7.0.0 -> 8.0.0`
- SPDX change: `Apache-2.0` -> `SSPL-1.0`
- Fix: Block upgrade; legal review
### Warnings (internal triage — still ship as critical on the wire)
- LGPL-2.1 deps (3 packages) — verify dynamic linking only
- Apache-2.0 deps requiring NOTICE preservation (18 packages) — regenerate attribution bundle
### Project License
- Current: MIT (declared in `package.json`)
- Compatibility verdict: NOT compatible — AGPL dep in the tree
### Recommendations
1. Replace `example-agpl-lib` with `permissive-alt` (Apache-2.0)
2. Resolve `internal-utils` license metadata before next release
3. Block `state-store@8.x` upgrade pending legal review
4. Regenerate NOTICE bundle and ship with release artifact
5. Pin allowlist in CI (`license-checker --failOn`, `cargo deny check licenses`, etc.)
# JS
- name: Check JS licenses
run: npx license-checker --production --failOn "GPL;AGPL;SSPL;BUSL;Commons-Clause;UNLICENSED;UNKNOWN"
# Python
- name: Check Python licenses
run: pip-licenses --allow-only="MIT;BSD;BSD-2-Clause;BSD-3-Clause;Apache-2.0;ISC"
# Rust
- name: Check Rust licenses
run: cargo deny check licenses
# Go
- name: Check Go licenses
run: go-licenses check ./... --disallowed_types=forbidden,restricted,unknown
# .NET
- name: Check NuGet licenses
run: nuget-license --input MySolution.sln --allowed-license-types allowed-licenses.json
# SBOM (multi-language)
- name: Emit SPDX SBOM
run: fossa analyze && fossa report licenses --format spdx > sbom-licenses.spdx.json
These tiers are the internal triage view used in the human-readable report. When this skill emits a letter to CTO Chief via the refinement loop, every finding becomes severity: critical per the warnings-are-bugs rule — see agents/_shared/warnings-are-critical.md. The triage tiers stay in the report body for prioritization; the letter's severity field is always critical.
| Triage tier | Examples | Internal action |
|---|---|---|
| CRITICAL | AGPL in SaaS tree · GPL incompatible with product license · SSPL/BSL in OSS product · license drift to copyleft on upgrade | BLOCK |
| HIGH | Unknown license · missing license field in own package · dual-license unclear default · commercial dep unbooked | Resolve before release |
| MEDIUM | LGPL with linking-method unverified · MPL-2.0 modifications uncleared · NOTICE preservation gap | Fix this sprint |
| LOW | Permissive deps missing attribution-bundle line · cosmetic SPDX-id casing | Backlog |
When emitting a finding via the refinement loop, write the letter with these fields:
finding_id: <sha256(critic+file+line+kind+package)[:12]> # fingerprint for dedup
severity: critical # ALWAYS critical (warnings-are-bugs)
confidence: high | medium | low # high = SPDX match + lockfile pin; low = inferred from text
engine: license-checker | pip-licenses | cargo-license | cargo-deny | go-licenses | nuget-license | licensescan-maven-plugin | scancode | fossa | snyk | blackduck | manual
kind: agpl_in_saas_tree | gpl_incompatible_with_product | missing_license_field | dual_license_unclear_default | license_drift_after_upgrade | copyright_notice_missing | unknown_license_dep | sspl_or_bsl_in_oss_product | commercial_license_unbooked
package: <name@version>
license_spdx: "<SPDX expression>" # e.g. "AGPL-3.0-only", "MIT OR Apache-2.0", "NOASSERTION"
target_file: "<lockfile or manifest path>" # e.g. package-lock.json, Cargo.lock, requirements.txt
line: <line number if applicable, else null>
host_product_license: "<SPDX of the scanned project, if known>"
upgrade_from: "<previous version on drift findings, else null>"
upgrade_to: "<new version on drift findings, else null>"
suggested_fix: "<concrete replacement or remediation step>"
reference: "<URL — SPDX page, license text, FSF compat note>"
The integrator uses confidence to weight findings — a confidence: low inferred match (e.g. ScanCode text similarity below threshold) doesn't block phase advancement alone; SPDX-exact + lockfile-pinned confidence: high always blocks. kind: unknown_license_dep is always emitted but its block behavior depends on host-product policy (proprietary/SaaS = block; pure-OSS-research = informational).
unknown_license_dep findings unresolved.## Decisions Taken Under Ambiguity.When invoked as a critic by the Iron Loop integrator (see docs/REFINEMENT_LOOP.md), apply the warnings-are-critical rule:
severity: critical in the letter you write to CTO Chief.warn — there is no soft tier.## Decisions Taken Under Ambiguity section.The principle: a missed license obligation today is a takedown notice, an injunction, or an M&A red flag tomorrow. Code that ships green-with-warnings ships with known latent legal exposure.