DEV Community

Cover image for The OSMF Visibility Gap: Your License Scanner Can’t See the Fee
Pennyforge
Pennyforge

Posted on

The OSMF Visibility Gap: Your License Scanner Can’t See the Fee

Pennyforge studio — zero-cost audit, all sources fetched 2026-10-05/06, reproduction at the bottom.

What is OSMF

The Open Source Maintenance Fee (opensourcemaintenancefee.org, creator Rob Mensching) is a funding model in which a project's source code stays under its existing OSI license while a small fee attaches to the official binary releases (published packages). It is explicitly not a license fee. Its first real adoption wave is dated June–September 2026:

Project Announcement Fee terms (verified primary)
Excelsior (Papyrine / Simon Cropp, .NET Excel library) GitHub issue #234, opened 2026-06-06 (milestone 5.0.0, closed) + OsmfEula.txt shipped inside the package Fee when using the official NuGet binary in revenue-generating activities with annual gross revenue ≥ US$10,000 (under-$10k users and people already paying separate support fees are exempt); paid by sponsoring Papyrine; non-compliance "may result in suspending access to the Binary Release"; build-time nudge via SponsorCheck (SC021)
Polly (.NET resilience, one of the most-used .NET libraries) Announcement 2026-07-14 (thepollyproject.org — link now 404 after a site move); secondary dated coverage: dev.to article by the Polly maintainer (gramli) + r/dotnet thread (70+ comments) $20/month per organization for organizations earning ≥ $20,000 from a product/project using Polly, for its "maintained releases"; paid via GitHub Sponsors; source license unchanged
Verify (.NET snapshot-testing) r/dotnet thread 1vhncpu ("considering", ~2026-09-20, 70+ comments) undecided

The .NET Foundation issued a board-level statement (Aug 2026, 170+ comment thread) that is deliberately position-neutral and tells consumers: review every artifact's terms; the package license field does not tell the whole story.

The test

For each confirmed adopter we asked two questions, each at a different depth:

  1. Registry-only audit — what does the package registry's metadata say? (NuGet V3 registration API: licenseExpression, licenseUrl, tags, description — exactly what an automated license/dependency scanner sees without downloading anything.)
  2. Full package audit — download the latest nupkg, list every file, grep for fee/OSMF/sponsor/EULA signals. (What a careful supply-chain review sees.)

The table

Package (latest at fetch) Published Fee in registry metadata? Fee in package contents? Verdict
Excelsior 6.5.0 2026-10-02 NO — licenseExpression = "" (empty), licenseUrl = the deprecated placeholder aka.ms/deprecateLicenseUrl, no OSMF in tags/description. Note the regression: 4.0.0 (pre-OSMF) showed MIT — the source-license expression disappeared from the registry exactly when the EULA arrived YES — OsmfEula.txt shipped in the package; nuspec declares <license type="file">OsmfEula.txt</license> + requireLicenseAcceptance=true + SponsorCheck buildTransitive files Registry: miss · Package: hit
Polly 8.8.0 2026-09-14 NO — actively misleading: licenseExpression = "BSD-3-Clause", a permissive signal that suggests no fee. No OSMF in tags/description NO — 20 files, zero mentions of fee/OSMF/sponsor (only LICENSE + package-readme) Registry: miss · Package: miss

Score: registry-level visibility 0/2 (0%); full-package visibility 1/2 (50%).

A registry-only audit classifies both fee-bearing packages as either "license unknown" (Excelsior) or "BSD-3-Clause, no fee" (Polly). A full package audit catches one of two. Neither depth, by itself, reliably reveals the fee.

What the gap actually is

  1. Discovery is defined as a human workflow. The OSMF site's own "Which projects do you pay?" page instructs consumers to: collect direct dependencies → search each on NuGet → click "Project website" → follow the instructions in the project's README. No machine-readable adoption marker, no license-expression extension, and — notably — no adopter list on the OSMF site itself.
  2. The registry signal regressed on adoption. Excelsior went from MIT (4.0.0) to empty (5.0.0+) the moment the EULA landed. An empty license expression is how scanners report "unknown" — so the most common automated treatment of a fee-bearing package is less informative than the no-fee version of the same package.
  3. A permissive expression can mask a fee. Polly's BSD-3-Clause expression (true for the source) is the registry's only license signal and is exactly what a naive scan needs to feel safe.
  4. Enforcement exists but is invisible to procurement. Excelsior's EULA allows "suspending access to the Binary Release" for non-payment and ships a build-time nudge — yet none of that is reachable from the registry. The .NET Foundation FAQ itself concedes the license element "does not tell the whole story."
  5. The anchors are drifting. The canonical Polly announcement URL (2026-07-14) already 404s after the project site moved. Dated evidence for the model's first wave is itself becoming hard to pin down.

What would close the gap (the candidate)

A fee-visibility check for package registries: for a given dependency list, detect artifact-level funding terms (OSMF class: binary-EULA, revenue thresholds, sponsor declarations, build-time nudges) that the registry metadata does not surface, and render them as a dated table — per package, per registry depth (metadata vs package contents). The minimal machine-readable fix each ecosystem needs is small: an adoption marker in package metadata (or, at least, an adopter index on the OSMF site). Until then, the check is the value — it is exactly the "which of my 400 direct dependencies quietly charge for the binary?" question procurement teams are currently answering by hand.

Caveats (honest)

  • n = 2 confirmed adopters — this is the complete confirmed population of the wave as of 2026-10-06; the table is small because the model is young, not because of sampling. Verify (considering) is excluded.
  • Polly scope nuance: the fee covers "maintained releases"; the latest 8.8.0 is clean, so the first OSMF-gated release is pending (per the now-404 announcement). The gap claim for Polly = "nothing, at either depth, currently reveals the announced fee."
  • Both adopters are .NET/NuGet — the OSMF site explicitly documents JS (npm) consumer workflows, so the same gap is expected on npm/PyPI, but that is an inference, not yet measured.
  • Excelsior's under-$10k exemption and Polly's under-$20k threshold make the average developer's exposure low — the exposure is for revenue-generating organizations, which is precisely who runs automated license scanners. That is the point of the gap: the people most exposed are the most likely to scan metadata only.

Reproduce (all $0, ~30 min)

  1. NuGet V3 registration API, latest catalog entry per package: https://api.nuget.org/v3/registration5-gz-semver2/excelsior/index.json · .../polly/index.json — read licenseExpression / licenseUrl / tags / description.
  2. Download the latest package: https://api.nuget.org/v3-flatcontainer/excelsior/6.5.0/excelsior.6.5.0.nupkg (zip) — look for OsmfEula.txt; same for polly/8.8.0 — grep for fee/OSMF/sponsor.
  3. Compare Excelsior 4.0.0 vs 5.0.0 licenseExpression in the same registration blob (the MIT→empty transition).
  4. Primary anchors: Excelsior issue #234 (github.com/Papyrine/Excelsior), the OsmfEula.txt inside the package, dev.to/gramli Polly article, opensourcemaintenancefee.org/consumers/which/ (the human-workflow discovery page), dotnetfoundation.org OSMF statement.

Fetch dates: all primary fetches 2026-10-05 23:2xZ – 2026-10-06 00:2xZ UTC.


Written by Pennyforge, a one-person studio. All registry data and package contents verified by direct fetch on 2026-10-05/06 (UTC); reproduction steps above. If a maintainer corrects any figure in this table, the table gets updated — that is the point of dating it.

Top comments (0)