Skip to content

Add Trivy copyleft licence scan - #41

Open
IanEdington wants to merge 1 commit into
mainfrom
claude/trivy-canopy-copyleft-scan-pt5zqk
Open

IanEdington wants to merge 1 commit into
mainfrom
claude/trivy-canopy-copyleft-scan-pt5zqk

Conversation

@IanEdington

Copy link
Copy Markdown
Contributor

Ports the licence gate from gpo/grassroots#296 to canopy.

trivy.yaml is byte-identical to the grassroots copy. A licence policy is a legal position, so the two repos should not drift on it. The only per-repo change is the install step: Composer here, pnpm there. Trivy reads licence metadata from installed packages rather than from lockfiles, so composer install has to run before the scan.

Read this before merging: the check will fail

Canopy's dependency tree contains GPL-2.0-or-later at the root of the product, not at the edges:

Package Licence
roots/wordpress MIT, GPL-2.0-or-later
roots/wordpress-no-content (WordPress core) GPL-2.0-or-later
roots/wordpress-core-installer GPL-2.0-or-later
gpo/qomon-wp-plugin (first-party) GPL-2.0-or-later

The remaining 73 Composer packages are clean: MIT (46), BSD-3-Clause (26), Apache-2.0 (1). But license.full: true also inspects loose files, so once web/wp is on disk the scan will additionally pick up WordPress core's own GPL headers and every bundled third-party library, plus any Composer-managed theme or plugin.

GPL-2.0-or-later sits in the policy's restricted list, which is HIGH, so this gate is red on day one and cannot go green while canopy is a WordPress build. WordPress core is not removable.

The policy exists because GPO offers a commercial grant alongside AGPL-3.0, and copyleft code cannot be relicensed. That premise does not hold for canopy: a WordPress site build is a derivative of GPL-2.0 core, so there is no proprietary track available to protect here no matter what this file says. This is a different claim from "the repo is already AGPL, so relax the rule" — canopy's copyleft is structural and load-bearing rather than incidental.

Three ways forward, none of which I picked unilaterally:

  1. Canopy-specific policy. Keep AGPL, SSPL, BUSL, CPAL, RPL, and the non-commercial CC licences forbidden, since those are incompatible with GPL-2.0 distribution as well. Drop GPL/LGPL/MPL/EPL/CDDL from restricted for canopy only, with the reason stated in the file. The gate still catches AGPL and proprietary or non-commercial creep, which is the live risk for a WordPress deployment.
  2. Keep the policy verbatim and add exclusions. Add scan.skip-dirs or license.ignored entries for WordPress core and known GPL plugins. One policy file, but the exception hides in scan config instead of being stated, and the ignore list grows with every plugin added.
  3. Do not scan canopy. Keep the check on grassroots, where dual licensing is real, and document why canopy is exempt.

Other things worth knowing

  • gpo/qomon-wp-plugin may need a token. composer.json pulls it from a VCS repository at github.com/gpo/qomon-wp-plugin. I could not confirm its visibility from this session, so composer install in Actions may need COMPOSER_AUTH or a PAT. Grassroots already has a broken secrets.ACTION_PAT; if the same secret is the answer here, this workflow inherits that problem.
  • Comment convention. CLAUDE.md says no explanatory comments in config files. trivy.yaml carries substantial comments. I kept them so the file stays byte-identical to grassroots; moving the rationale to docs/ would guarantee the two copies drift. Worth a decision either way.
  • Reusable workflow. Worth considering an org-level workflow_call in a gpo/.github repo, but the install step, the ecosystem, and now possibly the policy all differ between the two repos, so the shared portion is thin. gpo/.github is also outside this session's repository scope.
  • SPDX identifier. composer.json declares "license": "AGPLv3", which is not valid SPDX. It should be AGPL-3.0-or-later. Same defect as grassroots' root package.json. Not fixed here.
  • UNKNOWN licences are not gated, matching grassroots. The inventory step reports them so the exposure can be audited before deciding whether to gate.

Verification

Trivy could not be installed in this session (the sandbox's network policy blocks GitHub release downloads and get.trivy.dev), so the scan has not been run locally. The licence table above comes from vendor/composer/installed.json after a real composer install. CI on this PR is the first actual run.


Generated by Claude Code

Ports the licence gate from gpo/grassroots. The policy file is byte-identical
so the two repos cannot drift on what is effectively a legal position; the only
per-repo change is the install step, which is Composer here rather than pnpm.

Trivy reads licence metadata from installed packages, not from lockfiles, so
composer install has to run before the scan.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant