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¶
- Stop. Do not ship a release that includes a GPL / AGPL dependency.
- Identify the package —
npm ls <pkg>/go mod why <pkg>to find the transitive source. - Look for an alternative — most ecosystems have multiple implementations; permissively-licensed alternatives almost always exist for popular use cases.
- 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).
- 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
NOTICEat 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.mdreviews 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.
Related¶
LICENSE— our distribution licenceUSAGE_POLICY.md— plain-language scopeNOTICE— major-dep attributionAUTHORS.md— human authorship + patent inventorsdocs/governance/QUALITY_GATES.md— scanning approach queuedocs/governance/VEX_POLICY.md— sibling supply-chain policydocs/runbooks/verify-release.md— downstream verificationdocs/ADR/0018-enterprise-procurement-compliance.md— broader compliance posture
Last verified against shipping code: v3.7.0 (2026-05-12).