Every modern application is built on a foundation of open source dependencies. Dozens, hundreds, sometimes thousands of packages can make up a unit of software being shipped to production. Each of these packages carries its own license terms. A single incompatible license deep in your dependency tree can create legal headaches, force costly rewrites, or even block a product release. 

What looks like a routine compliance task can quickly turn into what some have called “death by a thousand cuts”. Every weekend disappears into spreadsheets, combing through packages, trying to spot the legal landmines buried in the latest snapshot of a software supply chain. The danger doesn’t normally come from the obvious places but from the invisible depths of transitive dependencies—the “dependencies of dependencies”—where one unexpected license could derail an entire product.

As software supply chains grow more complex, manual license review becomes an intractable method. That’s where Grant comes in. We’ve rebuilt key parts of Syft to make SBOM license inspection for Golang packages smarter, while also updating Grant’s config to allow for stricter policies that are easier to use.

90% improvements on license inspection for Golang modules

At its surface, the package detection problem for Golang seems straight forward. Give me the go.mod, enumerate all the entries, build the package list…done!. In actuality, it’s a lot more complicated if you want the licenses.  When we tested Grant’s new Golang module integration on the MinIO Golang client (a popular S3-compatible storage solution), the new results for licenses detection were very promising:

  • Before: 295 packages with undetected licenses (go.mod approach)
  • After: Only 29 missing licenses – a 90% improvement (golang source inspection)

Each undetected license carries potential harm such as:

  • A competitor claiming code ownership
  • A consumer forced to open-source proprietary features
  • Personal liability for engineering leaders

For a company preparing for acquisition or IPO, having 295 unknown licenses in their SBOM could delay due diligence. With Grant’s improvements, that same audit/inspection can now isolate the problem packages and figure out what licenses are missing.

Stronger Policies for Safer (and Faster) Compliance

Detect Unlicensed Packages

“No license” cases are now flagged by default. This closes gaps where unlicensed code could slip through and gives organizations clearer control over compliance risks. If it’s ok that a package has no licenses, it’s quick to add it to the exceptions list for a green CI.

Understanding License Families

Grant now categorizes licenses into risk-based families, making it easier to create policies that match your organization’s risk tolerance. We create the following classification to help teams quickly identify which dependencies need legal review versus which can be auto-approved :

Strong Copyleft (High Risk): GPL, AGPL, SSPL

  • Requires derivative works to use the same license
  • Can “infect” proprietary code with open source obligations
  • Example policy: deny: ["GPL-*", "AGPL-*"]

Weak Copyleft (Medium Risk): LGPL, MPL, EPL

  • More permissive than strong copyleft
  • Allows linking without license propagation
  • Example policy: allow: ["LGPL-*"] # but review usage context

Permissive (Low Risk): MIT, Apache-2.0, BSD

  • Minimal restrictions on reuse
  • Generally safe for commercial products
  • Example policy: allow: ["MIT", "Apache-2.0", "BSD-*"]

Easier, Cleaner Configuration

The old .grant.yaml was powerful but too verbose and hard to manage. Users told us it was unwieldy, repetitive, and full of boilerplate. We rebuilt the configuration system with sensible defaults and simpler patterns.

👉 The result: policies that used to take ~50 lines can now be expressed in ~15.

Before: Verbose & Rule-Heavy

#.grant.yaml

rules:
  - pattern: "BSD-*"
    name: "bsd-allow"
    mode: "allow"
    reason: "BSD is compatible with our project"
    exceptions:
      - my-package # denied for this package
  - pattern: "MIT"
    name: "mit-allow"
    mode: "allow"
    reason: "MIT is compatible with our project"
  - pattern: "*"
    name: "default-deny-all"
    mode: "deny"
    reason: "All licenses need to be explicitly allowed"

After: Streamlined & User-Friendly

# Default: DENY all licenses (including no-license packages)

require-license: true
require-known-license: false
allow:
  - MIT
  - MIT-*
  - Apache-2.0
  - Apache-2.0-*
  - BSD-2-Clause
  - BSD-3-Clause
  - BSD-3-Clause-Clear
  - ISC
  - 0BSD
  - Unlicense
  - CC0-1.0
ignore-packages:
  - github.com/mycompany/*  # Our own Go modules

The new format is:

  • Shorter – no more repetitive rule definitions
  • Clearer – defaults make intent obvious (deny all unless explicitly allowed)
  • More flexible – glob patterns and ignore-packages handle common exceptions

CI/CD Upgrades with --dry-run and --allow-failure

Not every scan should block your build. Based on feedback from teams running Grant in CI/CD, we’ve added two new flags for more control:

  • --dry-run — preview scan results without enforcing policy
  • --allow-failure — let pipelines continue even if violations are found

These options make it easier to adopt Grant incrementally: start in “report-only” mode, then turn on strict enforcement when it fits your needs.

Smarter Package Discovery

Golang Toolchain Integration

The latest update builds Golang package licenses by using golang.org/x/tools/go/packages to build a full import graph, detect the main module, and pull licenses from the Golang module cache. If the toolchain isn’t available, we gracefully fall back to go.mod. This approach catches transitive dependencies that other tools might miss and handles complex scenarios like replace directives and local modules.

Under the Hood: How Go Module Discovery Works

Grant’s new Golang integration enhances how we discover licenses for dependencies:

  1. Build-time analysis: We hook into golang.org/x/tools/go/packages to construct the actual import graph—not just what’s declared in go.mod, but what’s actually used.
  2. Module cache mining: Instead of crawling vendor directories, we pull licenses directly from Go’s module cache, ensuring we get the canonical license files.
  3. Graceful degradation: No Go toolchain? No problem. Grant still constructs the SBOM and grabs what licenses it can in the current directory’s context. It just won’t be as powerful as it is when combined with the go tool chain knowledge.

Expanded Package Type Support

Grant now leverages Syft’s enhanced cataloging capabilities to detect licenses across more package ecosystems:

  • Cataloging snap packages with transitive package support and their included licenses
  • Conda ecosystem support when license location available
  • Better license detection with over 1400 URL-to-license mappings

Better Data, Faster Runs

SPDX Upgrade

Added ~1,400 new URL-to-license mappings, improved lookups, and upgraded the SPDX license list from 3.22 → 3.27. Deprecated URLs now resolve cleanly to replacements.

Focused Crawling

License detection is now limited to common filenames (LICENSE, COPYING, NOTICE, etc.), avoiding slow scans through irrelevant directories. Users even have the ability to turn off Grant’s scanning feature with --disable-file-search if they trust the content of their SBOM.

In prior releases large directories of files would give grant issues since it would try to read the contents of every file to look for license evidence:

$ npx create-react-app . --template minimal

$ grant check .
~/d/test (main)> grant check .
 ⠹ Checking licenses  ━━━━━━━━━━━━━━━━━━━━

The above would balloon a workstation’s memory usage and take about 3-4 cups of coffee before finishing its task.

With this change we see this process execute in a shorter amount of time.

$ time grant check dir:.
                                                                                                                          
Target: dir:. (directory)
Status: ✗ NON-COMPLIANT

Summary:
  Packages: 1289 total, 1289 denied, 43 unlicensed
  Licenses: 15 unique, 15 denied

Denied Packages (1256):
...........................
________________________________________________________
Executed in    2.87 secs    fish           external
   usr time    2.22 secs    0.21 millis    2.22 secs
   sys time    1.26 secs    1.22 millis    1.26 secs

The secret? Focused crawling that skips irrelevant files and parallel license classification. The new --disable-file-search flag can also reduce scan times by another 40% when you only need licenses that are found in the SBOM and associated packages.

TLDR; Top 5 Grant Improvements

With this update, Grant is:

  1. Stricter where it counts, by detecting unlicensed packages
  2. Simpler to configure with defaults that reflect real-world needs
  3. Safer to adopt in CI/CD with dry-run and allow-failure modes
  4. Smarter for Go projects and other ecosystems with toolchain-backed cataloging
  5. Faster across large repositories with reduced crawl time

Together these improvements make Grant a sharper, safer tool for software license inspection and evaluation.

And This Is What’s Next

This release sets the foundation for what’s coming next:

  • Configuration templates: Pre-built license configurations for common scenarios
  • License remediation hints: Automated suggestions for replacing problematic dependencies
  • MCP integration: Real-time license feedback from your favorite AI agent
  • SBOM enrichment: Adding edited/discovered licenses back into your SBOMs

Try it yourself

$ grant check dir:.

Join us on September 18 for our live webinar where we demo the latest functionality.

Packages, Policies and Performance: What's New in Grant Webinar

Questions? Issues? Join the discussion at anchore.com/discourse or reach out and file an issue!


Grant is part of Anchore’s open source toolkit for software supply chain security. Learn more about our complete SBOM and vulnerability management solutions at anchore.com.