Skip to content

v1.6.1 — SBOM-driven SCA, AWS Labs CDEFs, SAF CLI hardening + migration squash

Choose a tag to compare

@clem-field clem-field released this 17 May 23:30

SPARC v1.6.1

A maintenance + capability release. Three new defensive layers in the security pipeline (Grype SBOM scanning, AWS Labs CDEF ingestion, hardened HDF normalization), one operator-facing entrypoint fix, the second-ever migration squash, and the dependency-bump backlog cleared.

Highlights

🔐 SBOM-driven vulnerability scanning via Grype (#461)

Grype now consumes the CycloneDX SBOMs produced by sbom_generation, trivy_fs_scan, and trivy_container_scan and emits SARIF (for Code Scanning) + JSON (normalized to HDF). The supply-chain artifact downstream consumers receive is now scan-verified, not just generated. Three new categories in Code Scanning: grype-sbom-ruby, grype-sbom-trivy-fs, grype-sbom-trivy-container.

🧰 SAF CLI Node 22 pin + cdxgen Ruby SBOM (#463)

Resolved three nested CI bugs:

  1. ubuntu-latest defaults to Node 20.x but @mitre/saf transitively requires Node ≥22 — cyclonedx_sbom2hdf and anchoregrype2hdf were silently failing with MODULE_NOT_FOUND. Pinned Node 22 + @mitre/saf@1.6.0.
  2. download-artifact@v8 with name: extracts files flat, not into per-artifact subdirs — corrected the script paths.
  3. The cyclonedx-ruby gem (v1.1.0) only emits XML — replaced with @cyclonedx/cdxgen@11 which emits valid CycloneDX JSON.

Also fixed the Required Checks Passed aggregator: it now sorts check runs by started_at descending and picks the latest per name (was overwriting fresh passes with stale failures).

After the fix the hdf-results artifact contains all 11 expected HDFs (was 5 on main).

📥 AWS Labs CDEF runtime ingestion (#466)

Opt-in (SPARC_AWS_LABS_CDEF_ENABLED=true) Solid Queue recurring job that ingests OSCAL Component Definitions from awslabs/oscal-content-for-aws-services. Tenant-tunable refresh interval (default every 7 days), ETag-conditional fetches, copy-to-amend policy (AWS-sourced rows are read-only; users click "Copy for editing" to derive an editable clone — refreshes never touch clones), and full Apache 2.0 attribution via NOTICE, LICENSES/AWS-LABS-OSCAL-CONTENT-LICENSE, and docs/compliance/THIRD_PARTY_NOTICES.md.

New env vars (all default off):

  • SPARC_AWS_LABS_CDEF_ENABLED (default false)
  • SPARC_AWS_LABS_CDEF_REPO / _BRANCH (override fork/mirror)
  • SPARC_AWS_LABS_OSCAL_VERSIONS (auto-detected from loaded OSCAL schemas)
  • SPARC_AWS_LABS_CDEF_REFRESH_INTERVAL_DAYS (default 7, clamped 1–90)
  • SPARC_AWS_LABS_GITHUB_TOKEN (optional; raises rate limit 60→5000/hr)

NIST controls touched: RA-3(1), CA-2, CM-8, SR-3, SA-15.

🧹 Entrypoint db:prepare:all typo (#456)

bin/docker-entrypoint was invoking db:prepare:all (not a real Rails command) after the correct db:prepare line. Rails threw Rails::Command::UnrecognizedCommandError on every container boot — silenced by 2>/dev/null || true but still polluting CloudWatch. Line removed; the existing db:prepare already handles the migration.

🗄️ Migration squash + version bump (#470, this release)

Second consolidation since the 2026-03-19 squash (#183). Folds 29 migrations from Phases 5–9 into a single file with the same idempotent pattern (read db/schema.rb, eval, skip-if-tables-exist). Production databases with the per-migration history applied are unaffected (no-op on up). VERSION bumped 1.6.01.6.1.

Dependency Bumps

Ruby — minor bumps (#468)

Gem From To
jbuilder 2.14.1 2.15.0
aws-sdk-s3 1.220.0 1.222.0
aws-sdk-secretsmanager 1.129.0 1.130.0
aws-sdk-rds 1.311.0 1.312.0
aws-sdk-core (transitive) 3.247.0
aws-sdk-kms (transitive) 1.125.0
aws-partitions (transitive) 1.1249.0
jwt (transitive) 3.2.0
selenium-webdriver (transitive) 4.44.0
minitest (transitive) 6.0.6

Ruby — patch bumps (#458)

Gem To
puma 8.0.1
pagy 43.5.4
sidekiq 8.1.5
bootsnap 1.24.4
json 2.19.5
redis-client 0.29.0

Ruby — single (#452)

Gem From To
nokogiri 1.19.2 1.19.3

GitHub Actions (#465)

Action From To
actions/github-script v8 v9
actions/setup-node v4 v6
actions/cache v4 v5

Removed Dependencies

  • cyclonedx-ruby gem (v1.1.0) — removed in #466 / #463 work; replaced with @cyclonedx/cdxgen@11 invoked via npx in CI. The gem only emitted CycloneDX XML with a misleading .cdx.json filename, breaking both Grype and SAF CLI's cyclonedx_sbom2hdf converter.

Upgrade Notes

  • No env-var changes required for existing deployments. All new vars default to off / sensible values.
  • db:prepare on existing prod is a no-op — the new squash migration has an idempotency guard.
  • CI workflow node version pinned to 22 — if you maintain a fork of .github/workflows/security.yml, sync from upstream.
  • docs/compliance/THIRD_PARTY_NOTICES.md is new — review for compliance audit hand-off.

Backlog Carried Forward

  • Aggregator hardening — short-circuit-on-stale-failure pattern still exists; the started_at sort fix from #463 mitigates by re-run.
  • SBOM license tracking + license-policy gate (#472).

Verification

  • Full test suite: 2182 examples, 0 failures, 2 pending (HdfRunner real-binary; environmental).
  • hdf-results CI artifact: 11/11 expected HDFs present.
  • Fresh-DB and existing-DB migration paths verified locally on PR #471.
  • All security scans (Brakeman, CodeQL, Gitleaks, Trivy fs+container, dependency_audit, importmap_audit, Grype SBOM scan) green on every PR in the release.