v1.8.0 — CdefMutationService + back-matter promotion + bulk Converter→CDEF
v1.8.0 — CdefMutationService + back-matter promotion + bulk Converter→CDEF
Minor release. Headline change: every CDEF mutation now funnels through
CdefMutationService, which validates the post-mutation OSCAL against
the NIST component-definition v1.1.2 schema before the transaction
commits. A mutation that would produce an invalid OSCAL hash is
rejected pre-commit instead of silently persisting. OSCAL back-matter
is promoted out of the legacy import_metadata["back_matter"] stash
to first-class BackMatterResource rows across every document type.
Six closed issues bundled into this release:
- #498 — CdefMutationService + first-class CDEF back-matter
- #581 — BackMatterResourceChange audit rows on BMR mutations
- #582 — Deterministic CdefControlStatement UUIDs on clone
- #583 — Back-matter promotion (stash → first-class) for SSP / SAR /
SAP / Profile / POAM - #584 — AWS Labs validate:false opt-out removed; underlying schema
gap root-caused (two local bugs, not upstream) - #499 — Bulk-apply Converter output to a CDEF clone, with NIST
Rev 4 ↔ Rev 5 helper
Headline features
#498 — CdefMutationService
Single contract for all CDEF mutations. Wraps writes in a database
transaction; validates the post-mutation OSCAL via
OscalComponentDefinitionExportService.validation_result before
commit. Used by API #create / #update, web
#update_metadata / #update_field / #update_statement, clone via
DocumentDuplicationService, parser write-through, profile-derived
construction, and #create_control_resource. Raises
CdefMutationService::ValidationError on invalid OSCAL — caller sees
a clean 422 with the schema failure detail.
#583 — Back-matter promotion to first-class
Every doc-type parser (CDEF, SSP, SAR, SAP, Profile, POAM) now
writes BackMatterResource rows (source: "imported") instead of
stashing the OSCAL back-matter.resources array in
import_metadata["back_matter"]. Idempotent data migrations
backfill existing documents. BackMatterBuilder#deduplicated_imports
is now removed — the exporter reads from a single source.
#499 — Bulk-apply Converter → CDEF
Preview-then-confirm workflow takes a Converter (AWS Security Hub,
AWS Config, DISA CCI, CIS, SCAP) and applies its NIST 800-53 output
in bulk to a CDEF clone. Two API endpoints + a Hotwire UI on the
CDEF show page. Preview returns a HMAC-signed (15-min TTL) token
the confirm endpoint replays via CdefMutationService. Refuses
AWS-Labs-sourced CDEFs (clone first). NIST Rev 4 ↔ Rev 5
ControlMapping seeded from the official NIST CSRC
sp800-53r4-to-r5-comparison-workbook.xlsx; ControlIdNormalizer
translates ids across revisions automatically when a Rev-4
converter is applied with target_rev=5 (or vice versa). Every
successful apply cites the source Converter (and the rev mapping
when used) as BackMatterResource rows on the CDEF — the OSCAL
export carries auditable provenance.
- Bulk-apply gated on admin OR
converters.writeRBAC. - Idempotent: re-applying the same converter is a no-op.
- Two new AuditEvent actions registered:
cdef_bulk_apply_converter_previewed,
cdef_bulk_apply_converter_applied.
Supporting fixes
#582 — Deterministic statement UUIDs on clone
Re-exporting a cloned CDEF previously gave statement UUIDs fresh
random values each time. Now derived from
(new_control.uuid, "cdef-statement", statement_id) — same shape
the parser already uses for fresh imports — so re-exports
byte-compare cleanly. CdefControl-level derivation deferred (needs
a schema addition; control_id isn't unique within a CDEF).
#581 — BMR audit rows
BackMatterAudit.record_create emits one BackMatterResourceChange
per BMR create from CDEF write paths (parser promotion +
#create_control_resource), with batch_uuid grouping for
multi-resource transactions and explicit user: capture.
#584 — AWS Labs OSCAL validation re-enabled
Investigated the validate: false opt-out added in #580: not an
upstream problem. Two local bugs were masked — one bad placeholder
UUID in a test fixture, and the AwsLabsCdefImportService writing
the string "true" into published (which the exporter blindly
emitted into OSCAL metadata.published, failing the datetime
pattern). Both fixed; validate: false removed.
Compliance
docs/compliance/nist-sp800-53-rev5-mapping.mdupdated:- AU-2: notes the two new bulk-apply audit event types
- CM-3: documents the preview-then-confirm workflow as a
change-control pattern
- Per-CDEF back-matter citations of converter source + rev mapping
surface in the OSCAL export (CDEF back-matter is the audit
trail of where each control came from).
Migrations
Two new migrations (both IrreversibleMigration, idempotent on
re-run):
- 20260526120000_promote_cdef_back_matter_imports
(shipped in #580, listed here for completeness) - 20260526200000_promote_remaining_back_matter_imports
Seed bumps (re-run on existing deployments):
- converters → 1.4.0 (target_rev backfill on existing seeds)
- nist_rev4_rev5_mapping → 1.0.0 (new section)
Test result
bundle exec rspec 2517 examples, 0 failures, 2 pending
(+~75 net new across the train)
bin/rubocop 0 offenses
Upgrade notes
- No env var or config changes required.
- The two data migrations run automatically via
bin/rails db:migrate
and are forward-only. - Operators on the v1.7.x line can upgrade in place.
- The new bulk-apply UI is gated on the existing
converters.write
permission. Operators who can already use the AWS Labs refresh
button can use bulk-apply.
🤖 Generated with Claude Code