Supported-release vulnerability maintenance¶
Editions: OSS, Cloud, Enterprise. Unless stated otherwise, everything on this page ships in OSS.
This controller keeps one durable work item per opted-in product, supported release, and advisory/component pair. It is not a backport factory, not a conformity assessment, and not an SLA. Finding absence on a later scan is not resolution. Failed, incomplete, or unknown audits never become a new baseline.
Clone Automated Issue Implementation (011) for the repair flow and a
read-only CRA audit preset (004–007, unchanged) for the recheck. Optional
preset 014 is a conservative implementation overlay: isolated publication,
a verification gate, and no agent approval tools. Configure inventory through
the API, not by pasting a model-output URL. Scan ingest must name an existing
tracker issue so implementation receives a real issue body, number, and
repository. The trigger payload carries the pinned build, SBOM bytes or path,
prior baseline result, and published SHA on the existing workspace/trigger
contracts. After human approval, a rebuilt SBOM for that published commit
must be submitted (POST /items/{id}/build); the controller does not rebuild
the product. Recheck then checks out the verified published commit. Human
decisions go through the platform approval workflow (owner, escalation, quorum,
expiry); approving the linked request in the console advances the item without
a second maintenance-specific call. Background reconciliation retries dispatch
and expired approvals without requiring a GET. GET returns the stored item.
Opt in a release¶
POST /api/v1/security-maintenance/releases is the only enrollment path.
Unsupported product or release names fail closed on scan ingest.
{
"product_key": "example-widget",
"release_key": "1.2",
"display_name": "Example Widget 1.2",
"project_id": "<project-uuid>",
"pinned_build_ref": "v1.2.3",
"sbom_input_ref": "sbom/image.spdx.json",
"audit_flow_id": "<audit-flow-uuid>",
"implementation_flow_id": "<implementation-flow-uuid>",
"recheck_flow_id": "<recheck-flow-uuid>",
"approval_workflow_id": "<approval-workflow-uuid>",
"approval_owner_user_id": "<user-uuid>",
"escalation_user_ids": [],
"escalation_after_seconds": 604800,
"max_retries": 3,
"enabled": true
}
The implementation flow must use isolated publication and verification.mode:
gate. The audit/recheck flow must not publish, and should keep an empty MCP
tool list. Model and input-kind allow lists, when set, are enforced.
Initial baseline¶
Schedule the source SBOM audit through the authenticated inventory API, then accept only a completed bound execution:
POST /api/v1/security-maintenance/releases/{release_id}/baseline/audit
{"sbom_content_base64": "<source CycloneDX or SPDX JSON>"}
That request pins the saved audit flow, pinned_build_ref, and
sbom_input_ref, writes a PENDING execution with the controller envelope,
commits, then dispatches through the existing flow trigger path. GET
/api/v1/security-maintenance/releases/{release_id} shows
baseline_audit_execution_id and baseline_dispatch_state. Dispatch takes a
short exclusive claim (the same stale interval as flow-execution recovery,
default 120 seconds). If the process stops after the claim is stored and
before the execution is handed off, the row stays PENDING with
dispatch_state=dispatching. After the claim expires, the same POST with
the same SBOM bytes, or background reconcile, redelivers that execution id.
A live claim is not duplicated. An execution that has already started or
finished is not restarted. Older dispatching records without a claim
timestamp are treated as expired. A dispatch failure that the process
survives leaves dispatch_state=pending so the same retry can run
immediately. PENDING or failed executions cannot be accepted.
After the audit execution is SUCCEEDED and evidence is stored:
POST /api/v1/security-maintenance/releases/{release_id}/baseline
{"audit_execution_id": "<execution-uuid>"}
Acceptance still requires the envelope release_id and the digest of the
supplied SBOM bytes. Filename and pin matches alone are not enough.
What happens¶
- A trusted scan ingest names findings. The same identity updates the existing item. A disappeared finding is recorded as unverified and does not close the item or open a second pull request.
- One implementation execution is dispatched through the existing flow worker.
Completion reads controller publication receipts (
head_sha) and controller-owned verification for that commit.SUCCEEDEDwithout a test receipt does not pass. Implementation and recheck use the same expiring dispatch claim as the initial-baseline audit: background reconcile retries an abandonedPENDINGexecution after the claim expires, and does not restart a running or finished execution. - Tests failing holds the item. Tests passing opens a platform approval
request. Agent
result.approvedis ignored. An execution API key cannot approve its own repair. Denied or expired approvals hold or escalate; they never auto-release. The approval owner must already be on the selected workflow; maintenance does not rewrite shared workflow rows. - After a human approval, submit a rebuilt SBOM bound to the published SHA
(
POST /api/v1/security-maintenance/items/{id}/build). Reusing the original SBOM bytes is rejected. The controller parses the submitted CycloneDX or SPDX JSON and derives component identities from those bytes; a model inventory that omits a still-present target cannot prove removal. Removal requires a supported CycloneDX JSON (specVersion1.2–1.6) or SPDX JSON (spdxVersionSPDX-2.2 or SPDX-2.3) document with an explicit component list (componentsorpackages). Omitted or null lists, unsupported versions, and malformed nesting are rejected; an explicit empty list is a valid empty inventory. This is inventory integrity, not full SBOM schema validation. Malformed, ambiguous, incomplete, or unadvertised SBOM input is rejected. A recheck execution then checks out the published SHA against that new inventory. CRA results are validated by the contracts layer. Missing evidence, unknownpreloop.cra.*schemas, incomplete scans, and unscreened components cannot prove the advisory is gone. Checkout proof is the controller-verified frozen publication checkout (observed bundle SHA orproduct_provenancerepositories withsha_status=verified), not agent-writableHEAD.txtand notpayload.sha. Audit and recheck flows must namegit_clone_config.repositories[].repository_url. Whenpinned_build_refor the published SHA is an exact git object name, the controller writes aproduct_provenancemapping onto the trigger. Hosted and private audit/recheck post-exec export that checkout into the existing evidencebranch.bundlepath even when there are no code changes, no target branch, and publication is off. The export does not commit, push, open a pull request, or receive writer credentials. Isolated publication keeps its own exporter. Completion verifies the mapping against those frozen bundle members. The mapping is checkout observation, not a signed build attestation. Tag-like pins stay unverified until a bundle proves the checkout. Initial baseline acceptance requires the audit execution scheduled above. - Only an accepted recheck writes a new baseline. Prior decisions stay append-only. Resume retries without rewriting history.
What this is not¶
This is not automatic backporting, not a Cyber Resilience Act filing, not a certification, and not a promise that every supported release will be patched on a calendar. Operators still choose which products are opted in, which flows run, and which humans approve a repair.