Skip to content

chore(license): relicense GPL v3 → Apache 2.0 (CNCF Sandbox hard blocker)#138

Merged
Jovonni merged 8 commits into
masterfrom
cncf/relicense-apache-2.0
Jun 22, 2026
Merged

chore(license): relicense GPL v3 → Apache 2.0 (CNCF Sandbox hard blocker)#138
Jovonni merged 8 commits into
masterfrom
cncf/relicense-apache-2.0

Conversation

@Jovonni

@Jovonni Jovonni commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Why

CNCF Charter §11 requires Apache 2.0. This PR is the single license-swap blocker for the Sandbox application tracked in GACWR/OSSVCs#76 (also referenced in OSSVCs#79 / #80). Without this swap, the application can't move forward — every other governance prerequisite is already in flight via the companion PR.

Companion: #137 (cncf/governance-files) — already prepared governance files (GOVERNANCE.md, CODE_OF_CONDUCT.md, MAINTAINERS.md, ADOPTERS.md, SECURITY.md, ROADMAP.md).

What changed

Area Change Files
LICENSE Replaced GNU GPL v3 full text with canonical Apache License 2.0 text from https://www.apache.org/licenses/LICENSE-2.0.txt, plus Copyright (c) 2019–present GACWR. Licensed under the Apache License, Version 2.0. footer line 1
NOTICE New file at repo root (required by Apache 2.0 §4) 1 (new)
Source headers Swapped the existing This program is free software… GNU Lesser General Public License… block for the standard Apache 2.0 short header. Files without an existing header were intentionally left alone (separate cleanup pass). 30 (27 *.py, 3 *.js)
Package metadata sdk/pyproject.toml: license = \"GPL-3.0-only\"\"Apache-2.0\", plus trove classifier swap to License :: OSI Approved :: Apache Software License. interface/package.json has no license field — no change. No setup.py in the repo. 1
README badges + references README.md and sdk/README.md license badge → license-Apache_2.0-blue, License section text → Apache License 2.0 2

Totals: 35 files changed, +514 / -1072 lines (the big delta is the GPL v3 → Apache 2.0 LICENSE swap, 674 → 207 lines).

Things I did NOT touch (flagging for transparency)

  • interface/package-lock.json, interface/pnpm-lock.yaml — third-party dependency lock files. License strings inside refer to upstream packages and must not be hand-edited.
  • core/storage/models.json — contains base64-encoded model payloads; gpl substring matches are coincidental inside the encoded blobs, not license declarations.
  • Source files with no existing license header — adding new headers to bare files is a separate cleanup pass, intentionally out of scope per the brief.
  • Existing LGPL (Lesser GPL) header blocks were treated as in-scope for the swap (same GPL family, same blocker).

Honest section: contributor consent

Consent path — Georgia Cyber Warfare Range holds full copyright on all non-trivial contributions to date. The audit of git log --all --since=2025-06-21 confirms one human author (jovonnipharr@gmail.com) + dependabot in the past 12 months; project-history review identifies no third-party human contributors with substantive (copyrightable) GPL-licensed code. DCO sign-off (Signed-off-by: trailer) is required on all future PRs going forward.

If the operator confirms the consent path above, this PR is merge-ready end-to-end.

Commits

  • 81dd25d chore(license): relicense from GPL v3 to Apache 2.0 — LICENSE + NOTICE
  • cb2ab43 chore(license): swap GPL headers for Apache 2.0 short header across sources
  • 9e881b4 chore(license): update SPDX identifiers in package.json + pyproject.toml + setup.py
  • 09ab9d2 docs: README license badge + references → Apache 2.0

cc @Jovonni for the consent-path confirmation + merge. @copilot for review.

Jovonni added 4 commits June 21, 2026 19:46
Replace the GNU GPL v3 LICENSE with the canonical Apache License 2.0
text from https://www.apache.org/licenses/LICENSE-2.0.txt and add a
NOTICE file at the repo root as required by Apache 2.0 §4.

This is the first of four commits relicensing OpenUBA from GPL v3 to
Apache 2.0, which is the single hard blocker for the CNCF Sandbox
application (CNCF Charter §11 requires Apache 2.0).
…ources

Replace the GNU Lesser GPL v3 / GPL v3 header block (the
"This program is free software: you can redistribute it and/or modify…"
variant) with the standard Apache License 2.0 short header in every
source file that already carried a license header.

Touched 30 files (27 *.py, 3 *.js). Files without an existing header
are intentionally left untouched — adding headers to bare files is a
separate cleanup pass and out of scope for this relicensing PR.
…oml + setup.py

sdk/pyproject.toml:
  - license = "GPL-3.0-only" → "Apache-2.0" (SPDX identifier)
  - Trove classifier swap: GNU General Public License v3 (GPLv3)
    → Apache Software License

interface/package.json has no license field (no change needed).
There is no setup.py in the repo — sdk/ uses pyproject.toml via
hatchling, and no other Python distribution metadata exists.
- README.md badge: license-GPL-blue → license-Apache_2.0-blue
- README.md "License" section: GPL License → Apache License 2.0
- sdk/README.md badge: license-GPL--3.0-blue → license-Apache_2.0-blue
- sdk/README.md "License" section: GNU General Public License v3.0
  → Apache License 2.0

No other GPL/GNU references remain in markdown or metadata.
@Jovonni Jovonni added the enhancement New feature or request label Jun 21, 2026
@Jovonni Jovonni requested a review from Copilot June 21, 2026 23:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR relicenses the OpenUBA repository from GPLv3/LGPLv3-family headers to Apache License 2.0 to satisfy CNCF Sandbox requirements. It updates the canonical license texts, propagates the new short header across existing source files that already had a license block, and aligns key docs/package metadata to reflect the new license.

Changes:

  • Replaced repo-root LICENSE with Apache 2.0 text and added a new repo-root NOTICE.
  • Swapped existing GPL/LGPL header blocks for the Apache 2.0 short header across Python/JS source files that already had headers.
  • Updated SDK packaging metadata and README(s) to reference Apache 2.0.

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
LICENSE Replaces GPLv3 license text with Apache 2.0 license text.
NOTICE Adds Apache 2.0 NOTICE file at repo root.
README.md Updates license badge/link and License section reference.
sdk/README.md Updates license badge/link and License section reference.
sdk/pyproject.toml Updates SDK package license metadata and classifier to Apache.
interface/server.js Replaces LGPL header block with Apache 2.0 short header.
interface/src/components/Content/views/Home/Home.js Replaces LGPL header block with Apache 2.0 short header.
interface/src/components/Content/views/Home/index.js Replaces LGPL header block with Apache 2.0 short header.
core/alert.py Replaces LGPL header block with Apache 2.0 short header.
core/anomaly.py Replaces LGPL header block with Apache 2.0 short header.
core/api.py Replaces LGPL header block with Apache 2.0 short header.
core/case.py Replaces LGPL header block with Apache 2.0 short header.
core/core.py Replaces LGPL header block with Apache 2.0 short header.
core/database.py Replaces LGPL header block with Apache 2.0 short header.
core/dataset.py Replaces LGPL header block with Apache 2.0 short header.
core/dataset_test.py Replaces LGPL header block with Apache 2.0 short header.
core/display.py Replaces LGPL header block with Apache 2.0 short header.
core/display_test.py Replaces LGPL header block with Apache 2.0 short header.
core/encode.py Replaces LGPL header block with Apache 2.0 short header.
core/encode_test.py Replaces LGPL header block with Apache 2.0 short header.
core/entity.py Replaces LGPL header block with Apache 2.0 short header.
core/entity_test.py Replaces LGPL header block with Apache 2.0 short header.
core/hash.py Replaces LGPL header block with Apache 2.0 short header.
core/hash_test.py Replaces LGPL header block with Apache 2.0 short header.
core/model.py Replaces LGPL header block with Apache 2.0 short header.
core/model_test.py Replaces LGPL header block with Apache 2.0 short header.
core/process.py Replaces LGPL header block with Apache 2.0 short header.
core/process_test.py Replaces LGPL header block with Apache 2.0 short header.
core/risk.py Replaces LGPL header block with Apache 2.0 short header.
core/riskmanager.py Replaces LGPL header block with Apache 2.0 short header.
core/rule.py Replaces LGPL header block with Apache 2.0 short header.
core/test.py Replaces LGPL header block with Apache 2.0 short header.
core/user.py Replaces LGPL header block with Apache 2.0 short header.
core/user_test.py Replaces LGPL header block with Apache 2.0 short header.
core/utility.py Replaces LGPL header block with Apache 2.0 short header.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread LICENSE
Comment on lines +1 to +2

Apache License
Comment thread LICENSE Outdated
See the License for the specific language governing permissions and
limitations under the License.

Copyright (c) 2019–present GACWR. Licensed under the Apache License, Version 2.0.
Comment thread sdk/pyproject.toml Outdated
Comment on lines 11 to 12
license = "Apache-2.0"
license-files = ["LICEN[CS]E*"]
@Jovonni

Jovonni commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

@copilot Updated in 79aecbc: legal name "Georgia Cyber Warfare Range" replaces "GACWR" shorthand in all copyright text (LICENSE + NOTICE + READMEs + 30 source-file headers). Org URLs and GH slug references unchanged.

Verification:

  • LICENSE:204 and NOTICE both read Copyright (c) 2019–present Georgia Cyber Warfare Range
  • All 27 core/*.py + 3 interface/**/*.js headers updated (32 files changed, 33/33 ins/del — strictly the attribution line)
  • READMEs had no copyright-holder text; only repo-URL/badge references to GACWR (untouched)
  • sdk/pyproject.toml authors field already named jovonni, not GACWR — no swap needed
  • Remaining GACWR strings are all github.com/GACWR/... URLs, the diagram art label GACWR/openuba-model-hub, and the README badges/links — all intentional org-slug references

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 6 comments.

Comment thread LICENSE
Comment on lines +1 to +5

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

Comment thread sdk/pyproject.toml
Comment on lines +11 to 13
license = "Apache-2.0"
license-files = ["LICEN[CS]E*"]
authors = [
Comment thread README.md Outdated
| Status | Badge | Status | Badge |
| --- | --- | --- | --- |
| `Build` | [![Build](https://img.shields.io/github/actions/workflow/status/GACWR/OpenUBA/docker-publish.yml?branch=master&label=build)](https://github.com/GACWR/OpenUBA/actions) | `License` | [![License](https://img.shields.io/badge/license-GPL-blue.svg)](https://github.com/GACWR/OpenUBA/blob/master/LICENSE) |
| `Build` | [![Build](https://img.shields.io/github/actions/workflow/status/GACWR/OpenUBA/docker-publish.yml?branch=master&label=build)](https://github.com/GACWR/OpenUBA/actions) | `License` | [![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](https://github.com/GACWR/OpenUBA/blob/master/LICENSE) |
Comment thread README.md Outdated
## License

[GPL License](https://github.com/GACWR/OpenUBA/blob/master/LICENSE)
[Apache License 2.0](https://github.com/GACWR/OpenUBA/blob/master/LICENSE)
Comment thread sdk/README.md Outdated
Comment thread sdk/README.md Outdated
Jovonni added 3 commits June 21, 2026 20:47
… only

Strip the appended project-specific copyright footer from LICENSE so the
file is byte-exact with https://www.apache.org/licenses/LICENSE-2.0.txt.
Attribution already lives in NOTICE (the correct home per Apache 2.0
conventions), so license scanners (SPDX, scancode, etc.) now detect
the license cleanly without the modified-text false negative.

Addresses Copilot review comments #1, #2, #4 on PR #138.
Hatchling's license-files glob is relative to the package root (sdk/), so
the previous "LICEN[CS]E*" pattern matched nothing — the published wheel
shipped without any License-File metadata. Add sdk/LICENSE and sdk/NOTICE
as copies of the repo-root files, and extend the glob to include NOTICE*.

Verified with `hatch build`: both sdist (PKG-INFO) and wheel (METADATA)
now declare:

    License-Expression: Apache-2.0
    License-File: LICENSE
    License-File: NOTICE

and the wheel ships them under .dist-info/licenses/.

Addresses Copilot review comments #3, #5 on PR #138.
Hard-coded blob/master URLs break the moment the default branch is
renamed (e.g. master → main). For in-repo references, use relative paths
so navigation works on forks and at any ref. For URLs that must render
off-GitHub (sdk/README.md is the PyPI long description), use blob/HEAD
so GitHub resolves the active default branch dynamically.

- README.md (badge + footer link): → ./LICENSE
- sdk/README.md (badge + footer link): → blob/HEAD/LICENSE

Addresses Copilot review comments #6, #7, #8, #9 on PR #138.
@Jovonni

Jovonni commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

@copilot Addressed all 9 review comments in ef21303 (3-commit series fe830449b6c7b4ef21303):

  1. LICENSE (Error in Makefile #1, Main dev branch #2, Add a continuous integration service #4): stripped appended project footer, file is now byte-exact with https://www.apache.org/licenses/LICENSE-2.0.txt. Attribution lives in NOTICE only. Verified: diff <(cat LICENSE) <(curl -s https://www.apache.org/licenses/LICENSE-2.0.txt) returns clean.
  2. sdk packaging (Merging Main dev branch with new install.md #3, Create CODE_OF_CONDUCT.md #5): added sdk/LICENSE + sdk/NOTICE (copies of root) and extended license-files = [\"LICEN[CS]E*\", \"NOTICE*\"]. Verified with hatch build: both sdist (PKG-INFO) and wheel (METADATA) now declare License-File: LICENSE and License-File: NOTICE, and wheel ships them under .dist-info/licenses/.
  3. blob/master links (URL not found on server #6, merge with correct installation documentation #7, merging to fix install.md file link #8, updated in-file licenses and readme to reflect OpenUBA #9): README.md badge + footer → ./LICENSE (relative, works on forks); sdk/README.md badge + footer → blob/HEAD/LICENSE (absolute, renders correctly on PyPI long description and survives default-branch renames).

@Jovonni Jovonni merged commit 21474ef into master Jun 22, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants