v1.6.1 — SBOM-driven SCA, AWS Labs CDEFs, SAF CLI hardening + migration squash
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:
ubuntu-latestdefaults to Node 20.x but@mitre/saftransitively requires Node ≥22 —cyclonedx_sbom2hdfandanchoregrype2hdfwere silently failing withMODULE_NOT_FOUND. Pinned Node 22 +@mitre/saf@1.6.0.download-artifact@v8withname:extracts files flat, not into per-artifact subdirs — corrected the script paths.- The
cyclonedx-rubygem (v1.1.0) only emits XML — replaced with@cyclonedx/cdxgen@11which 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(defaultfalse)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.0 → 1.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-rubygem (v1.1.0) — removed in #466 / #463 work; replaced with@cyclonedx/cdxgen@11invoked vianpxin CI. The gem only emitted CycloneDX XML with a misleading.cdx.jsonfilename, breaking both Grype and SAF CLI'scyclonedx_sbom2hdfconverter.
Upgrade Notes
- No env-var changes required for existing deployments. All new vars default to off / sensible values.
db:prepareon 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.mdis 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-resultsCI 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.