Operating · Lesson 21 — AGPL vs Apache: the license decision that ships or sinks your product
O21Operating
Operating · Lesson 21● live

AGPL vs Apache — the license decision that ships or sinks your product

Permissive vs strong-copyleft, the SaaS loophole, and why a single library can turn your whole codebase open.

9 min read · 15 min applyprereq: Operating 04 (hooks)

Why licenses matter — even when nobody is looking

Open-source licensing is the most boring part of a startup, right up until it’s the most expensive part. I’ve watched teams ship a feature, take diligence calls from acquirers six months later, and learn at the table that a single library in their bundle obligated them to open-source the whole codebase. The deal terms shift in that moment. Sometimes the deal evaporates.

The other failure mode is quieter: you ship a clean product, no acquirer in the picture, and a copyleft compliance complaint arrives by email. Pulling the library out is a multi-week rewrite. Publishing your source — the alternative the license demands — was never something you agreed to. The team did, the moment one developer ran npm install on a dependency nobody had vetted.

License is a structural property of your shipping product. It travels with every dependency, every fine-tuned model, every static link. The cost of getting it wrong is paid in rewrites and lawyers. The cost of getting it right is one license check at the right moment in your workflow. This lesson is about installing that check.

The story

The first time I really took licensing seriously was when I almost picked the wrong library for a shipping product. I was deep in evaluation mode — comparing two open-source options that did roughly the same job. One had more stars, better docs, a more active community. I was 15 minutes from running npm install. I checked the license at the bottom of the README out of habit.

AGPL-3.0.

Reading the actual license text took 10 minutes. The summary: I could absolutely use this library. I could even modify it. But the moment a user interacted with my product over a network — which, by definition, they would — I owed the world my modified source code. Not just the library. The modifications. Which, for a real integration, meant a meaningful chunk of my product’s internals.

The other library was Apache 2.0. Same job, slightly less polish, explicit patent grant. I picked the Apache one and never thought about it again. That ten-minute license read saved a future me a multi-week rewrite, or worse, a forced open-source disclosure I had not agreed to make.

The story isn’t dramatic. That’s the point. The decision was small at the time and irreversible by the time it mattered. Most licensing damage is exactly this shape: a missed check at the cheap moment that becomes a structural problem at the expensive moment. The fix is to make the check unavoidable.

Two families, one network clause

Every open-source license falls into one of a few families. You don’t need to memorize the long tail — you need to know the two families that actually decide whether you ship.

Permissive: MIT, Apache 2.0, BSD, ISC

You can use, modify, and distribute the code inside a closed-source commercial product. You generally have to keep the copyright notice and (for Apache) ship a NOTICE file. That’s the entire compliance cost.

Apache 2.0 carries one feature MIT does not: an explicit patent grant.Every contributor to an Apache-licensed project grants you a patent license for their contributions. If they later try to sue you over a patent that covers their own contributed code, they lose the patent license automatically. For anything you’re going to depend on long-term, Apache 2.0 is the safer permissive choice — the patent grant is real protection.

Strong copyleft: GPL, AGPL

Viral. If you incorporate a GPL library into your product, your entire product is now GPL — and you must publish your full source code under GPL terms.One library, one link, your whole codebase opens. That’s not a rhetorical exaggeration; that’s the actual mechanism in the license.

Standard GPL has a loophole companies used for years: the obligation triggers on distribution. If you never shipped binaries — if you only hosted the code on your servers and let users interact with it over a network — you didn’t trigger the disclosure clause. SaaS companies built whole stacks on top of GPL code this way.

The AGPL (Affero GPL) was written specifically to close that loophole. Under the AGPL, network interaction counts as distribution. If you modify AGPL code and let users hit it over HTTP, you must publish the modified source. Hosting is the trigger. There is no SaaS exemption.

This is why Google bans AGPL outright internally. The rule is not ambiguous — it’s very clear — and the compliance cost (publish everything you touched) is structurally incompatible with running closed-source SaaS. Most commercial AI shops follow the same rule.

Restrictive: BUSL, SSPL, custom commercial

A newer family. Not technically open-source under OSI definitions, but you’ll see them on real projects. HashiCorp moved Terraform from MPL 2.0 to the Business Source License (BUSL) to restrict competing commercial use. The community forked the last MPL version into OpenTofu within weeks. OpenObserve switched from Apache 2.0 to AGPL specifically to stop hyperscalers from reselling their software as a managed service.

Both moves are legal and increasingly common. The implication for you: a library you depended on under permissive terms can change license under you. If the upstream relicenses to AGPL or BUSL, your old version is still under the old terms — but every update from that point forward is under the new license. The fork ecosystem (OpenTofu being the canonical example) exists precisely for teams that want to keep shipping under the old permissive terms.

The model layer is the same problem, harder

For AI shops, the license trap that bites hardest is at the model layer. Fine-tuned weights are a derivative work of the base model and inherit the upstream license. If the base model is Apache 2.0, the fine-tune is essentially Apache 2.0 too — ship freely. If the base is non-commercial, the fine-tune is non-commercial too — you cannot ship it in a paid product without violating the license. If the base is AGPL-style, the network clause comes with you.

Picking the base model is therefore a license decision, not just a quality decision. The teams that get this right pick a permissive open-weight base before training. The teams that get it wrong only learn at exit diligence that their flagship feature is encumbered.

Three ways teams sink

The most common license failures I see. None of them are about understanding licensing — they’re about not running the check at the right moment. Hover any card to see the diagnosis.

01

The transitive copyleft surprise

claim looks likeTeam picks a permissive library. Three layers down, one of its dependencies is GPL or AGPL. Nobody checked the transitive tree.
what’s missingThe viral terms travel through the dependency graph. Your code statically links against the GPL transitive — you now owe source. The package.json that looked clean was lying about what was actually in the bundle.
the moveRun a license-tree scan, not a top-level scan. Tools like `license-checker`, `pip-licenses`, or `cargo-deny` walk the full transitive graph. Make the scan a CI gate before any new dependency lands.
02

The base-model trap

claim looks likeAI shop fine-tunes an open-weight model. The fine-tune is great. Ship-day, legal asks: what's the upstream license on the base?
what’s missingFine-tuned weights are derivative works. They inherit the upstream model's license — including non-commercial clauses, ShareAlike requirements, or AGPL-style network terms. The fine-tuning effort did not strip the license; it carried it forward.
the moveCheck the base-model license BEFORE the fine-tune run, not after. Apache 2.0 base models (and similarly permissive open-weights) keep you free to ship. AGPL or non-commercial bases lock the derivative in. Pick the license at the model selection step.
03

The network-clause blind spot

claim looks likeTeam uses an AGPL library inside their SaaS backend. "We're not distributing it — we're just running it on our servers."
what’s missingThe AGPL was written specifically to close that loophole. If users interact with your modified AGPL code over a network, you must publish your modifications. The standard GPL distinction (distribute vs run) does not apply.
the moveTreat AGPL as a hard no for anything in a network-served product unless you are intentionally building open-source-by-default. The compliance cost of "AGPL but private" is publishing all your modifications. That's usually not a deal you wanted.

The pattern across all three: the check happens too late or not at all. The fix is the same — move the license check upstream, into dependency selection and model selection, and gate it mechanically so future-you cannot skip it.

The license-check prompt

The diagnostic that should fire on every new dependency, every base-model selection, and (at least once) on your existing dependency tree.

The license-check prompt
Walk every dependency in this project — top-level AND transitive.
For each, report:
- Name and version
- License (SPDX identifier)
- Family: permissive (MIT/Apache/BSD), weak copyleft (LGPL/MPL), strong
  copyleft (GPL/AGPL), or restrictive (SSPL/BUSL/non-commercial)
- Risk for a closed-source commercial product served over a network

Sort by risk. Flag anything strong-copyleft or restrictive at the top.

For every flagged item, answer:
- Is this dependency actually linked into the shipping product, or
  only used in dev/build/test? (Dev-only is usually safe.)
- Is there a permissive equivalent we could swap in?
- If we keep it, what compliance steps are required (publish source,
  attribution, network-accessible source link)?

Same prompt applies to model selection: for any open-weight base
model in the project, run the same check on the model card license.

Forces every dependency and model to declare its license family before it enters the shipping path.

What this catches:

  • Transitive copyleft. The clean-looking permissive parent that pulls GPL three layers down.
  • Relicensing surprises. A dependency that was Apache last year and is BUSL now.
  • Non-commercial base models. The fine-tuning candidate that locks your derivative.
  • Restrictive custom licenses. The library with a friendly-looking license file that turns out to forbid your exact use case.

Run it once on your existing project as a baseline. Then add a CI gate so it runs on every new dependency before merge. The cost is one initial audit and a config file. The payoff is that license is a property you maintain on purpose instead of discover by accident.

Annotated transcript

A real walkthrough: pick between two libraries, understand why AGPL disqualifies one of them, learn how the network clause works, then audit the transitive tree and the base-model layer. Click any pinned annotation for the “why this turn matters” commentary.

Picking the right license, in five turns

Five operator turns, five agent turns. Result: a two-question decision rule plus the model-layer audit.

  1. operator

    I'm picking between two libraries that do roughly the same thing. One is Apache 2.0. The other is AGPL. The AGPL one has better docs and more stars. Does it matter which I pick?

  2. agent

    Yes — and the answer flips depending on what you're building. Two questions decide it:

    1. Is this going into a product you ship as closed-source (commercial SaaS, native app, embedded device)?
    2. Will users interact with this code over a network — even indirectly, through your backend?

    If yes to (1), AGPL is almost certainly disqualifying. The AGPL is strong copyleft — it's viral. Linking against it means your code inherits the AGPL terms. And the network clause means "I'm not distributing, I'm just running it on my server" does not save you.

    Apache 2.0 has none of that. It's permissive — you can use, modify, and ship in closed-source products. It even carries an explicit patent grant, which protects you from later patent claims by the contributors.

  3. operator

    What if I just keep my modifications private and don't tell anyone? It's running on my server, nobody can see the source.

  4. agent

    The AGPL was written specifically against that scenario. The standard GPL only triggers compliance when you distribute the software — ship binaries, send installers, etc. SaaS companies used to host GPL code without triggering source-disclosure because they never "distributed" anything.

    The AGPL closes that loophole. Section 13 says: if you modify the software and let users interact with it over a network, you must publish the modified source. Hosting is the trigger. Nobody has to be a customer or have a login — "users" includes anyone who can ping the service.

    This is why Google bans AGPL internally outright. Not because the rules are unclear — because they're very clear, and the cost of compliance (publishing every modification) is incompatible with running closed-source products at scale.

  5. operator

    OK — so I'll just use the Apache one. But the AGPL library has a transitive dependency I want too. Can I use that one?

  6. agent

    Check the actual license of the transitive dependency, not the parent. AGPL is not transitive across separate works — if the dependency itself is MIT or Apache, you can use the dependency directly without inheriting the AGPL parent's terms.

    But the reverse trap is real: a permissive parent library that pulls in a GPL transitive will quietly drag GPL terms through. The viral effect runs from copyleft outward. So the rule:

    - Permissive parent + permissive transitives → safe.
    - Permissive parent + copyleft transitive → the copyleft applies to your linked product.
    - Copyleft parent + anything → copyleft applies.

    Run a license-tree scan. license-checker for npm. pip-licenses for Python. cargo-deny for Rust. Walk the full transitive graph and surface every license. Anything red (GPL, AGPL, SSPL, BUSL) gets a manual decision.

  7. operator

    What about open-weight models? I'm thinking about fine-tuning one for a product feature.

  8. agent

    Model layer is where AI shops get hit the hardest. The fine-tuned weights are a derivative work of the base model. They inherit the base model's license — including any non-commercial clauses, attribution requirements, or ShareAlike terms.

    Real pattern: a team fine-tunes on a base model with non-commercial restrictions, ships the fine-tune in a product, and only learns at exit diligence that the entire feature is non-commercial. The fix at that point is: rip the model out, retrain on a permissive base, validate the new fine-tune meets quality bar. Weeks of work.

    The rule: pick the base model's license deliberately, at the model-selection step. Apache 2.0 or similarly permissive base = you can ship the derivative in a closed-source product. Non-commercial or AGPL-style base = the derivative is encumbered the same way. Treat model selection as a license decision, not just a quality decision.

The decision rule — paste this into your CLAUDE.md

The whole lesson collapses to one checklist. Use it on every dependency, every base model, every fork-vs-stay decision.

# License decision rule

Before any new dependency or base model enters the shipping path:

1. Identify the license. Read the actual LICENSE file, not memory.
2. Classify the family:
     - Permissive (MIT, Apache-2.0, BSD, ISC) → safe to ship.
     - Weak copyleft (LGPL, MPL) → safe in most cases; dynamic
       linking and isolated modifications usually OK. Read terms.
     - Strong copyleft (GPL, AGPL) → assume disqualifying for
       any closed-source product. AGPL is disqualifying even for
       SaaS — the network clause closes the hosting loophole.
     - Restrictive (BUSL, SSPL, non-commercial, custom) →
       case-by-case. Read the actual terms.
3. If the license is permissive, prefer Apache 2.0 over MIT for
   anything load-bearing. The explicit patent grant is real
   protection.
4. Walk the transitive tree. Copyleft underneath a permissive
   parent still applies to your linked product.
5. For AI base models: same check, applied at model selection.
   Fine-tunes inherit the base license. Pick the base
   deliberately.
6. Block the disallowed licenses in CI. Don't rely on memory
   or vigilance. Mechanical enforcement.

When in doubt: pick the Apache 2.0 alternative and move on.
The cost of the safer choice is small. The cost of the wrong
choice is a rewrite or a forced disclosure.

The rule isn’t complicated. The discipline is in actually running it at the cheap moment — dependency selection, model selection — instead of discovering the answer at the expensive moment.

Prompt kit

Three prompts for auditing the tree, reviewing new dependencies, and gating model selection. Drop them into your CLAUDE.md or a personal snippets file so future sessions fire them automatically.

The license-check prompt
Walk every dependency in this project — top-level AND transitive.
For each, report:
- Name and version
- License (SPDX identifier)
- Family: permissive (MIT/Apache/BSD), weak copyleft (LGPL/MPL), strong
  copyleft (GPL/AGPL), or restrictive (SSPL/BUSL/non-commercial)
- Risk for a closed-source commercial product served over a network

Sort by risk. Flag anything strong-copyleft or restrictive at the top.

For every flagged item, answer:
- Is this dependency actually linked into the shipping product, or
  only used in dev/build/test? (Dev-only is usually safe.)
- Is there a permissive equivalent we could swap in?
- If we keep it, what compliance steps are required (publish source,
  attribution, network-accessible source link)?

Same prompt applies to model selection: for any open-weight base
model in the project, run the same check on the model card license.
Pre-merge dependency review
I want to add this new dependency: <package@version>.
Before I run the install:

1. What's the license? Confirm against the package metadata, not memory.
2. What's the family — permissive, weak copyleft, strong copyleft,
   or restrictive?
3. Does it have a patent grant? (Apache 2.0 yes; MIT no; GPL family
   has its own structure.)
4. Walk one level deep into its transitive dependencies. Any
   copyleft underneath the permissive top?
5. If we're shipping this in a closed-source network product, is
   this safe to merge?

Output: a one-line verdict (safe / safe-with-conditions / blocked)
plus the reasoning. If safe-with-conditions, list the conditions
(attribution, NOTICE file, link to source, etc.).
Base-model license audit before fine-tuning
I'm about to fine-tune <base model name> for <use case>.
Before any training run:

1. What's the upstream license on the base model weights?
   Read the model card, not training data.
2. Is it permissive (Apache 2.0, MIT-style open weights),
   restricted commercial use, non-commercial only, or copyleft?
3. What does the license say specifically about derivative
   works (fine-tunes, LoRA adapters, distilled models)?
4. Does the license restrict redistribution of the fine-tuned
   weights? Restrict commercial use of model outputs?
5. If we ship a product feature built on this fine-tune, what
   compliance steps are required?

Output: verdict plus the specific clauses we'd need to comply
with. If non-commercial or AGPL-style, recommend a permissive
alternative at similar quality before any compute is spent.

Apply this — audit your tree today

15-minute exercise. The license-tree scan takes minutes. Reading the output and deciding what to do takes longer. The CI gate is a one-time setup that pays back forever.

Install the license check

Each step is small. The whole sequence is the difference between hoping and knowing.

0/5
  1. 01Run a license-tree scan on your current project. Not just top-level — walk the transitive graph.npm: `npx license-checker --production --json`. Python: `pip-licenses --format=json`. Rust: `cargo deny check licenses`. Read the output, not just the exit code.
  2. 02Sort the report by license family. Flag every strong-copyleft (GPL, AGPL, SSPL) and restrictive (BUSL) entry.For each flagged item, decide: keep with compliance, swap for a permissive equivalent, or remove. Document the decision somewhere committed.
  3. 03Add a license-check step to your CI pipeline. Block new dependencies with disallowed licenses before merge.Most license-check tools have a config file (`.licensee.yml`, `deny.toml`, etc.) where you allowlist acceptable SPDX identifiers. Permissive: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC. Block by default: AGPL-3.0, SSPL, BUSL-1.1.
  4. 04If you ship AI features, audit your base-model license too. Open the model card. Read the actual license text — don't trust summaries.Apache 2.0 open-weights base = safe to ship derivatives in closed products. Non-commercial base = the derivative is non-commercial. Custom RAIL or community licenses = read the fine print on commercial use and redistribution.
  5. 05Write the rule into your CLAUDE.md so future sessions enforce it.Example: "Before adding any new dependency or base model: confirm license, confirm patent grant if linked into product, refuse AGPL/SSPL/BUSL for any code served over a network."
Operating tier · what's next

After this lesson