Skip to main content

License Policies

Govern software composition license risk (prohibited / reciprocal / high‑risk categories) with diff‑aware policies that block net‑new problematic licenses while observing existing backlog.

Overview

License policies filter detected package licenses and apply actions per change category (new | changed | removed | existing). Use multiple focused policies (e.g., block GPL, observe LGPL) to progressively tighten compliance without stalling delivery. See Progressive Enforcement for staged rollout patterns. Canonical change semantics: Diff-Based Analysis.

Style & naming conventions (actions formatting info | warn | block, change category order) live in the Style & Naming Guide.

AI Governance Rationale

Fast AI‑assisted dependency additions can quietly introduce reciprocal or prohibited licenses. Diff focus ensures only new or changed risky licenses block while legacy debt is surfaced separately for planned remediation.

Policy Schema (Subset)

Full schema & operators: Policy System. Allowed record fields: Allowed Fields. Naming conventions: Style & Naming Guide.

{
"name": "block-gpl",
"actions": {"new": "block", "existing": "warn"},
"rules": [ {"field": "Name", "type": "contains", "value": "GPL"} ],
"outputs": [
{"format": "markdown", "template": "table", "destination": "git:pr", "fields": ["Name","Category","Severity","PkgName"], "changes": ["new"], "collapse": true},
{"format": "json", "destination": "file:/results/license-new.json", "changes": ["new"], "combined": true}
]
}

Notes:

  • rules is an array (OR logic). No nested objects keyed by field names.
  • Omit unused change actions to reduce noise (canonical display order: new, changed, removed, existing).
  • Multiple license policies can target distinct categories / severities.

Common Rule Patterns

Block Reciprocal / Copyleft

{"rules": [
{"field": "Category", "type": "eq", "value": "Reciprocal"},
{"field": "Category", "type": "eq", "value": "Forbidden"}
]}

Observe High Risk / Unknown

{"rules": [
{"field": "Severity", "type": "eq", "value": "HIGH"},
{"field": "Severity", "type": "eq", "value": "CRITICAL"},
{"field": "Severity", "type": "eq", "value": "UNKNOWN"}
]}

Narrow to Package Patterns

{"rules": [
{"field": "PkgName", "type": "hasPrefix", "value": "@internal/"},
{"field": "Name", "type": "contains", "value": "GPL"}
]}

Output Strategy

GoalPattern
PR clarityTable with Name, Category, Severity, PkgName for new/changed
Backlog visibilityIssue / file destination with only existing
AutomationJSON combined outputs for dashboards (see Combining & Grouping)
Minimal noiseExclude removed unless tracking cleanup KPI

Combined JSON semantics & grouping rules: Combining & Grouping (single concatenated array per destination).

Exceptions / Allowlisting

Prefer inequality to exclude a single accepted license while still blocking class:

"rules": [
{"field":"Name","type":"contains","value":"GPL"},
{"field":"Name","type":"ne","value":"GPL-2.0-with-classpath-exception"}
]

Document rationale via output comment or change description.

Common Mistakes & Fixes

ProblemCauseFix
Rules ignoredUsed legacy nested object (e.g. { "rules": { "severity": [...] }})Convert to array of rule objects
Everything marked newMissing main baseline (/main) or wrong CI_EVENTProvide /main mount + set CI_EVENT=pr
Relationship filter no effectdependency_tree disabledEnable global.dependency_tree=true
Mixed JSON + markdown combine errorCombined outputs mix formatsKeep JSON groups pure or separate destinations
Severity not displayedOmitted from fieldsAdd Severity to fields list

Best Practices

GoalRecommendation
Progressive rolloutStart by blocking clearly prohibited (GPL/AGPL) only; expand after confidence
Reduce review frictionShow only new + changed in PR; route existing to issue/file
Explain decisionsInclude Category + Severity in blocking outputs
Maintainable configMultiple narrow policies instead of one large rule list
AutomationProduce a combined JSON export for compliance dashboards

Next: manage dependency inventory with Package Policies.