chore(license): relicense GPL v3 → Apache 2.0 (CNCF Sandbox hard blocker)#138
Conversation
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.
There was a problem hiding this comment.
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
LICENSEwith Apache 2.0 text and added a new repo-rootNOTICE. - 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.
|
|
||
| Apache License |
| 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. |
| license = "Apache-2.0" | ||
| license-files = ["LICEN[CS]E*"] |
|
@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:
|
|
|
||
| Apache License | ||
| Version 2.0, January 2004 | ||
| http://www.apache.org/licenses/ | ||
|
|
| license = "Apache-2.0" | ||
| license-files = ["LICEN[CS]E*"] | ||
| authors = [ |
| | Status | Badge | Status | Badge | | ||
| | --- | --- | --- | --- | | ||
| | `Build` | [](https://github.com/GACWR/OpenUBA/actions) | `License` | [](https://github.com/GACWR/OpenUBA/blob/master/LICENSE) | | ||
| | `Build` | [](https://github.com/GACWR/OpenUBA/actions) | `License` | [](https://github.com/GACWR/OpenUBA/blob/master/LICENSE) | |
| ## License | ||
|
|
||
| [GPL License](https://github.com/GACWR/OpenUBA/blob/master/LICENSE) | ||
| [Apache License 2.0](https://github.com/GACWR/OpenUBA/blob/master/LICENSE) |
… 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.
|
@copilot Addressed all 9 review comments in ef21303 (3-commit series fe83044 → 9b6c7b4 → ef21303):
|
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
LICENSECopyright (c) 2019–present GACWR. Licensed under the Apache License, Version 2.0.footer lineNOTICEThis 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).*.py, 3*.js)sdk/pyproject.toml:license = \"GPL-3.0-only\"→\"Apache-2.0\", plus trove classifier swap toLicense :: OSI Approved :: Apache Software License.interface/package.jsonhas no license field — no change. Nosetup.pyin the repo.README.mdandsdk/README.mdlicense badge →license-Apache_2.0-blue, License section text →Apache License 2.0Totals: 35 files changed, +514 / -1072 lines (the big delta is the GPL v3 → Apache 2.0
LICENSEswap, 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;gplsubstring matches are coincidental inside the encoded blobs, not license declarations.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-21confirms 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
81dd25dchore(license): relicense from GPL v3 to Apache 2.0 — LICENSE + NOTICEcb2ab43chore(license): swap GPL headers for Apache 2.0 short header across sources9e881b4chore(license): update SPDX identifiers in package.json + pyproject.toml + setup.py09ab9d2docs: README license badge + references → Apache 2.0cc @Jovonni for the consent-path confirmation + merge. @copilot for review.