Hamburger Cross Icon
Has Licenses
+
License Origins Collector

Has Licenses + License Origins Collector

Guardrail Collector Stable Security And Compliance

Enforce Has Licenses using data collected by License Origins Collector. Automatically check security and compliance standards on every PR.

Guardrail: Verifies that SBOM components have license information populated. Fails if license coverage is below the configured threshold.
Data Source: Scan dependency license files for geographic origin signals — country names in copyright lines, governing law clauses, and author addresses. Results are cached in Postgres for fast repeat scans across projects.

How License Origins Collector Powers This Guardrail

The License Origins Collector gathers metadata from your security systems. This data flows into Lunar's Component JSON, where the Has Licenses guardrail evaluates it against your standards.

When enabled, this check runs automatically on every PR and in AI coding workflows, providing real-time enforcement with actionable feedback.

1
License Origins Collector Gathers Data Collector
Extracts metadata from code, configs, and tool outputs
2
{ } Component JSON
Data centralized in structured format for evaluation
3
Has Licenses Checks Guardrail
Pass/fail result with actionable feedback in PRs

Quick Start Configuration

Add both the collector and policy to your lunar-config.yml to enable this guardrail.

📄 lunar-config.yml
# Step 1: Enable the License Origins Collector
collectors:
  - uses: github://earthly/lunar-lib/collectors/license-origins@v1.0.0
    # with: ...

# Step 2: Enable the SBOM Guardrails
policies:
  - uses: github://earthly/lunar-lib/policies/sbom@v1.0.0
    include: [has-licenses]
    # with: ...

What License Origins Collector Collects

This collector gathers the following data that the Has Licenses guardrail evaluates.

Collector code

scan

Fetches dependencies (Rust, Go, Node.js, Python) and generates an internal SBOM to enumerate them, then scans each dependency's license files for country name mentions. Scan results are cached in a configurable Postgres database keyed by PURL@version. Writes origin results to .sbom.license_origins in Component JSON. Use alongside the syft collector for full SBOM + origin coverage.

Example Data Flow

Here's an example of the data that License Origins Collector writes to the Component JSON, which Has Licenses then evaluates.

{ } component.json From License Origins Collector
{
  "sbom": {
    "license_origins": {
      "source": {
        "tool": "license-origins",
        "integration": "code",
        "version": "0.1.0"
      },
      "packages": [
        {
          "purl": "pkg:npm/scheduler-lib@2.1.0",
          "name": "scheduler-lib",
          "license_file": "node_modules/scheduler-lib/LICENSE",
          "countries": ["Germany"],
          "excerpts": ["Copyright 2024 Hans Mueller, Berlin, Germany"],
          "cached": false
        }
      ],
      "summary": {
        "files_scanned": 185,
        "packages_with_mentions": 1,
        "countries_found": ["Germany"],
        "cache_hits": 140,
        "cache_misses": 45
      }
    }
  }
}

Configuration Options

License Origins Collector Inputs

Input Required Default Description
cache_enabled Optional true Enable Postgres caching of scan results (set to "false" to scan fresh every time)
cache_db_host Optional postgres Postgres host
cache_db_port Optional 5432 Postgres port
cache_db_name Optional hub Postgres database name
cache_db_user Optional lunar Postgres user (needs CREATE TABLE, INSERT, SELECT)

SBOM Guardrails Inputs

Input Required Default Description
disallowed_licenses Required Regex patterns of disallowed licenses. Accepts a comma-separated string (e.g. "GPL.*,AGPL.*") or a JSON array (e.g. '["GPL.*", "AGPL.*"]').
min_license_coverage Optional 50 Minimum percentage of components that must have license info (0-100)
min_components Optional 1 Minimum number of components the SBOM must contain
allowed_formats Required Comma-separated list of allowed SBOM formats (e.g. "cyclonedx,spdx"). Empty means any.
blocked_countries Required Comma-separated list of blocked countries for license origin checks (e.g. "Russia,China,Iran,North Korea")
disallowed_packages Required Regex patterns for disallowed packages, matched against PURL, name, and group. Accepts a comma-separated string or a JSON array (e.g. '["ru\\.yandex\\..*", "com\\.alibaba\\..*"]').

Ready to Automate Your Standards?

See how Lunar can turn your engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 100+ built-in guardrails.

Works with any process
check Infrastructure conventions
check Post-mortem action items
check Security & compliance policies
check Testing & quality requirements
Automate Now
Turn any process doc into guardrails
Book a Demo