Skip to content

License compliance policy

What licences TLSStress.Art dependencies are allowed to carry, how we detect incompatibilities, and how we respond when a scan flags one.

Our distribution licence

TLSStress.Art ships under PolyForm Noncommercial 1.0.0 with Appendix A (field-of-use restrictions). The licence text is in LICENSE; the plain-language explanation is in USAGE_POLICY.md.

Critical for compliance: PolyForm Noncommercial is source-available, not OSI-approved open source. Specifically, it forbids commercial use without separate written authorisation from the maintainer. Dependencies we pull in must not impose obligations that are incompatible with this distribution model.

Allowed dependency licences

Licence family Allowed? Notes
MIT / BSD / Apache 2.0 / ISC ✅ Yes Permissive — fully compatible
MPL 2.0 / EPL 2.0 ✅ Yes File-level copyleft — fine for libraries
CC0 / Unlicense / 0BSD ✅ Yes Public-domain-equivalent
OpenSSL / Boost / Zlib ✅ Yes Permissive variants
PolyForm Noncommercial / PolyForm Free Trial ✅ Yes Our own licence family
LGPL 2.1 / 3.0 ⚠️ Case-by-case OK if we link dynamically and document the LGPL component; obligations on us are minimal but not zero
GPL 2.0 / 3.0 / AGPL ❌ No Strong copyleft — would force us to redistribute under GPL, which conflicts with the PolyForm noncommercial model
SSPL / BSL / Confluent CL ❌ No Source-available with broader restrictions than ours; cannot freely re-redistribute
Proprietary ❌ No Cannot redistribute without case-by-case clearance
Public-source NOLICENSE ❌ No Without an explicit licence, the default is "all rights reserved" — we cannot use it

The single hardest red line: no GPL or AGPL anywhere in any shipping artefact. If you accidentally pull a GPL dep transitively, the PR fails compliance and we either find an alternative or open a case-by-case review.

Where the manifest of dependencies lives

Each module owns its own manifest:

Module type Manifest Tool we use to read it
Node.js (dashboard/, agent/, k6-agent/, cloner/, iperf3-agent/, bgp-router-peer/, ospf-router-peer/) package.json + package-lock.json npm ls / license-checker
Go (har-engine/, mock-engine/, persona-seeder/, every pkg/...) go.mod + go.sum go-licenses report
Python (ansible-orchestrator/) requirements.txt pip-licenses
Docker base images Dockerfile FROM lines manual review on bump
System packages (Debian / Alpine) base-image layer Syft SBOM os cataloguer

The release SBOM (<image>-sbom.spdx.json per release asset) contains the per-package licence field for every package it enumerates — including OS-level packages — so a single document is enough for an audit handoff.

Scanning approach

Method Frequency Scope
Per-PR: Dependabot updates flag licence changes implicitly (different version, sometimes different licence) continuous new + bumped deps
Per-release: Syft SBOM captures the full licence inventory every release shipping artefacts
Per-release (planned): scancode-toolkit or go-licenses report --check as a CI gate every release enforcement
Quarterly: human review of the SBOM licence histogram quarterly drift detection

Why automated CI-blocking licence scanning is queued, not shipping today: scancode-toolkit and FOSSA are heavy (multi-minute runs on a full Node.js dep tree). We want to introduce them as a release-time gate, not a per-PR gate, to keep the PR feedback loop fast. Tracked under docs/governance/QUALITY_GATES.md § "Queued for enrolment".

When a scan flags a non-allowed licence

  1. Stop. Do not ship a release that includes a GPL / AGPL dependency.
  2. Identify the packagenpm ls <pkg> / go mod why <pkg> to find the transitive source.
  3. Look for an alternative — most ecosystems have multiple implementations; permissively-licensed alternatives almost always exist for popular use cases.
  4. If no alternative exists — open an RFC (per RFC process) explaining the dependency, the unavailable alternative search, and the proposed resolution (carve-out via dynamic linking / case-by-case licence acquisition / feature removal).
  5. Never silently override — if a licence appears in the "❌ No" column above and lands in our manifest, that's a release-blocker until resolved.

Attribution requirements

Every shipping release surfaces the full dependency licence list via:

  • SBOM (SPDX, per release asset) — primary attribution artefact, machine-readable
  • NOTICE at repo root — human-readable list for the major permissive deps. We do not enumerate every transitive dep here (that's the SBOM's job); we list the ones whose licences require explicit attribution (Apache 2.0 NOTICE files, MPL 2.0 source-availability statements, etc.)
  • AUTHORS.md § Acknowledgements — points at SBOM + NOTICE + per-module manifests as the source of truth

What this policy is NOT

  • ❌ A substitute for a lawyer's licence-compatibility review before commercial relicensing. If we ever spin off a commercial variant of TLSStress.Art, every dependency's licence must be re-cleared against the new distribution model.
  • ❌ A guarantee that every transitive dep is permissive. Manifests drift; SBOMs catch drift. The release-prep checklist in docs/governance/RELEASE_CADENCE.md reviews the SBOM histogram against this policy.
  • ❌ An indemnification. PolyForm Noncommercial provides no warranty; downstream users are responsible for their own licence-compliance posture in their environment.

Last verified against shipping code: v3.7.0 (2026-05-12).