Back to blog
|Rorix Team

License Policy Without Blocking Every Pull Request

policylicensescompliance
Software packages passing through a policy gate with one package isolated

License compliance tends to fail in one of two ways. Either nobody looks until a customer or acquisition review creates an emergency, or a blunt blocklist starts failing builds without enough context to resolve the failures.

Neither creates a dependable control.

A practical license policy tells developers what is acceptable, identifies the dependencies that need review, and gives ambiguous cases a clear owner. It should make routine decisions automatic while keeping legal judgment where it belongs.

Inventory Before You Enforce

Start by scanning the current dependency graph and grouping results into four buckets:

  1. Approved — licenses already compatible with the organization's distribution and use model.
  2. Prohibited — licenses the organization has decided not to accept for this type of software.
  3. Review required — licenses whose obligations depend on linking, modification, distribution, or another product-specific fact.
  4. Unknown — missing, custom, conflicting, or unrecognized license metadata.

The fourth bucket deserves special attention. Unknown does not mean prohibited, but it also does not mean safe. It means automation lacks enough evidence to decide.

Write Policy Around Your Distribution Model

There is no responsible universal allowlist for every .NET repository. An internal service, an on-premises commercial product, a mobile application, and a reusable SDK distribute software differently.

Capture at least:

  • whether the software is distributed outside the organization;
  • whether customers receive binaries, source, containers, or packages;
  • whether dependencies are modified;
  • whether the repository produces a library other applications will link;
  • who can approve an exception.

Two repositories in the same organization may need different policies. Consistency means applying the same decision rules to the same context, not forcing every product into one list.

Use SPDX Identifiers in Configuration

License names have many informal spellings. Policy becomes more reliable when configuration uses normalized SPDX identifiers.

A Rorix policy can block licenses the organization has already classified as unacceptable:

version: 1
policies:
  block-licenses:
    - GPL-2.0
    - GPL-3.0
    - AGPL-3.0

The example is a configuration pattern, not a legal recommendation. Your list should come from counsel or the people accountable for open-source governance.

See the policy reference for the full .rorix.yml schema.

Roll Out the Gate in Stages

If an existing repository already contains unresolved license findings, turning on a strict gate immediately makes unrelated pull requests fail. That teaches developers that the control is arbitrary.

Use a staged rollout:

Stage 1: Observe

Create the inventory, normalize known license data, and find packages with missing metadata. Do not block builds yet.

Stage 2: Triage the Baseline

Approve, replace, or document existing dependencies. Give each exception an owner and a review date.

Stage 3: Prevent New Violations

Gate newly introduced packages and changed versions against the agreed policy. Keep the existing baseline visible without making every PR responsible for all historical work.

Stage 4: Reduce Exceptions

Review expiring exceptions and replace dependencies where the long-term cost of the exception exceeds the cost of migration.

Give Developers a Resolution Path

A failed check should answer three questions:

  • Which direct or transitive dependency triggered the rule?
  • What license evidence was used?
  • What should the developer do next?

The next step might be selecting an alternative package, upgrading to a version with corrected metadata, providing a missing license file, or requesting review. A generic “license denied” message turns a policy into a queue for the legal team.

Preserve the Evidence

License metadata can change between package versions, and packages with similar names can carry different terms. Store the package identity, resolved version, detected expression, source of the metadata, decision, and approver.

Include license information in the release SBOM so the evidence travels with the software inventory. That creates a defensible record of what was evaluated, not merely a snapshot of today's dashboard.

The goal is not to make engineers interpret licenses. It is to give them fast, repeatable answers for routine dependencies and an obvious escalation path for everything else.