Skip to content

v1.6.2 — Open-source-readiness: license inventory + policy + GPL-3.0 remediation

Choose a tag to compare

@clem-field clem-field released this 18 May 12:40

SPARC v1.6.2

The open-source-readiness release. Closes out license inventory, policy, dispositions, and the GPL-3.0 runtime concern so SPARC can ship as an Apache-2.0 public repository with a clean compliance story.

This release does not add new application features — it's the infrastructure of supply-chain transparency: SBOM-driven license inventory, machine-readable policy, per-component dispositions, the actual license texts, and the gate that fails CI on un-dispositioned license violations. Plus one CI quality-of-life fix (aggregator hardening) and the removal of the only GPL-3.0 runtime dependency.

Highlights

📋 SBOM License Inventory + Policy (#472 → PR #474)

Consolidates the three CycloneDX SBOMs (Ruby gems via cdxgen, Trivy filesystem, Trivy container) into a single canonical license inventory artifact published on every Security Scanning CI run:

  • license-inventory.json — machine-readable (operators / sparc-iac / audit pipelines)
  • license-inventory.md — human-readable with grouped action-item tables (warn / unmapped / block) for compliance review
  • docs/compliance/license-policy.yml — declarative allowlist / warn_list / blocklist as policy-as-code
  • docs/compliance/license-dispositions.yml — per-component disposition tracker following the existing sparc-findings.yml (CVE) pattern. Supports accepted / replace / waiver / remediated.
  • Trivy --scanners license enabled on both fs and container scans (closes a 0% / 21% license coverage gap).

NIST control coverage updated: RA-3(1), CA-2, CM-8, SR-3, SA-15, SA-22.

🛠️ Inventory polish + LICENSES/ population (#475 → PR #477)

Cleaned up the inventory's signal-to-noise ratio and committed canonical SPDX license text:

  • License-alias normalization map in build_license_inventory.rb — canonicalizes upstream variants (Apache 2.0Apache-2.0, GPL-3.0GPL-3.0-only, OpenLDAP-2.8OLDAP-2.8, etc.) before policy lookup.
  • Cross-SBOM purl-level dedup — when the same gem appears in both sbom-ruby (with license) and trivy-container (without), collapse to the row that has the license, preserve provenance via joined source labels.
  • sparc-combined-sbom.cdx.json — single canonical CycloneDX SBOM with purl-deduplicated components (530 unique from 885 raw).
  • LICENSES/ populated — 26 license text files: 24 fetched from the SPDX license-list-data corpus + 2 hand-curated for non-SPDX entries (Brakeman, BSD-3-clause-Cambridge expression). New lib/tasks/licenses.rake (bin/rails licenses:fetch) regenerates LICENSES/README.md with component-count maps.

🧾 Baseline dispositions for the open-source story (#475 → PR #478)

Recorded 65 per-component dispositions covering the GPL family found in the inventory:

  • 64 acceptedbrakeman and bundler-audit (CI/dev-only Ruby gems) + 62 Debian Bookworm base-image system packages (dynamically-linked OS dependencies, not derivative works of SPARC application code).
  • 1 replacespreadsheet 1.3.4 flagged as a runtime GPL-3.0-only dependency. Remediated in this release; see below.

Audit result: AGPL: 0, OFL/Artistic/EPL/CDDL: 0 — no licensing surprises hiding in the dependency tree.

🚮 Removed spreadsheet / roo-xls (the GPL-3.0 fix, #479 → PR #480)

spreadsheet 1.3.4 (GPL-3.0-only) was loaded at runtime via SspExcelParserService / SarExcelParserService — strong copyleft incompatible with Apache-2.0 redistribution. Eliminated by dropping roo-xls from the Gemfile, which removes both gems transitively:

  • Gemfile.lock no longer contains spreadsheet 1.3.4 or roo-xls 2.0.0
  • roo (MIT, .xlsx) + caxlsx (MIT, export) retained — capability preserved for API consumers
  • Legacy .xls (Excel 97-2003 binary) support dropped as the trade-off

🧹 Excel UI scrub (#479)

Removed every user-facing reference to Excel ingest or export across views, about pages, and docs. Underlying services / routes / controllers / API stay live — the capability lives in the codebase and API; the UI just stops advertising it. Files affected:

app/views/sar_documents/{index,show,new,select_ssp,enrich}.html.erb
app/views/ssp_documents/{index,show,new,editor}.html.erb
app/views/about/{index,quickstart,api_docs}.html.erb
app/views/shared/_oscal_export_dropdown.html.erb
CLAUDE.md
docs/{API.md,SPARC_Video_Script.md,puma-dev.md}

Notable removal: the "Convert Excel to JSON" upload card + handleExcelUpload() / convertExcelToJSON() / showConversionStatus() JS in ssp_documents/editor.html.erb.

Historical creation_method == "excel" rows now display as "Import" in the UI (data preserved, label scrubbed).

🚦 License enforce gate flipped on (#479)

docs/compliance/license-policy.yml::enforce is now true. CI fails on:

  • Any component matching blocklist (BUSL / SSPL / Elastic / Commons Clause / etc.)
  • Any component matching warn_list without a recorded disposition in license-dispositions.yml

Operators resolve new findings by adding dispositions, not by weakening policy.

🔧 Aggregator hardening (#473 → PR #476)

Required Checks Passed (the branch-protection aggregator) now:

  • Fires on edited pull_request events (so body edits re-triggering Test plan checklist also re-run the aggregator — closes the gap that required manual gh run rerun on PRs #462, #467, #469, #471).
  • Skips short-circuiting on a stale failure when an in-flight rerun for the same check name exists. Logs "ignoring stale failures (in-flight rerun pending) for: …" and keeps polling.

Validated end-to-end on this release: every PR in #1.6.2 passed the aggregator on first run without manual intervention.

Upgrade Notes

  • No env-var changes required. Existing deployments continue to work.
  • No database migrations. bin/rails db:prepare is a no-op.
  • .xls (Excel 97-2003 binary) uploads will now fail. Use .xlsx, or — preferably — OSCAL JSON/YAML/XML.
  • License compliance documentation expanded. NOTICE, LICENSES/, docs/compliance/THIRD_PARTY_NOTICES.md, docs/compliance/license-policy.yml, docs/compliance/license-dispositions.yml are now part of the audit-package surface.
  • license_inventory is now a required CI artifact alongside the existing SBOM + HDF outputs in sparc-compliance-latest.

Backlog Carried Forward

  • 120 unmapped components in the inventory (5 Ruby gems where cdxgen missed the license, 4 Debian system libs Trivy didn't enrich, 26 Python deps in tests/api/uv.lock, 80 Go modules from the vendored hdf binary, 5 meta entries) — to be triaged in a separate follow-up issue with a 5-category disposition plan.

Verification

  • Full test suite: 2202 examples, 0 failures, 2 pending (HdfRunner real-binary; environmental).
  • license_inventory CI artifact: 0 block-severity items, 0 un-dispositioned warns.
  • Required Checks Passed passed on first run for every PR in this release (#476, #477, #478, #480) — validates the aggregator fix.
  • AGPL components in the inventory: 0.

Release Contents

Issue PR Description
#472 #474 SBOM license inventory + policy + dispositions schema
#473 #476 Aggregator hardening (in-flight reruns, edited trigger)
#475 #477 Inventory polish + alias map + dedup + LICENSES/ population
#475 #478 Baseline GPL dispositions (65 entries)
#479 #480 Drop roo-xls; Excel UI scrub; enforce flip; v1.6.2 bump