From 743295a4e3abb1e9152959cffdce9635c9d47040 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 20 Sep 2026 19:34:49 -0500 Subject: [PATCH 1/7] feat: safety impact of changes on classified contexts (#954, #1041) Signed-off-by: Steve Springett --- .../model/cyclonedx-blueprint-2.0.schema.json | 77 ++++++ .../model/cyclonedx-common-2.0.schema.json | 8 + .../cyclonedx-requirement-2.0.schema.json | 2 + .../2.0/model/cyclonedx-risk-2.0.schema.json | 57 +++++ ...nvalid-risk-assessment-conclusion-2.0.json | 19 ++ ...ety-integrity-level-missing-level-2.0.json | 29 +++ .../valid-safety-impact-assessment-2.0.json | 222 ++++++++++++++++++ .../2.0/valid-safety-impact-behavior-2.0.json | 184 +++++++++++++++ 8 files changed, 598 insertions(+) create mode 100644 tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json diff --git a/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json b/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json index 58cd5a7e9..55b6495a0 100644 --- a/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json @@ -1910,6 +1910,15 @@ "criticality": { "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/criticality" }, + "safetyIntegrityLevels": { + "type": "array", + "title": "Safety Integrity Levels", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/safetyIntegrityLevel" + }, + "description": "The safety integrity classifications of this asset in the context of the blueprint. An asset may carry classifications from more than one scheme, for example where an element classified under IEC 61508 is also mapped to an automotive ASIL. The classification identifies the safety significance of the context so that the impact of a change on it can be assessed." + }, "classification": { "$ref": "cyclonedx-data-2.0.schema.json#/$defs/dataClassification" }, @@ -1929,6 +1938,74 @@ } } }, + "safetyIntegrityLevel": { + "type": "object", + "title": "Safety Integrity Level", + "description": "A safety integrity classification drawn from a functional safety scheme, such as an Automotive Safety Integrity Level, a Safety Integrity Level, a Design Assurance Level, or a software safety class. The classification describes the safety significance of the context; a level that an authority has attested the subject achieved is recorded as a certification.", + "required": [ + "scheme", + "level" + ], + "additionalProperties": false, + "properties": { + "scheme": { + "title": "Scheme", + "description": "The functional safety scheme from which the level is drawn. Use the custom option for schemes not covered by the enumeration.", + "oneOf": [ + { + "title": "Predefined Safety Scheme", + "enum": [ + "ISO-26262", + "IEC-61508", + "DO-178C", + "IEC-62304", + "EN-50128" + ], + "meta:enum": { + "ISO-26262": "Road vehicles functional safety. Levels are Automotive Safety Integrity Levels, from QM to ASIL D.", + "IEC-61508": "Functional safety of electrical, electronic, and programmable electronic safety-related systems. Levels are Safety Integrity Levels 1 to 4.", + "DO-178C": "Software considerations in airborne systems and equipment certification. Levels are Design Assurance Levels A to E.", + "IEC-62304": "Medical device software life cycle processes. Levels are software safety classes A to C.", + "EN-50128": "Railway applications software for railway control and protection systems. Levels are Software Safety Integrity Levels 0 to 4." + } + }, + { + "type": "object", + "title": "Custom Safety Scheme", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom scheme." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom scheme." + } + } + } + ] + }, + "level": { + "type": "string", + "minLength": 1, + "title": "Integrity Level", + "description": "The level within the scheme, using the designation the scheme defines. Lowercase kebab-case tokens are recommended so that levels compare reliably across documents.", + "examples": [ + "asil-d", + "sil-3", + "dal-a", + "class-c" + ] + } + } + }, "ownership": { "type": "array", "title": "Ownership", diff --git a/schema/2.0/model/cyclonedx-common-2.0.schema.json b/schema/2.0/model/cyclonedx-common-2.0.schema.json index 7c2e52305..d8d47eab6 100644 --- a/schema/2.0/model/cyclonedx-common-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-common-2.0.schema.json @@ -219,12 +219,16 @@ "threat-model", "adversary-model", "risk-assessment", + "hazard-analysis", + "safety-case", "vulnerability-assertion", "exploitability-statement", "pentest-report", "static-analysis-report", "dynamic-analysis-report", "runtime-analysis-report", + "test-report", + "incident-report", "component-analysis-report", "maturity-report", "certification-report", @@ -271,12 +275,16 @@ "threat-model": "An enumeration of identified weaknesses, threats, and countermeasures, dataflow diagram (DFD), attack tree, and other supporting documentation in human-readable or machine-readable format.", "adversary-model": "The defined assumptions, goals, and capabilities of an adversary.", "risk-assessment": "Identifies and analyzes the potential of future events that may negatively impact individuals, assets, and/or the environment. Risk assessments may also include judgments on the tolerability of each risk.", + "hazard-analysis": "A hazard analysis, such as a hazard analysis and risk assessment (HARA), a failure mode and effects analysis (FMEA), or a fault tree analysis (FTA).", + "safety-case": "A structured argument, supported by a body of evidence, that a system is acceptably safe for a given application in a given environment.", "vulnerability-assertion": "A Vulnerability Disclosure Report (VDR) which asserts the known and previously unknown vulnerabilities that affect a component, service, or product including the analysis and findings describing the impact (or lack of impact) that the reported vulnerability has on a component, service, or product.", "exploitability-statement": "A Vulnerability Exploitability eXchange (VEX) which asserts the known vulnerabilities that do not affect a product, product family, or organization, and optionally the ones that do. The VEX should include the analysis and findings describing the impact (or lack of impact) that the reported vulnerability has on the product, product family, or organization.", "pentest-report": "Results from an authorized simulated cyberattack on a component or service, otherwise known as a penetration test.", "static-analysis-report": "SARIF or proprietary machine or human-readable report for which static analysis has identified code quality, security, and other potential issues with the source code.", "dynamic-analysis-report": "Dynamic analysis report that has identified issues such as vulnerabilities and misconfigurations.", "runtime-analysis-report": "Report generated by analyzing the call stack of a running application.", + "test-report": "Results of testing, such as a laboratory test, a verification test, or a validation test, of a component, service, or system.", + "incident-report": "A report of an incident, such as a safety incident, a security incident, or an operational failure, and its investigation.", "component-analysis-report": "Report generated by Software Composition Analysis (SCA), container analysis, or other forms of component analysis.", "maturity-report": "Report containing a formal assessment of an organization, business unit, or team against a maturity model.", "certification-report": "Industry, regulatory, or other certification from an accredited (if applicable) certification body.", diff --git a/schema/2.0/model/cyclonedx-requirement-2.0.schema.json b/schema/2.0/model/cyclonedx-requirement-2.0.schema.json index de0b64357..2e3e6665a 100644 --- a/schema/2.0/model/cyclonedx-requirement-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-requirement-2.0.schema.json @@ -164,6 +164,7 @@ "privacy", "regulatory", "reliability", + "safety", "scalability", "security", "system", @@ -190,6 +191,7 @@ "privacy": "Requirements specifically addressing the handling and protection of personal and sensitive data.", "regulatory": "Requirements necessary for legal compliance, dictated by laws, regulations, or standards.", "reliability": "Requirements ensuring the system consistently performs under specified conditions and duration.", + "safety": "Requirements that address the prevention of harm to people, property, or the environment, such as functional safety requirements.", "scalability": "Requirements focused on the ability of the system to grow and manage increased demand effectively.", "security": "Requirements intended to protect systems, data, and users from malicious actions or threats.", "system": "Technical requirements defining infrastructure, architecture, or underlying technologies.", diff --git a/schema/2.0/model/cyclonedx-risk-2.0.schema.json b/schema/2.0/model/cyclonedx-risk-2.0.schema.json index f522fe517..dfcb2ed10 100644 --- a/schema/2.0/model/cyclonedx-risk-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-risk-2.0.schema.json @@ -260,6 +260,14 @@ }, "description": "References using bom-link or bom-ref to the weaknesses that inform this risk." }, + "relatedBehaviors": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the declared or observed behaviours that inform this risk. Any behaviour can give rise to a risk depending on context and expectation, for example an observed behaviour that defeats a declared safety behaviour." + }, "relatedRequirements": { "type": "array", "uniqueItems": true, @@ -1184,6 +1192,15 @@ "title": "Scope", "description": "The scope of the assessment, including the systems, boundaries, and what is in or out of scope." }, + "triggeredBy": { + "type": "array", + "title": "Triggered By", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the objects that occasioned this assessment, such as a vulnerability, a threat scenario, a component, a release note, or an annotation that records an incident or a change. Typically used when the cadence is triggered." + }, "status": { "title": "Status", "description": "The lifecycle status of the assessment. Use the custom option for a status specific to an organization's process.", @@ -1307,6 +1324,46 @@ }, "description": "The aggregated risk result for this assessment." }, + "conclusion": { + "title": "Conclusion", + "description": "The conclusion of the assessment for decision-making, such as a release decision. The conclusion states whether the assessed risks are acceptable against the applicable risk appetite, whereas `overallRisk` carries the aggregated score. Use the custom option for a conclusion specific to an organization's process.", + "oneOf": [ + { + "title": "Predefined Assessment Conclusion", + "enum": [ + "acceptable", + "unacceptable", + "inconclusive" + ], + "meta:enum": { + "acceptable": "The assessed risks are within the applicable risk appetite.", + "unacceptable": "One or more assessed risks exceed the applicable risk appetite.", + "inconclusive": "The assessment could not determine whether the assessed risks are within the applicable risk appetite, for example because evidence is incomplete." + } + }, + { + "title": "Custom Assessment Conclusion", + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom conclusion." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom conclusion." + } + } + } + ] + }, "assumptions": { "type": "array", "title": "Assumptions", diff --git a/tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json b/tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json new file mode 100644 index 000000000..f93337b9e --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Invalid: pass is not a predefined assessment conclusion; use acceptable, unacceptable, inconclusive, or a custom object.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "risks": { + "assessments": [ + { + "bom-ref": "a1", + "type": [ + "safety" + ], + "cadence": "triggered", + "timestamp": "2026-09-12T15:00:00Z", + "conclusion": "pass" + } + ] + } +} diff --git a/tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json b/tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json new file mode 100644 index 000000000..c175cba75 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Invalid: a safety integrity level requires both scheme and level; the level is missing.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "blueprints": [ + { + "bom-ref": "bp-vehicle", + "name": "Vehicle braking controller", + "modelTypes": [ + "architecture" + ], + "assets": [ + { + "bom-ref": "asset-brake-ecu", + "type": "device", + "name": "Brake ECU", + "classification": { + "safetyIntegrityLevels": [ + { + "scheme": "ISO-26262" + } + ] + } + } + ] + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json new file mode 100644 index 000000000..689c6ba22 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json @@ -0,0 +1,222 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Safety impact of a change trigger on a classified context. A vulnerability in a library (the trigger) is assessed for its safety impact on the pump's therapy path (the context, which carries a software safety class). The impact is a risk, the activity is a triggered assessment with a conclusion, and the evidence is a CDXA claim backed by an FMEA excerpt plus test and hazard analysis references.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:7a2b3c4d-5e6f-4a70-8b91-c2d3e4f5a6b7", + "version": 1, + "metadata": { + "timestamp": "2026-09-17T09:00:00Z" + }, + "components": [ + { + "bom-ref": "comp-pump-firmware", + "type": "firmware", + "name": "acme-pump-firmware", + "version": "3.2.0", + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-117" + } + ] + }, + { + "bom-ref": "comp-globex-tls", + "type": "library", + "name": "globex-tls", + "version": "1.4.2" + } + ], + "dependencies": [ + { + "ref": "comp-pump-firmware", + "dependsOn": [ + "comp-globex-tls" + ] + } + ], + "blueprints": [ + { + "bom-ref": "bp-pump-deployment", + "name": "Infusion pump, hospital deployment", + "modelTypes": [ + "data-flow" + ], + "assets": [ + { + "bom-ref": "asset-tls-path", + "componentRef": "comp-globex-tls", + "classification": { + "criticality": "critical", + "safetyIntegrityLevels": [ + { + "scheme": "IEC-62304", + "level": "class-c" + } + ] + } + } + ] + } + ], + "vulnerabilities": [ + { + "bom-ref": "vuln-globex-tls-1", + "id": "GLOBEX-2026-0007", + "description": "Certificate name confusion in the Globex TLS library.", + "ratings": [ + { + "method": "CVSSv31", + "score": 7.4, + "severity": "high", + "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H" + } + ], + "analysis": { + "state": "not_affected", + "justification": "requires_configuration", + "detail": "The pump pins the gateway certificate, so name confusion is not reachable. Safety impact assessed separately, see the triggered assessment.", + "firstIssued": "2026-09-10T00:00:00Z" + }, + "affects": [ + { + "ref": "comp-globex-tls" + } + ] + } + ], + "declarations": { + "claims": [ + { + "bom-ref": "claim-tls-fmea", + "target": "asset-tls-path", + "predicate": "The vulnerability introduces no new hazardous failure mode on the therapy command path.", + "reasoning": "FMEA rows for the TLS path were re-evaluated with the vulnerability as a new cause; the existing certificate pinning control keeps the failure mode undetected-tampering at its assessed occurrence.", + "evidence": [ + "evidence-fmea-excerpt" + ] + } + ], + "evidence": [ + { + "bom-ref": "evidence-fmea-excerpt", + "description": "FMEA excerpt for the TLS communication path, re-evaluated for GLOBEX-2026-0007.", + "data": [ + { + "name": "FMEA-2026-117 rows 14 to 19", + "contents": { + "attachment": { + "mediaType": "text/plain", + "content": "Row 14: undetected command tampering; cause: TLS name confusion; control: certificate pinning; occurrence 2; severity 9; detection 3." + } + } + } + ], + "created": "2026-09-12T00:00:00Z", + "author": { + "name": "Dana Whitfield" + } + } + ] + }, + "risks": { + "risks": [ + { + "bom-ref": "risk-tls-vuln-safety", + "name": "Vulnerability GLOBEX-2026-0007 on the therapy command path", + "statement": "If the certificate name confusion were exploitable on the pump, therapy commands could be tampered with, causing incorrect drug delivery.", + "domains": [ + { + "type": "safety" + } + ], + "affects": [ + "asset-tls-path", + "comp-pump-firmware" + ], + "relatedVulnerabilities": [ + "vuln-globex-tls-1" + ], + "relatedClaims": [ + "claim-tls-fmea" + ], + "inherentRisk": { + "likelihood": { + "level": "low" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety", + "integrity" + ], + "description": "Incorrect drug delivery to a patient." + } + }, + "residualRisk": { + "likelihood": { + "level": "very-low" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety", + "integrity" + ] + }, + "rationale": "Certificate pinning makes the vulnerability unreachable in the deployed configuration." + }, + "status": "assessed" + } + ], + "assessments": [ + { + "bom-ref": "assessment-2026-09-12", + "name": "Safety impact reassessment for GLOBEX-2026-0007", + "type": [ + "safety", + "vulnerability" + ], + "cadence": "triggered", + "triggeredBy": [ + "vuln-globex-tls-1" + ], + "timestamp": "2026-09-12T15:00:00Z", + "status": "approved", + "scope": "The pump firmware 3.2.0 therapy command path in the hospital deployment blueprint.", + "assessors": [ + { + "roles": [ + { + "role": "auditor" + } + ], + "organization": { + "name": "Acme Medical Systems" + } + } + ], + "risks": [ + "risk-tls-vuln-safety" + ], + "conclusion": "acceptable", + "summary": "No new hazardous failure mode. Release 3.2.1 may proceed without a safety-driven change; the library update is scheduled for 3.3.", + "nextReview": "2026-12-12T00:00:00Z", + "externalReferences": [ + { + "type": "test-report", + "url": "https://plm.acme-medical.example/tests/TR-2026-0412", + "comment": "Certificate pinning regression test against the vulnerable library version." + }, + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-117" + } + ] + } + ] + } +} diff --git a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json new file mode 100644 index 000000000..3a6f97c20 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json @@ -0,0 +1,184 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "A behavior as the cause of a safety impact. The dosing controller declares the safety-relevant behavior enforcesOperatingLimits from the behavior taxonomy. Runtime monitoring observes a second behavior, suppressesError, on the same controller. A threat names the observed behavior as its intent, a risk states the safety consequence for the classified asset, and a triggered assessment records the verdict. The risk names the behavior directly through relatedBehaviors and the threat through relatedThreats; the assessment is triggered by the behavior. The chain is behavior, then threat, then risk, then assessment.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:9c8d7e6f-5a4b-4c3d-8e2f-1a0b9c8d7e6f", + "version": 1, + "metadata": { + "timestamp": "2026-09-18T09:00:00Z" + }, + "components": [ + { + "bom-ref": "comp-dosing-controller", + "type": "firmware", + "name": "acme-dosing-controller", + "version": "2.7.0" + }, + { + "bom-ref": "comp-runtime-monitor", + "type": "application", + "name": "globex-runtime-monitor", + "version": "5.1.3" + } + ], + "blueprints": [ + { + "bom-ref": "bp-pump", + "name": "Infusion pump, dosing path", + "modelTypes": [ + "behavioral" + ], + "assets": [ + { + "bom-ref": "asset-dosing-controller", + "componentRef": "comp-dosing-controller", + "classification": { + "criticality": "critical", + "safetyIntegrityLevels": [ + { + "scheme": "IEC-62304", + "level": "class-c" + } + ] + } + } + ], + "behaviors": { + "instances": [ + { + "bom-ref": "bi-enforces-limits", + "behavior": "safety:operationalSafety:enforcesOperatingLimits", + "acknowledgment": [ + "declared" + ], + "trigger": "continuous", + "actors": [ + "asset-dosing-controller" + ] + }, + { + "bom-ref": "bi-suppresses-error", + "behavior": "security:errorHandling:suppressesError", + "acknowledgment": [ + "observed" + ], + "trigger": "condition-based", + "actors": [ + "asset-dosing-controller" + ], + "targets": [ + "bi-enforces-limits" + ] + } + ] + } + } + ], + "threats": { + "threats": [ + { + "bom-ref": "threat-silent-limit-failure", + "name": "Silent failure of operating limit enforcement", + "description": "The controller suppresses the error raised when a dose exceeds its operating limit, so the limit check can fail without an alarm.", + "origin": "structural", + "behaviors": [ + "bi-suppresses-error" + ], + "affectedAssets": [ + "asset-dosing-controller" + ] + } + ], + "scenarios": [ + { + "bom-ref": "ts-overdose-unalarmed", + "name": "Over-limit dose delivered without alarm", + "threats": [ + "threat-silent-limit-failure" + ], + "affectedAssets": [ + "asset-dosing-controller" + ], + "relatedRisks": [ + "risk-overdose" + ] + } + ] + }, + "risks": { + "risks": [ + { + "bom-ref": "risk-overdose", + "name": "Over-limit dose delivered without alarm", + "statement": "If the controller suppresses the operating limit error, an over-limit dose can be delivered to a patient without an alarm.", + "domains": [ + { + "type": "safety" + } + ], + "affects": [ + "asset-dosing-controller" + ], + "relatedThreats": [ + "ts-overdose-unalarmed" + ], + "relatedBehaviors": [ + "bi-suppresses-error" + ], + "inherentRisk": { + "likelihood": { + "level": "medium" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety" + ], + "description": "Patient overdose." + } + }, + "status": "assessed" + } + ], + "assessments": [ + { + "bom-ref": "assessment-2026-09-15", + "name": "Safety impact assessment of observed error suppression", + "type": [ + "safety" + ], + "cadence": "triggered", + "triggeredBy": [ + "bi-suppresses-error" + ], + "timestamp": "2026-09-15T14:00:00Z", + "status": "completed", + "assessors": [ + { + "roles": [ + { + "role": "auditor" + } + ], + "organization": { + "name": "Acme Medical Systems" + } + } + ], + "risks": [ + "risk-overdose" + ], + "conclusion": "unacceptable", + "summary": "Observed behavior defeats a declared safety behavior on a class C context. Release blocked until the error path is restored and re-tested.", + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-131" + } + ] + } + ] + } +} From de22e2cb2f28a79625f1cdb680c54351201bf5f4 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 20 Sep 2026 20:48:53 -0500 Subject: [PATCH 2/7] feat: damage scenarios and impact methodology (ISO/SAE 21434, RDX alignment). Added test cases. Signed-off-by: Steve Springett --- .../2.0/model/cyclonedx-risk-2.0.schema.json | 165 +++++++++---- .../model/cyclonedx-threat-2.0.schema.json | 9 + ...d-risk-damage-scenario-no-impacts-2.0.json | 15 ++ .../2.0/valid-risk-damage-scenario-2.0.json | 223 ++++++++++++++++++ 4 files changed, 367 insertions(+), 45 deletions(-) create mode 100644 tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json diff --git a/schema/2.0/model/cyclonedx-risk-2.0.schema.json b/schema/2.0/model/cyclonedx-risk-2.0.schema.json index dfcb2ed10..23d7b404a 100644 --- a/schema/2.0/model/cyclonedx-risk-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-risk-2.0.schema.json @@ -20,6 +20,15 @@ }, "description": "The documented risks identified through risk analysis." }, + "damageScenarios": { + "type": "array", + "title": "Damage Scenarios", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/damageScenario" + }, + "description": "The damage scenarios identified through risk analysis. A damage scenario describes an adverse consequence for the subjects it affects, independent of any particular cause, and is rated per impact category." + }, "assessments": { "type": "array", "title": "Assessments", @@ -244,6 +253,14 @@ }, "description": "References using bom-link or bom-ref to the threats or threat scenarios from a threat model that inform this risk. A reference may point to a discrete threat or to a threat scenario." }, + "relatedDamageScenarios": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the damage scenarios that this risk realizes. A risk typically pairs a threat scenario, which supplies the likelihood, with a damage scenario, which supplies the impact." + }, "relatedVulnerabilities": { "type": "array", "uniqueItems": true, @@ -679,6 +696,10 @@ "description": { "type": "string", "description": "A description of the potential impact." + }, + "methodology": { + "$ref": "#/$defs/riskMethodology", + "description": "The methodology used to derive this impact rating, where the impact is rated on its own, for example on a damage scenario before any risk is scored." } } }, @@ -894,54 +915,58 @@ "description": "A textual representation of the metric values used to derive the score, in the format defined by the methodology." }, "methodology": { - "title": "Methodology", - "description": "The risk rating methodology used to derive this score. Only methodologies that define a scoring calculation are listed; governance frameworks such as [ISO 31000](https://www.iso.org/iso-31000-risk-management.html) are recorded as standards rather than as a score methodology. Use the custom option for methodologies not listed.", - "oneOf": [ - { - "title": "Predefined Risk Methodology", - "enum": [ - "dread", - "fair", - "fmea", - "nist-sp-800-30", - "octave", - "owasp-risk-rating", - "qualitative-matrix" - ], - "meta:enum": { - "dread": "[DREAD](https://en.wikipedia.org/wiki/DREAD_%28risk_assessment_model%29) risk rating model, the average of five ratings (damage, reproducibility, exploitability, affected users, discoverability) each scored 1 to 10.", - "fair": "[Factor Analysis of Information Risk (FAIR)](https://www.fairinstitute.org/), a quantitative methodology expressing risk as loss event frequency multiplied by loss magnitude.", - "fmea": "[Failure Mode and Effects Analysis (FMEA)](https://asq.org/quality-resources/fmea), using a risk priority number of severity multiplied by occurrence multiplied by detection.", - "nist-sp-800-30": "[NIST SP 800-30](https://csrc.nist.gov/pubs/sp/800/30/r1/final) guide for conducting risk assessments, using its exemplary likelihood and impact scales.", - "octave": "[OCTAVE Allegro](https://www.sei.cmu.edu/documents/786/2007_005_001_14885.pdf), using its relative risk score.", - "owasp-risk-rating": "[OWASP Risk Rating](https://owasp.org/www-community/OWASP_Risk_Rating_Methodology), averaging likelihood and impact factors each scored 0 to 9.", - "qualitative-matrix": "A qualitative risk matrix that derives a risk level by plotting a likelihood band against an impact band, such as a five by five matrix producing a score from 1 to 25." - } + "$ref": "#/$defs/riskMethodology", + "description": "The risk rating methodology used to derive this score. Only methodologies that define a scoring calculation are listed; governance frameworks such as [ISO 31000](https://www.iso.org/iso-31000-risk-management.html) are recorded as standards rather than as a score methodology. Use the custom option for methodologies not listed." + } + } + }, + "riskMethodology": { + "title": "Risk Methodology", + "description": "A risk rating methodology that defines a scoring calculation. Use the custom option for methodologies not listed.", + "oneOf": [ + { + "title": "Predefined Risk Methodology", + "enum": [ + "dread", + "fair", + "fmea", + "nist-sp-800-30", + "octave", + "owasp-risk-rating", + "qualitative-matrix" + ], + "meta:enum": { + "dread": "[DREAD](https://en.wikipedia.org/wiki/DREAD_%28risk_assessment_model%29) risk rating model, the average of five ratings (damage, reproducibility, exploitability, affected users, discoverability) each scored 1 to 10.", + "fair": "[Factor Analysis of Information Risk (FAIR)](https://www.fairinstitute.org/), a quantitative methodology expressing risk as loss event frequency multiplied by loss magnitude.", + "fmea": "[Failure Mode and Effects Analysis (FMEA)](https://asq.org/quality-resources/fmea), using a risk priority number of severity multiplied by occurrence multiplied by detection.", + "nist-sp-800-30": "[NIST SP 800-30](https://csrc.nist.gov/pubs/sp/800/30/r1/final) guide for conducting risk assessments, using its exemplary likelihood and impact scales.", + "octave": "[OCTAVE Allegro](https://www.sei.cmu.edu/documents/786/2007_005_001_14885.pdf), using its relative risk score.", + "owasp-risk-rating": "[OWASP Risk Rating](https://owasp.org/www-community/OWASP_Risk_Rating_Methodology), averaging likelihood and impact factors each scored 0 to 9.", + "qualitative-matrix": "A qualitative risk matrix that derives a risk level by plotting a likelihood band against an impact band, such as a five by five matrix producing a score from 1 to 25." + } + }, + { + "title": "Custom Risk Methodology", + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom risk methodology." }, - { - "title": "Custom Risk Methodology", - "type": "object", - "required": [ - "name" - ], - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "title": "Name", - "description": "The name of the custom risk methodology." - }, - "description": { - "type": "string", - "title": "Description", - "description": "A description of the custom risk methodology." - } - } + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom risk methodology." } - ] + } } - } + ] }, "riskResponse": { "type": "object", @@ -1047,6 +1072,56 @@ } } }, + "damageScenario": { + "type": "object", + "title": "Damage Scenario", + "description": "An adverse consequence for one or more subjects, described independently of the threat or event that could cause it. A damage scenario carries an impact per category, such as safety, financial, operational, or privacy, so that the same consequence can be paired with several causes. In ISO/SAE 21434 terms, for example, the damage scenario is the harm to a road user, the threat scenario is the cause, and the risk pairs the two.", + "required": [ + "bom-ref", + "name" + ], + "additionalProperties": false, + "properties": { + "bom-ref": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "A short name for the damage scenario." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the adverse consequence and the circumstances in which it occurs." + }, + "affects": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the subjects harmed in this damage scenario, such as the functions, assets, or components involved and the parties harmed, for example a road user or a patient." + }, + "impacts": { + "type": "array", + "title": "Impacts", + "uniqueItems": true, + "minItems": 1, + "items": { + "$ref": "#/$defs/impact" + }, + "description": "The impact of the damage scenario, one entry per impact category or group of categories, each with its own level. For example, a single damage scenario may be catastrophic for safety and moderate for finance." + }, + "externalReferences": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" + }, + "properties": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" + } + } + }, "assessment": { "type": "object", "required": [ diff --git a/schema/2.0/model/cyclonedx-threat-2.0.schema.json b/schema/2.0/model/cyclonedx-threat-2.0.schema.json index 5dc6b3404..3f064fc8c 100644 --- a/schema/2.0/model/cyclonedx-threat-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-threat-2.0.schema.json @@ -560,6 +560,15 @@ }, "description": "References using bom-link or bom-ref to the assets affected in this scenario." }, + "damageScenarios": { + "type": "array", + "title": "Damage Scenarios", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the damage scenarios, declared under the risks collection, that this scenario can lead to." + }, "relatedRisks": { "type": "array", "title": "Related Risks", diff --git a/tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json b/tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json new file mode 100644 index 000000000..03f0127c5 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Invalid: a damage scenario that carries impacts requires at least one impact.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "risks": { + "damageScenarios": [ + { + "bom-ref": "ds-1", + "name": "No impact given", + "impacts": [] + } + ] + } +} diff --git a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json new file mode 100644 index 000000000..2d1f48ce7 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json @@ -0,0 +1,223 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Damage scenario, threat scenario, and risk, in the ISO/SAE 21434 shape as carried by RDX. The damage scenario is the consequence with an impact per category; the threat scenario is the cause and names the damage scenarios it can lead to; the risk pairs the two and carries the rating. The light controller asset carries an ASIL so the safety significance of the context is explicit.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3b4c5d6e-7f80-4a91-b2c3-d4e5f6a7b8c9", + "version": 1, + "metadata": { + "timestamp": "2026-09-20T10:00:00Z" + }, + "components": [ + { + "bom-ref": "comp-light-controller", + "type": "firmware", + "name": "acme-light-controller", + "version": "4.2.0" + } + ], + "blueprints": [ + { + "bom-ref": "bp-headlamp", + "name": "Adaptive headlamp system", + "modelTypes": [ + "architecture" + ], + "assets": [ + { + "bom-ref": "asset-light-control", + "componentRef": "comp-light-controller", + "classification": { + "criticality": "high", + "safetyIntegrityLevels": [ + { + "scheme": "ISO-26262", + "level": "asil-b" + } + ] + } + }, + { + "bom-ref": "asset-fn-glare-free", + "type": "function", + "name": "Glare-free high beam" + } + ], + "actors": [ + { + "bom-ref": "actor-oncoming-driver", + "party": { + "roles": [ + { + "role": "subject" + } + ], + "persona": { + "archetype": { + "name": "road-user", + "description": "A person on or near the road who is exposed to the vehicle's behaviour." + }, + "description": "Oncoming driver." + } + }, + "description": "A driver of an oncoming vehicle exposed to the headlamp output." + } + ] + } + ], + "threats": { + "threats": [ + { + "bom-ref": "threat-can-spoof", + "name": "Spoofed light control message on the body CAN", + "origin": "adversarial", + "categories": [ + { + "taxonomy": "STRIDE", + "category": "spoofing" + } + ], + "affectedAssets": [ + "asset-light-control" + ] + } + ], + "scenarios": [ + { + "bom-ref": "ts-can-spoof", + "name": "Attacker injects light control frames from a compromised body ECU", + "threats": [ + "threat-can-spoof" + ], + "attackVector": { + "type": "adjacent", + "complexity": "low", + "privileges": "low", + "userInteraction": "none" + }, + "likelihood": { + "level": "medium", + "rationale": "Attack feasibility rated medium: hours of elapsed time, proficient expertise, public CAN knowledge, standard equipment." + }, + "affectedAssets": [ + "asset-light-control" + ], + "damageScenarios": [ + "ds-road-users-blinded" + ], + "relatedRisks": [ + "risk-can-spoof-blinding" + ] + } + ] + }, + "risks": { + "damageScenarios": [ + { + "bom-ref": "ds-road-users-blinded", + "name": "Driver or other road users blinded", + "description": "Incorrect headlamp operation causes loss of visibility for the driver or glare for oncoming traffic, leading to a collision.", + "affects": [ + "asset-fn-glare-free", + "asset-light-control", + "actor-oncoming-driver" + ], + "impacts": [ + { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety" + ], + "description": "Loss of visibility at speed can cause a fatal collision. Severe on the ISO/SAE 21434 scale.", + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15.5 impact rating." + } + }, + { + "level": "major", + "polarity": "harm", + "categories": [ + "operational" + ], + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15.5 impact rating." + } + }, + { + "level": "moderate", + "polarity": "harm", + "categories": [ + "financial" + ], + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15.5 impact rating." + } + } + ], + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-automotive.example/hara/HL-2026-004" + } + ] + } + ], + "risks": [ + { + "bom-ref": "risk-can-spoof-blinding", + "name": "CAN spoofing leads to road users blinded", + "statement": "If an attacker injects light control frames on the body CAN, the headlamps can be driven to blind the driver or oncoming traffic.", + "domains": [ + { + "type": "safety" + }, + { + "type": "security" + } + ], + "affects": [ + "asset-light-control" + ], + "relatedThreats": [ + "ts-can-spoof" + ], + "relatedDamageScenarios": [ + "ds-road-users-blinded" + ], + "inherentRisk": { + "likelihood": { + "level": "medium" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety" + ] + }, + "score": { + "level": "high", + "score": 4, + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15 risk value from impact rating and attack feasibility rating." + } + }, + "rationale": "Medium feasibility combined with severe safety impact." + }, + "responses": [ + { + "bom-ref": "resp-can-auth", + "strategy": "reduce", + "description": "Authenticate light control frames and rate-limit diagnostic writes." + } + ], + "status": "assessed" + } + ] + } +} From 78f96fee673c1965ffcc856df9a208ddf6c36306 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 20 Sep 2026 21:35:07 -0500 Subject: [PATCH 3/7] refactor: align threat and risk models with ISO 31000, ISO/SAE 21434, and ISO 26262 Threat scenarios carry feasibility only, risks pair them with damage scenarios and reference one way, and naming, statuses, and scales are now unified across the two models. Signed-off-by: Steve Springett --- .../model/cyclonedx-blueprint-2.0.schema.json | 9 +++ .../2.0/model/cyclonedx-risk-2.0.schema.json | 65 +++++++++++------- .../model/cyclonedx-threat-2.0.schema.json | 68 +++++-------------- ...nvalid-threatmodel-missing-bomref-2.0.json | 2 +- .../2.0/valid-risk-damage-scenario-2.0.json | 41 ++++++++--- .../valid-safety-impact-assessment-2.0.json | 12 ++-- .../2.0/valid-safety-impact-behavior-2.0.json | 9 +-- .../2.0/valid-threatmodel-simple-2.0.json | 9 +-- 8 files changed, 114 insertions(+), 101 deletions(-) diff --git a/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json b/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json index 55b6495a0..96dd6f54b 100644 --- a/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-blueprint-2.0.schema.json @@ -1919,6 +1919,15 @@ }, "description": "The safety integrity classifications of this asset in the context of the blueprint. An asset may carry classifications from more than one scheme, for example where an element classified under IEC 61508 is also mapped to an automotive ASIL. The classification identifies the safety significance of the context so that the impact of a change on it can be assessed." }, + "riskAttributes": { + "type": "array", + "title": "Risk Attributes", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/riskAttribute" + }, + "description": "The security and privacy attributes of this asset that are worth protecting, such as integrity or availability, whose compromise leads to damage. Corresponds to the cybersecurity properties of an asset in ISO/SAE 21434 and to the security objectives of FIPS 199." + }, "classification": { "$ref": "cyclonedx-data-2.0.schema.json#/$defs/dataClassification" }, diff --git a/schema/2.0/model/cyclonedx-risk-2.0.schema.json b/schema/2.0/model/cyclonedx-risk-2.0.schema.json index 23d7b404a..3554bf2c8 100644 --- a/schema/2.0/model/cyclonedx-risk-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-risk-2.0.schema.json @@ -70,9 +70,9 @@ "privacy", "operational", "financial", - "compliance", + "regulatory", "strategic", - "reputational", + "reputation", "safety", "environmental", "supply-chain", @@ -89,9 +89,9 @@ "privacy": "Data protection and privacy risks.", "operational": "Business operations and continuity risks.", "financial": "Financial loss and economic impact risks.", - "compliance": "Regulatory and legal compliance risks.", + "regulatory": "Regulatory and legal compliance risks.", "strategic": "Strategic business and market risks.", - "reputational": "Brand and reputation damage risks.", + "reputation": "Brand and reputation damage risks.", "safety": "Human safety and physical security risks.", "environmental": "Environmental impact and sustainability risks.", "supply-chain": "Supply chain and third-party risks.", @@ -338,24 +338,22 @@ }, "status": { "title": "Status", - "description": "The lifecycle status of the risk. Use the custom option for a status specific to an organization's risk process.", + "description": "The lifecycle status of the risk. The status tracks progress through the risk process; the disposition chosen, such as reduce, share, or accept, is recorded on the responses. Use the custom option for a status specific to an organization's risk process.", "oneOf": [ { "title": "Predefined Risk Status", "enum": [ "identified", "assessed", - "mitigated", - "accepted", - "transferred", + "treated", + "monitored", "retired" ], "meta:enum": { - "identified": "Risk has been identified but not yet evaluated.", - "assessed": "Risk has been assessed and prioritized.", - "mitigated": "Responses are in place reducing this risk.", - "accepted": "Risk has been formally accepted.", - "transferred": "Risk has been transferred to another party.", + "identified": "The risk has been identified and recorded.", + "assessed": "The risk has been analysed and rated.", + "treated": "Responses to the risk have been decided and are being applied. The disposition, such as reduce or accept, is recorded on the responses.", + "monitored": "The risk and its responses are under ongoing monitoring and review.", "retired": "Risk no longer applies." } }, @@ -423,6 +421,23 @@ } } }, + "controllability": { + "type": "object", + "title": "Controllability", + "additionalProperties": false, + "description": "The ability of the people involved to avoid the harm once the event occurs, used as a third axis by functional safety methodologies such as the hazard analysis and risk assessment of [ISO 26262](https://www.iso.org/standard/68383.html), which derives an integrity level from severity, exposure, and controllability.", + "properties": { + "score": { + "type": "number", + "minimum": 0, + "description": "The controllability value on the scale defined by the methodology. For ISO 26262, a higher class indicates that the harm is harder to avoid." + }, + "description": { + "type": "string", + "description": "A narrative explanation of the controllability assessment." + } + } + }, "confidence": { "type": "number", "minimum": 0, @@ -532,8 +547,11 @@ "control-effectiveness", "detectability", "discoverability", + "elapsed-time", + "equipment", "exploit-maturity", "exposure", + "knowledge", "motivation", "opportunity", "targeting", @@ -546,8 +564,11 @@ "control-effectiveness": "Strength, reliability, and coverage of existing preventive, detective, or corrective controls that reduce the probability of successful exploitation. Corresponds to resistance strength in FAIR.", "detectability": "Likelihood that the activity is detected before the risk is realized. Lower detectability increases the chance of a successful action. Aligns with the OWASP Risk Rating intrusion detection factor and the FMEA detection axis.", "discoverability": "Ease with which the weakness or opportunity can be found by a potential actor. Aligns with the OWASP Risk Rating ease of discovery factor.", + "elapsed-time": "The time an attacker needs to identify and exploit the weakness, one of the attack potential factors of [ISO/IEC 18045](https://www.iso.org/standard/72889.html) used by attack feasibility ratings such as ISO/SAE 21434.", + "equipment": "The equipment an attacker needs, from standard to bespoke, one of the attack potential factors of [ISO/IEC 18045](https://www.iso.org/standard/72889.html).", "exploit-maturity": "Availability, reliability, and sophistication of known exploits, attack toolkits, or proof-of-concept code targeting the identified weakness.", "exposure": "Degree to which the target asset, system, or service is visible, discoverable, or reachable by potential threat actors.", + "knowledge": "The knowledge of the target an attacker needs, from public to critical, one of the attack potential factors of [ISO/IEC 18045](https://www.iso.org/standard/72889.html).", "motivation": "Level of incentive, intent, or determination driving the threat actor to pursue exploitation, including financial gain, ideology, or competitive advantage.", "opportunity": "Availability of the conditions, timing, or circumstances required for the threat actor to act, including access windows, environmental factors, and resource availability.", "targeting": "Degree to which the threat actor specifically selects this asset or organization rather than acting opportunistically. Aligns with the NIST SP 800-30 targeting factor.", @@ -705,14 +726,11 @@ }, "impactCategory": { "title": "Impact Category", - "description": "A category of impact, including harms relevant to AI and societal risk. Use the custom option for categories specific to an organization's risk taxonomy.", + "description": "A category of impact, including harms relevant to AI and societal risk. The security and privacy attributes compromised, such as confidentiality or integrity, are recorded as risk attributes rather than as impact categories. Use the custom option for categories specific to an organization's risk taxonomy.", "oneOf": [ { "title": "Predefined Impact Category", "enum": [ - "confidentiality", - "integrity", - "availability", "financial", "reputation", "regulatory", @@ -731,9 +749,6 @@ "health" ], "meta:enum": { - "confidentiality": "Impact on data confidentiality.", - "integrity": "Impact on data or system integrity.", - "availability": "Impact on service availability.", "financial": "Financial loss or impact.", "reputation": "Reputational damage.", "regulatory": "Regulatory compliance impact.", @@ -890,7 +905,7 @@ "properties": { "level": { "enum": [ - "info", + "negligible", "low", "medium", "high", @@ -898,7 +913,7 @@ ], "description": "The overall qualitative risk level.", "meta:enum": { - "info": "Informational.", + "negligible": "Negligible risk.", "low": "Low risk.", "medium": "Medium risk.", "high": "High risk.", @@ -988,7 +1003,7 @@ "enum": [ "avoid", "reduce", - "transfer", + "share", "accept", "exploit", "enhance" @@ -996,7 +1011,7 @@ "meta:enum": { "avoid": "Eliminate the risk by removing its source or not proceeding with the activity.", "reduce": "Lower the likelihood or impact of the risk through controls.", - "transfer": "Shift the risk to another party, for example through insurance or contract.", + "share": "Share the risk with another party, for example through insurance, contract, or outsourcing. Some frameworks call this transfer.", "accept": "Take no further action and retain the risk.", "exploit": "Pursue an opportunity so that a positive risk occurs.", "enhance": "Increase the likelihood or benefit of a positive risk." @@ -1013,7 +1028,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls that implement this response." + "description": "References using bom-link or bom-ref to the controls that implement this response. Where a control is declared in the same document, its appliesTo property may also record the relationship." }, "status": { "title": "Status", diff --git a/schema/2.0/model/cyclonedx-threat-2.0.schema.json b/schema/2.0/model/cyclonedx-threat-2.0.schema.json index 3f064fc8c..b648110ac 100644 --- a/schema/2.0/model/cyclonedx-threat-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-threat-2.0.schema.json @@ -8,7 +8,7 @@ "threats": { "type": "object", "title": "Threats", - "description": "Threat-modelling content, including the documented threats, the scenarios that realize them, the attack patterns and attack trees that describe how they are carried out, and the trust boundaries they cross.", + "description": "Threat-modelling content, including the documented threats, the threat scenarios that realize them, the attack patterns and attack trees that describe how they are carried out, and the trust boundaries they cross. Control references throughout this model point at controls that mitigate the referencing element. Where a control is declared in the same document, its appliesTo property may also record the relationship; the reference here is intended primarily for controls defined elsewhere.", "additionalProperties": false, "properties": { "threats": { @@ -20,9 +20,9 @@ }, "description": "The documented threats. Each describes what can go wrong, independent of any specific actor or occurrence." }, - "scenarios": { + "threatScenarios": { "type": "array", - "title": "Scenarios", + "title": "Threat Scenarios", "uniqueItems": true, "items": { "$ref": "#/$defs/threatScenario" @@ -36,7 +36,7 @@ "items": { "$ref": "#/$defs/attackPattern" }, - "description": "A library of attack patterns, typically aligned with CAPEC, that threats and scenarios can reference." + "description": "A library of attack patterns, typically aligned with CAPEC, that threats and threat scenarios can reference." }, "attackTrees": { "type": "array", @@ -379,14 +379,14 @@ "indicators": { "$ref": "#/$defs/indicators" }, - "affectedAssets": { + "affects": { "type": "array", - "title": "Affected Assets", + "title": "Affects", "uniqueItems": true, "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the kinds of assets this threat affects." + "description": "References using bom-link or bom-ref to the assets that this threat can affect." }, "relatedBusinessObjectives": { "type": "array", @@ -416,7 +416,7 @@ "threatScenario": { "type": "object", "title": "Threat Scenario", - "description": "A specific realization of a threat, in which an actor seeks to cause harm. The scenario references the threat it realizes, supplies the actor by reference to a party, and carries the scenario-specific traits and risk assessment, such as motivation, intent, access level, likelihood, and impact.", + "description": "A specific realization of a threat, in which an actor seeks to cause harm. The scenario references the threats it realizes, supplies the actor by reference to a party, and carries the scenario-specific traits, such as motivation, intent, access level, and likelihood. The consequence is expressed by the damage scenarios it leads to, and the resulting risk is documented under risks, referencing both.", "additionalProperties": false, "required": [ "bom-ref", @@ -534,13 +534,8 @@ "$ref": "#/$defs/exploitability" }, "likelihood": { - "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/likelihood" - }, - "impact": { - "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/impact" - }, - "riskScore": { - "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/riskScore" + "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/likelihood", + "description": "The likelihood that this scenario is realized, which in attack terms is its feasibility. The consequence is carried by the damage scenarios the scenario leads to, and the paired rating by the risk that references both." }, "riskAttributes": { "type": "array", @@ -551,9 +546,9 @@ }, "description": "The security and privacy attributes that this threat would compromise if realized." }, - "affectedAssets": { + "affects": { "type": "array", - "title": "Affected Assets", + "title": "Affects", "uniqueItems": true, "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" @@ -569,15 +564,6 @@ }, "description": "References using bom-link or bom-ref to the damage scenarios, declared under the risks collection, that this scenario can lead to." }, - "relatedRisks": { - "type": "array", - "title": "Related Risks", - "uniqueItems": true, - "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" - }, - "description": "References using bom-link or bom-ref to the risks that this scenario contributes to." - }, "relatedVulnerabilities": { "type": "array", "uniqueItems": true, @@ -989,7 +975,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls that mitigate this node." + "description": "References using bom-link or bom-ref to the controls that mitigate this attack tree node." } } }, @@ -1085,20 +1071,8 @@ "additionalProperties": false, "properties": { "level": { - "title": "Level", - "description": "The maturity of available exploitation capability.", - "enum": [ - "theoretical", - "proof-of-concept", - "functional", - "weaponized" - ], - "meta:enum": { - "theoretical": "Exploitation is theoretically possible but has not been demonstrated.", - "proof-of-concept": "A proof of concept exists.", - "functional": "A functional exploit exists.", - "weaponized": "A weaponized exploit is in use." - } + "$ref": "cyclonedx-vulnerability-2.0.schema.json#/$defs/exploitMaturity", + "description": "The maturity of available exploitation capability, using the same scale as vulnerability exploit maturity." }, "complexity": { "title": "Complexity", @@ -1293,7 +1267,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls in place at this boundary. Intended primarily for referencing externally defined controls. Where the control and boundary are declared together, prefer the control's appliesTo property." + "description": "References using bom-link or bom-ref to the controls that mitigate threats at this trust boundary." }, "properties": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" @@ -1383,7 +1357,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls that detect or prevent this step." + "description": "References using bom-link or bom-ref to the controls that mitigate this attack path step, by preventing or detecting it." }, "properties": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" @@ -1441,14 +1415,6 @@ }, "description": "References using bom-link or bom-ref to the threats that this path realizes." }, - "relatedRisks": { - "type": "array", - "uniqueItems": true, - "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" - }, - "description": "References using bom-link or bom-ref to the risks that this path contributes to." - }, "externalReferences": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" }, diff --git a/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json b/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json index 49e07bb83..0a0fdf7d8 100644 --- a/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json +++ b/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json @@ -2,7 +2,7 @@ "specFormat": "CycloneDX", "specVersion": "2.0", "threats": { - "scenarios": [ + "threatScenarios": [ { "name": "Scenario missing its required bom-ref", "threats": [ diff --git a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json index 2d1f48ce7..5e0e01c9c 100644 --- a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json +++ b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json @@ -34,6 +34,10 @@ "scheme": "ISO-26262", "level": "asil-b" } + ], + "riskAttributes": [ + "integrity", + "availability" ] } }, @@ -77,12 +81,12 @@ "category": "spoofing" } ], - "affectedAssets": [ + "affects": [ "asset-light-control" ] } ], - "scenarios": [ + "threatScenarios": [ { "bom-ref": "ts-can-spoof", "name": "Attacker injects light control frames from a compromised body ECU", @@ -97,16 +101,33 @@ }, "likelihood": { "level": "medium", - "rationale": "Attack feasibility rated medium: hours of elapsed time, proficient expertise, public CAN knowledge, standard equipment." + "rationale": "Attack feasibility rated medium: hours of elapsed time, proficient expertise, public CAN knowledge, standard equipment.", + "factors": [ + { + "name": "Elapsed time", + "type": "elapsed-time", + "level": "medium", + "description": "Hours." + }, + { + "name": "Knowledge of the item", + "type": "knowledge", + "level": "low", + "description": "Public CAN protocol knowledge." + }, + { + "name": "Equipment", + "type": "equipment", + "level": "low", + "description": "Standard tools." + } + ] }, - "affectedAssets": [ + "affects": [ "asset-light-control" ], "damageScenarios": [ "ds-road-users-blinded" - ], - "relatedRisks": [ - "risk-can-spoof-blinding" ] } ] @@ -207,7 +228,11 @@ "description": "Clause 15 risk value from impact rating and attack feasibility rating." } }, - "rationale": "Medium feasibility combined with severe safety impact." + "rationale": "Medium feasibility combined with severe safety impact.", + "controllability": { + "score": 3, + "description": "Drivers cannot readily counter sudden loss of low beam at speed; ISO 26262 class C3." + } }, "responses": [ { diff --git a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json index 689c6ba22..6c9067266 100644 --- a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json +++ b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json @@ -149,10 +149,12 @@ "level": "catastrophic", "polarity": "harm", "categories": [ - "safety", - "integrity" + "safety" ], - "description": "Incorrect drug delivery to a patient." + "description": "Incorrect drug delivery to a patient.", + "riskAttributes": [ + "integrity" + ] } }, "residualRisk": { @@ -163,7 +165,9 @@ "level": "catastrophic", "polarity": "harm", "categories": [ - "safety", + "safety" + ], + "riskAttributes": [ "integrity" ] }, diff --git a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json index 3a6f97c20..f94994894 100644 --- a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json +++ b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json @@ -85,23 +85,20 @@ "behaviors": [ "bi-suppresses-error" ], - "affectedAssets": [ + "affects": [ "asset-dosing-controller" ] } ], - "scenarios": [ + "threatScenarios": [ { "bom-ref": "ts-overdose-unalarmed", "name": "Over-limit dose delivered without alarm", "threats": [ "threat-silent-limit-failure" ], - "affectedAssets": [ + "affects": [ "asset-dosing-controller" - ], - "relatedRisks": [ - "risk-overdose" ] } ] diff --git a/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json b/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json index d8d14f032..675d419a4 100644 --- a/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json +++ b/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json @@ -55,7 +55,7 @@ "relatedVulnerabilities": [ "vuln-weak-auth" ], - "affectedAssets": [ + "affects": [ "asset-datastore" ], "relatedBusinessObjectives": [ @@ -66,7 +66,7 @@ ] } ], - "scenarios": [ + "threatScenarios": [ { "bom-ref": "ts-credential-theft", "name": "APT credential theft via spear phishing", @@ -92,11 +92,8 @@ "confidentiality", "authentication" ], - "affectedAssets": [ + "affects": [ "asset-datastore" - ], - "relatedRisks": [ - "risk-account-takeover" ] } ], From ba042b47a354dbb18f3b4b7e95c351dc4b7807b5 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 20 Sep 2026 19:34:49 -0500 Subject: [PATCH 4/7] feat: safety impact of changes on classified contexts (#954, #1041) Signed-off-by: Steve Springett --- .../cyclonedx-blueprint-2.0.schema.json | 77 ++++++ .../modules/cyclonedx-common-2.0.schema.json | 8 + .../cyclonedx-requirement-2.0.schema.json | 2 + .../modules/cyclonedx-risk-2.0.schema.json | 57 +++++ ...nvalid-risk-assessment-conclusion-2.0.json | 19 ++ ...ety-integrity-level-missing-level-2.0.json | 29 +++ .../valid-safety-impact-assessment-2.0.json | 222 ++++++++++++++++++ .../2.0/valid-safety-impact-behavior-2.0.json | 184 +++++++++++++++ 8 files changed, 598 insertions(+) create mode 100644 tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json create mode 100644 tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json diff --git a/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json b/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json index 49d241545..5f163743b 100644 --- a/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json @@ -1910,6 +1910,15 @@ "criticality": { "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/criticality" }, + "safetyIntegrityLevels": { + "type": "array", + "title": "Safety Integrity Levels", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/safetyIntegrityLevel" + }, + "description": "The safety integrity classifications of this asset in the context of the blueprint. An asset may carry classifications from more than one scheme, for example where an element classified under IEC 61508 is also mapped to an automotive ASIL. The classification identifies the safety significance of the context so that the impact of a change on it can be assessed." + }, "classification": { "$ref": "cyclonedx-data-2.0.schema.json#/$defs/dataClassification" }, @@ -1929,6 +1938,74 @@ } } }, + "safetyIntegrityLevel": { + "type": "object", + "title": "Safety Integrity Level", + "description": "A safety integrity classification drawn from a functional safety scheme, such as an Automotive Safety Integrity Level, a Safety Integrity Level, a Design Assurance Level, or a software safety class. The classification describes the safety significance of the context; a level that an authority has attested the subject achieved is recorded as a certification.", + "required": [ + "scheme", + "level" + ], + "additionalProperties": false, + "properties": { + "scheme": { + "title": "Scheme", + "description": "The functional safety scheme from which the level is drawn. Use the custom option for schemes not covered by the enumeration.", + "oneOf": [ + { + "title": "Predefined Safety Scheme", + "enum": [ + "ISO-26262", + "IEC-61508", + "DO-178C", + "IEC-62304", + "EN-50128" + ], + "meta:enum": { + "ISO-26262": "Road vehicles functional safety. Levels are Automotive Safety Integrity Levels, from QM to ASIL D.", + "IEC-61508": "Functional safety of electrical, electronic, and programmable electronic safety-related systems. Levels are Safety Integrity Levels 1 to 4.", + "DO-178C": "Software considerations in airborne systems and equipment certification. Levels are Design Assurance Levels A to E.", + "IEC-62304": "Medical device software life cycle processes. Levels are software safety classes A to C.", + "EN-50128": "Railway applications software for railway control and protection systems. Levels are Software Safety Integrity Levels 0 to 4." + } + }, + { + "type": "object", + "title": "Custom Safety Scheme", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom scheme." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom scheme." + } + } + } + ] + }, + "level": { + "type": "string", + "minLength": 1, + "title": "Integrity Level", + "description": "The level within the scheme, using the designation the scheme defines. Lowercase kebab-case tokens are recommended so that levels compare reliably across documents.", + "examples": [ + "asil-d", + "sil-3", + "dal-a", + "class-c" + ] + } + } + }, "ownership": { "type": "array", "title": "Ownership", diff --git a/schema/2.0/modules/cyclonedx-common-2.0.schema.json b/schema/2.0/modules/cyclonedx-common-2.0.schema.json index 07e52f578..10a34bb5a 100644 --- a/schema/2.0/modules/cyclonedx-common-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-common-2.0.schema.json @@ -219,12 +219,16 @@ "threat-model", "adversary-model", "risk-assessment", + "hazard-analysis", + "safety-case", "vulnerability-assertion", "exploitability-statement", "pentest-report", "static-analysis-report", "dynamic-analysis-report", "runtime-analysis-report", + "test-report", + "incident-report", "component-analysis-report", "maturity-report", "certification-report", @@ -271,12 +275,16 @@ "threat-model": "An enumeration of identified weaknesses, threats, and countermeasures, dataflow diagram (DFD), attack tree, and other supporting documentation in human-readable or machine-readable format.", "adversary-model": "The defined assumptions, goals, and capabilities of an adversary.", "risk-assessment": "Identifies and analyzes the potential of future events that may negatively impact individuals, assets, and/or the environment. Risk assessments may also include judgments on the tolerability of each risk.", + "hazard-analysis": "A hazard analysis, such as a hazard analysis and risk assessment (HARA), a failure mode and effects analysis (FMEA), or a fault tree analysis (FTA).", + "safety-case": "A structured argument, supported by a body of evidence, that a system is acceptably safe for a given application in a given environment.", "vulnerability-assertion": "A Vulnerability Disclosure Report (VDR) which asserts the known and previously unknown vulnerabilities that affect a component, service, or product including the analysis and findings describing the impact (or lack of impact) that the reported vulnerability has on a component, service, or product.", "exploitability-statement": "A Vulnerability Exploitability eXchange (VEX) which asserts the known vulnerabilities that do not affect a product, product family, or organization, and optionally the ones that do. The VEX should include the analysis and findings describing the impact (or lack of impact) that the reported vulnerability has on the product, product family, or organization.", "pentest-report": "Results from an authorized simulated cyberattack on a component or service, otherwise known as a penetration test.", "static-analysis-report": "SARIF or proprietary machine or human-readable report for which static analysis has identified code quality, security, and other potential issues with the source code.", "dynamic-analysis-report": "Dynamic analysis report that has identified issues such as vulnerabilities and misconfigurations.", "runtime-analysis-report": "Report generated by analyzing the call stack of a running application.", + "test-report": "Results of testing, such as a laboratory test, a verification test, or a validation test, of a component, service, or system.", + "incident-report": "A report of an incident, such as a safety incident, a security incident, or an operational failure, and its investigation.", "component-analysis-report": "Report generated by Software Composition Analysis (SCA), container analysis, or other forms of component analysis.", "maturity-report": "Report containing a formal assessment of an organization, business unit, or team against a maturity model.", "certification-report": "Industry, regulatory, or other certification from an accredited (if applicable) certification body.", diff --git a/schema/2.0/modules/cyclonedx-requirement-2.0.schema.json b/schema/2.0/modules/cyclonedx-requirement-2.0.schema.json index 8fd140afa..669122206 100644 --- a/schema/2.0/modules/cyclonedx-requirement-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-requirement-2.0.schema.json @@ -164,6 +164,7 @@ "privacy", "regulatory", "reliability", + "safety", "scalability", "security", "system", @@ -190,6 +191,7 @@ "privacy": "Requirements specifically addressing the handling and protection of personal and sensitive data.", "regulatory": "Requirements necessary for legal compliance, dictated by laws, regulations, or standards.", "reliability": "Requirements ensuring the system consistently performs under specified conditions and duration.", + "safety": "Requirements that address the prevention of harm to people, property, or the environment, such as functional safety requirements.", "scalability": "Requirements focused on the ability of the system to grow and manage increased demand effectively.", "security": "Requirements intended to protect systems, data, and users from malicious actions or threats.", "system": "Technical requirements defining infrastructure, architecture, or underlying technologies.", diff --git a/schema/2.0/modules/cyclonedx-risk-2.0.schema.json b/schema/2.0/modules/cyclonedx-risk-2.0.schema.json index 30eda315d..9b24cead5 100644 --- a/schema/2.0/modules/cyclonedx-risk-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-risk-2.0.schema.json @@ -260,6 +260,14 @@ }, "description": "References using bom-link or bom-ref to the weaknesses that inform this risk." }, + "relatedBehaviors": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the declared or observed behaviours that inform this risk. Any behaviour can give rise to a risk depending on context and expectation, for example an observed behaviour that defeats a declared safety behaviour." + }, "relatedRequirements": { "type": "array", "uniqueItems": true, @@ -1184,6 +1192,15 @@ "title": "Scope", "description": "The scope of the assessment, including the systems, boundaries, and what is in or out of scope." }, + "triggeredBy": { + "type": "array", + "title": "Triggered By", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the objects that occasioned this assessment, such as a vulnerability, a threat scenario, a component, a release note, or an annotation that records an incident or a change. Typically used when the cadence is triggered." + }, "status": { "title": "Status", "description": "The lifecycle status of the assessment. Use the custom option for a status specific to an organization's process.", @@ -1307,6 +1324,46 @@ }, "description": "The aggregated risk result for this assessment." }, + "conclusion": { + "title": "Conclusion", + "description": "The conclusion of the assessment for decision-making, such as a release decision. The conclusion states whether the assessed risks are acceptable against the applicable risk appetite, whereas `overallRisk` carries the aggregated score. Use the custom option for a conclusion specific to an organization's process.", + "oneOf": [ + { + "title": "Predefined Assessment Conclusion", + "enum": [ + "acceptable", + "unacceptable", + "inconclusive" + ], + "meta:enum": { + "acceptable": "The assessed risks are within the applicable risk appetite.", + "unacceptable": "One or more assessed risks exceed the applicable risk appetite.", + "inconclusive": "The assessment could not determine whether the assessed risks are within the applicable risk appetite, for example because evidence is incomplete." + } + }, + { + "title": "Custom Assessment Conclusion", + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom conclusion." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom conclusion." + } + } + } + ] + }, "assumptions": { "type": "array", "title": "Assumptions", diff --git a/tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json b/tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json new file mode 100644 index 000000000..f93337b9e --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-risk-assessment-conclusion-2.0.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Invalid: pass is not a predefined assessment conclusion; use acceptable, unacceptable, inconclusive, or a custom object.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "risks": { + "assessments": [ + { + "bom-ref": "a1", + "type": [ + "safety" + ], + "cadence": "triggered", + "timestamp": "2026-09-12T15:00:00Z", + "conclusion": "pass" + } + ] + } +} diff --git a/tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json b/tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json new file mode 100644 index 000000000..c175cba75 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-safety-integrity-level-missing-level-2.0.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Invalid: a safety integrity level requires both scheme and level; the level is missing.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "blueprints": [ + { + "bom-ref": "bp-vehicle", + "name": "Vehicle braking controller", + "modelTypes": [ + "architecture" + ], + "assets": [ + { + "bom-ref": "asset-brake-ecu", + "type": "device", + "name": "Brake ECU", + "classification": { + "safetyIntegrityLevels": [ + { + "scheme": "ISO-26262" + } + ] + } + } + ] + } + ] +} diff --git a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json new file mode 100644 index 000000000..689c6ba22 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json @@ -0,0 +1,222 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Safety impact of a change trigger on a classified context. A vulnerability in a library (the trigger) is assessed for its safety impact on the pump's therapy path (the context, which carries a software safety class). The impact is a risk, the activity is a triggered assessment with a conclusion, and the evidence is a CDXA claim backed by an FMEA excerpt plus test and hazard analysis references.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:7a2b3c4d-5e6f-4a70-8b91-c2d3e4f5a6b7", + "version": 1, + "metadata": { + "timestamp": "2026-09-17T09:00:00Z" + }, + "components": [ + { + "bom-ref": "comp-pump-firmware", + "type": "firmware", + "name": "acme-pump-firmware", + "version": "3.2.0", + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-117" + } + ] + }, + { + "bom-ref": "comp-globex-tls", + "type": "library", + "name": "globex-tls", + "version": "1.4.2" + } + ], + "dependencies": [ + { + "ref": "comp-pump-firmware", + "dependsOn": [ + "comp-globex-tls" + ] + } + ], + "blueprints": [ + { + "bom-ref": "bp-pump-deployment", + "name": "Infusion pump, hospital deployment", + "modelTypes": [ + "data-flow" + ], + "assets": [ + { + "bom-ref": "asset-tls-path", + "componentRef": "comp-globex-tls", + "classification": { + "criticality": "critical", + "safetyIntegrityLevels": [ + { + "scheme": "IEC-62304", + "level": "class-c" + } + ] + } + } + ] + } + ], + "vulnerabilities": [ + { + "bom-ref": "vuln-globex-tls-1", + "id": "GLOBEX-2026-0007", + "description": "Certificate name confusion in the Globex TLS library.", + "ratings": [ + { + "method": "CVSSv31", + "score": 7.4, + "severity": "high", + "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H" + } + ], + "analysis": { + "state": "not_affected", + "justification": "requires_configuration", + "detail": "The pump pins the gateway certificate, so name confusion is not reachable. Safety impact assessed separately, see the triggered assessment.", + "firstIssued": "2026-09-10T00:00:00Z" + }, + "affects": [ + { + "ref": "comp-globex-tls" + } + ] + } + ], + "declarations": { + "claims": [ + { + "bom-ref": "claim-tls-fmea", + "target": "asset-tls-path", + "predicate": "The vulnerability introduces no new hazardous failure mode on the therapy command path.", + "reasoning": "FMEA rows for the TLS path were re-evaluated with the vulnerability as a new cause; the existing certificate pinning control keeps the failure mode undetected-tampering at its assessed occurrence.", + "evidence": [ + "evidence-fmea-excerpt" + ] + } + ], + "evidence": [ + { + "bom-ref": "evidence-fmea-excerpt", + "description": "FMEA excerpt for the TLS communication path, re-evaluated for GLOBEX-2026-0007.", + "data": [ + { + "name": "FMEA-2026-117 rows 14 to 19", + "contents": { + "attachment": { + "mediaType": "text/plain", + "content": "Row 14: undetected command tampering; cause: TLS name confusion; control: certificate pinning; occurrence 2; severity 9; detection 3." + } + } + } + ], + "created": "2026-09-12T00:00:00Z", + "author": { + "name": "Dana Whitfield" + } + } + ] + }, + "risks": { + "risks": [ + { + "bom-ref": "risk-tls-vuln-safety", + "name": "Vulnerability GLOBEX-2026-0007 on the therapy command path", + "statement": "If the certificate name confusion were exploitable on the pump, therapy commands could be tampered with, causing incorrect drug delivery.", + "domains": [ + { + "type": "safety" + } + ], + "affects": [ + "asset-tls-path", + "comp-pump-firmware" + ], + "relatedVulnerabilities": [ + "vuln-globex-tls-1" + ], + "relatedClaims": [ + "claim-tls-fmea" + ], + "inherentRisk": { + "likelihood": { + "level": "low" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety", + "integrity" + ], + "description": "Incorrect drug delivery to a patient." + } + }, + "residualRisk": { + "likelihood": { + "level": "very-low" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety", + "integrity" + ] + }, + "rationale": "Certificate pinning makes the vulnerability unreachable in the deployed configuration." + }, + "status": "assessed" + } + ], + "assessments": [ + { + "bom-ref": "assessment-2026-09-12", + "name": "Safety impact reassessment for GLOBEX-2026-0007", + "type": [ + "safety", + "vulnerability" + ], + "cadence": "triggered", + "triggeredBy": [ + "vuln-globex-tls-1" + ], + "timestamp": "2026-09-12T15:00:00Z", + "status": "approved", + "scope": "The pump firmware 3.2.0 therapy command path in the hospital deployment blueprint.", + "assessors": [ + { + "roles": [ + { + "role": "auditor" + } + ], + "organization": { + "name": "Acme Medical Systems" + } + } + ], + "risks": [ + "risk-tls-vuln-safety" + ], + "conclusion": "acceptable", + "summary": "No new hazardous failure mode. Release 3.2.1 may proceed without a safety-driven change; the library update is scheduled for 3.3.", + "nextReview": "2026-12-12T00:00:00Z", + "externalReferences": [ + { + "type": "test-report", + "url": "https://plm.acme-medical.example/tests/TR-2026-0412", + "comment": "Certificate pinning regression test against the vulnerable library version." + }, + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-117" + } + ] + } + ] + } +} diff --git a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json new file mode 100644 index 000000000..3a6f97c20 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json @@ -0,0 +1,184 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "A behavior as the cause of a safety impact. The dosing controller declares the safety-relevant behavior enforcesOperatingLimits from the behavior taxonomy. Runtime monitoring observes a second behavior, suppressesError, on the same controller. A threat names the observed behavior as its intent, a risk states the safety consequence for the classified asset, and a triggered assessment records the verdict. The risk names the behavior directly through relatedBehaviors and the threat through relatedThreats; the assessment is triggered by the behavior. The chain is behavior, then threat, then risk, then assessment.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:9c8d7e6f-5a4b-4c3d-8e2f-1a0b9c8d7e6f", + "version": 1, + "metadata": { + "timestamp": "2026-09-18T09:00:00Z" + }, + "components": [ + { + "bom-ref": "comp-dosing-controller", + "type": "firmware", + "name": "acme-dosing-controller", + "version": "2.7.0" + }, + { + "bom-ref": "comp-runtime-monitor", + "type": "application", + "name": "globex-runtime-monitor", + "version": "5.1.3" + } + ], + "blueprints": [ + { + "bom-ref": "bp-pump", + "name": "Infusion pump, dosing path", + "modelTypes": [ + "behavioral" + ], + "assets": [ + { + "bom-ref": "asset-dosing-controller", + "componentRef": "comp-dosing-controller", + "classification": { + "criticality": "critical", + "safetyIntegrityLevels": [ + { + "scheme": "IEC-62304", + "level": "class-c" + } + ] + } + } + ], + "behaviors": { + "instances": [ + { + "bom-ref": "bi-enforces-limits", + "behavior": "safety:operationalSafety:enforcesOperatingLimits", + "acknowledgment": [ + "declared" + ], + "trigger": "continuous", + "actors": [ + "asset-dosing-controller" + ] + }, + { + "bom-ref": "bi-suppresses-error", + "behavior": "security:errorHandling:suppressesError", + "acknowledgment": [ + "observed" + ], + "trigger": "condition-based", + "actors": [ + "asset-dosing-controller" + ], + "targets": [ + "bi-enforces-limits" + ] + } + ] + } + } + ], + "threats": { + "threats": [ + { + "bom-ref": "threat-silent-limit-failure", + "name": "Silent failure of operating limit enforcement", + "description": "The controller suppresses the error raised when a dose exceeds its operating limit, so the limit check can fail without an alarm.", + "origin": "structural", + "behaviors": [ + "bi-suppresses-error" + ], + "affectedAssets": [ + "asset-dosing-controller" + ] + } + ], + "scenarios": [ + { + "bom-ref": "ts-overdose-unalarmed", + "name": "Over-limit dose delivered without alarm", + "threats": [ + "threat-silent-limit-failure" + ], + "affectedAssets": [ + "asset-dosing-controller" + ], + "relatedRisks": [ + "risk-overdose" + ] + } + ] + }, + "risks": { + "risks": [ + { + "bom-ref": "risk-overdose", + "name": "Over-limit dose delivered without alarm", + "statement": "If the controller suppresses the operating limit error, an over-limit dose can be delivered to a patient without an alarm.", + "domains": [ + { + "type": "safety" + } + ], + "affects": [ + "asset-dosing-controller" + ], + "relatedThreats": [ + "ts-overdose-unalarmed" + ], + "relatedBehaviors": [ + "bi-suppresses-error" + ], + "inherentRisk": { + "likelihood": { + "level": "medium" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety" + ], + "description": "Patient overdose." + } + }, + "status": "assessed" + } + ], + "assessments": [ + { + "bom-ref": "assessment-2026-09-15", + "name": "Safety impact assessment of observed error suppression", + "type": [ + "safety" + ], + "cadence": "triggered", + "triggeredBy": [ + "bi-suppresses-error" + ], + "timestamp": "2026-09-15T14:00:00Z", + "status": "completed", + "assessors": [ + { + "roles": [ + { + "role": "auditor" + } + ], + "organization": { + "name": "Acme Medical Systems" + } + } + ], + "risks": [ + "risk-overdose" + ], + "conclusion": "unacceptable", + "summary": "Observed behavior defeats a declared safety behavior on a class C context. Release blocked until the error path is restored and re-tested.", + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-131" + } + ] + } + ] + } +} From d6174268a742148a61f6a77dd2f9f53981a672a1 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 20 Sep 2026 20:48:53 -0500 Subject: [PATCH 5/7] feat: damage scenarios and impact methodology (ISO/SAE 21434, RDX alignment). Added test cases. Signed-off-by: Steve Springett --- .../modules/cyclonedx-risk-2.0.schema.json | 165 +++++++++---- .../modules/cyclonedx-threat-2.0.schema.json | 9 + ...d-risk-damage-scenario-no-impacts-2.0.json | 15 ++ .../2.0/valid-risk-damage-scenario-2.0.json | 223 ++++++++++++++++++ 4 files changed, 367 insertions(+), 45 deletions(-) create mode 100644 tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json create mode 100644 tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json diff --git a/schema/2.0/modules/cyclonedx-risk-2.0.schema.json b/schema/2.0/modules/cyclonedx-risk-2.0.schema.json index 9b24cead5..d767f954c 100644 --- a/schema/2.0/modules/cyclonedx-risk-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-risk-2.0.schema.json @@ -20,6 +20,15 @@ }, "description": "The documented risks identified through risk analysis." }, + "damageScenarios": { + "type": "array", + "title": "Damage Scenarios", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/damageScenario" + }, + "description": "The damage scenarios identified through risk analysis. A damage scenario describes an adverse consequence for the subjects it affects, independent of any particular cause, and is rated per impact category." + }, "assessments": { "type": "array", "title": "Assessments", @@ -244,6 +253,14 @@ }, "description": "References using bom-link or bom-ref to the threats or threat scenarios from a threat model that inform this risk. A reference may point to a discrete threat or to a threat scenario." }, + "relatedDamageScenarios": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the damage scenarios that this risk realizes. A risk typically pairs a threat scenario, which supplies the likelihood, with a damage scenario, which supplies the impact." + }, "relatedVulnerabilities": { "type": "array", "uniqueItems": true, @@ -679,6 +696,10 @@ "description": { "type": "string", "description": "A description of the potential impact." + }, + "methodology": { + "$ref": "#/$defs/riskMethodology", + "description": "The methodology used to derive this impact rating, where the impact is rated on its own, for example on a damage scenario before any risk is scored." } } }, @@ -894,54 +915,58 @@ "description": "A textual representation of the metric values used to derive the score, in the format defined by the methodology." }, "methodology": { - "title": "Methodology", - "description": "The risk rating methodology used to derive this score. Only methodologies that define a scoring calculation are listed; governance frameworks such as [ISO 31000](https://www.iso.org/iso-31000-risk-management.html) are recorded as standards rather than as a score methodology. Use the custom option for methodologies not listed.", - "oneOf": [ - { - "title": "Predefined Risk Methodology", - "enum": [ - "dread", - "fair", - "fmea", - "nist-sp-800-30", - "octave", - "owasp-risk-rating", - "qualitative-matrix" - ], - "meta:enum": { - "dread": "[DREAD](https://en.wikipedia.org/wiki/DREAD_%28risk_assessment_model%29) risk rating model, the average of five ratings (damage, reproducibility, exploitability, affected users, discoverability) each scored 1 to 10.", - "fair": "[Factor Analysis of Information Risk (FAIR)](https://www.fairinstitute.org/), a quantitative methodology expressing risk as loss event frequency multiplied by loss magnitude.", - "fmea": "[Failure Mode and Effects Analysis (FMEA)](https://asq.org/quality-resources/fmea), using a risk priority number of severity multiplied by occurrence multiplied by detection.", - "nist-sp-800-30": "[NIST SP 800-30](https://csrc.nist.gov/pubs/sp/800/30/r1/final) guide for conducting risk assessments, using its exemplary likelihood and impact scales.", - "octave": "[OCTAVE Allegro](https://www.sei.cmu.edu/documents/786/2007_005_001_14885.pdf), using its relative risk score.", - "owasp-risk-rating": "[OWASP Risk Rating](https://owasp.org/www-community/OWASP_Risk_Rating_Methodology), averaging likelihood and impact factors each scored 0 to 9.", - "qualitative-matrix": "A qualitative risk matrix that derives a risk level by plotting a likelihood band against an impact band, such as a five by five matrix producing a score from 1 to 25." - } + "$ref": "#/$defs/riskMethodology", + "description": "The risk rating methodology used to derive this score. Only methodologies that define a scoring calculation are listed; governance frameworks such as [ISO 31000](https://www.iso.org/iso-31000-risk-management.html) are recorded as standards rather than as a score methodology. Use the custom option for methodologies not listed." + } + } + }, + "riskMethodology": { + "title": "Risk Methodology", + "description": "A risk rating methodology that defines a scoring calculation. Use the custom option for methodologies not listed.", + "oneOf": [ + { + "title": "Predefined Risk Methodology", + "enum": [ + "dread", + "fair", + "fmea", + "nist-sp-800-30", + "octave", + "owasp-risk-rating", + "qualitative-matrix" + ], + "meta:enum": { + "dread": "[DREAD](https://en.wikipedia.org/wiki/DREAD_%28risk_assessment_model%29) risk rating model, the average of five ratings (damage, reproducibility, exploitability, affected users, discoverability) each scored 1 to 10.", + "fair": "[Factor Analysis of Information Risk (FAIR)](https://www.fairinstitute.org/), a quantitative methodology expressing risk as loss event frequency multiplied by loss magnitude.", + "fmea": "[Failure Mode and Effects Analysis (FMEA)](https://asq.org/quality-resources/fmea), using a risk priority number of severity multiplied by occurrence multiplied by detection.", + "nist-sp-800-30": "[NIST SP 800-30](https://csrc.nist.gov/pubs/sp/800/30/r1/final) guide for conducting risk assessments, using its exemplary likelihood and impact scales.", + "octave": "[OCTAVE Allegro](https://www.sei.cmu.edu/documents/786/2007_005_001_14885.pdf), using its relative risk score.", + "owasp-risk-rating": "[OWASP Risk Rating](https://owasp.org/www-community/OWASP_Risk_Rating_Methodology), averaging likelihood and impact factors each scored 0 to 9.", + "qualitative-matrix": "A qualitative risk matrix that derives a risk level by plotting a likelihood band against an impact band, such as a five by five matrix producing a score from 1 to 25." + } + }, + { + "title": "Custom Risk Methodology", + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom risk methodology." }, - { - "title": "Custom Risk Methodology", - "type": "object", - "required": [ - "name" - ], - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "title": "Name", - "description": "The name of the custom risk methodology." - }, - "description": { - "type": "string", - "title": "Description", - "description": "A description of the custom risk methodology." - } - } + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom risk methodology." } - ] + } } - } + ] }, "riskResponse": { "type": "object", @@ -1047,6 +1072,56 @@ } } }, + "damageScenario": { + "type": "object", + "title": "Damage Scenario", + "description": "An adverse consequence for one or more subjects, described independently of the threat or event that could cause it. A damage scenario carries an impact per category, such as safety, financial, operational, or privacy, so that the same consequence can be paired with several causes. In ISO/SAE 21434 terms, for example, the damage scenario is the harm to a road user, the threat scenario is the cause, and the risk pairs the two.", + "required": [ + "bom-ref", + "name" + ], + "additionalProperties": false, + "properties": { + "bom-ref": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refType" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "A short name for the damage scenario." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the adverse consequence and the circumstances in which it occurs." + }, + "affects": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the subjects harmed in this damage scenario, such as the functions, assets, or components involved and the parties harmed, for example a road user or a patient." + }, + "impacts": { + "type": "array", + "title": "Impacts", + "uniqueItems": true, + "minItems": 1, + "items": { + "$ref": "#/$defs/impact" + }, + "description": "The impact of the damage scenario, one entry per impact category or group of categories, each with its own level. For example, a single damage scenario may be catastrophic for safety and moderate for finance." + }, + "externalReferences": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" + }, + "properties": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" + } + } + }, "assessment": { "type": "object", "required": [ diff --git a/schema/2.0/modules/cyclonedx-threat-2.0.schema.json b/schema/2.0/modules/cyclonedx-threat-2.0.schema.json index 345170c6c..c5337b777 100644 --- a/schema/2.0/modules/cyclonedx-threat-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-threat-2.0.schema.json @@ -560,6 +560,15 @@ }, "description": "References using bom-link or bom-ref to the assets affected in this scenario." }, + "damageScenarios": { + "type": "array", + "title": "Damage Scenarios", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" + }, + "description": "References using bom-link or bom-ref to the damage scenarios, declared under the risks collection, that this scenario can lead to." + }, "relatedRisks": { "type": "array", "title": "Related Risks", diff --git a/tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json b/tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json new file mode 100644 index 000000000..03f0127c5 --- /dev/null +++ b/tools/src/test/resources/2.0/invalid-risk-damage-scenario-no-impacts-2.0.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Invalid: a damage scenario that carries impacts requires at least one impact.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "risks": { + "damageScenarios": [ + { + "bom-ref": "ds-1", + "name": "No impact given", + "impacts": [] + } + ] + } +} diff --git a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json new file mode 100644 index 000000000..2d1f48ce7 --- /dev/null +++ b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json @@ -0,0 +1,223 @@ +{ + "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", + "$comment": "Damage scenario, threat scenario, and risk, in the ISO/SAE 21434 shape as carried by RDX. The damage scenario is the consequence with an impact per category; the threat scenario is the cause and names the damage scenarios it can lead to; the risk pairs the two and carries the rating. The light controller asset carries an ASIL so the safety significance of the context is explicit.", + "specFormat": "CycloneDX", + "specVersion": "2.0", + "serialNumber": "urn:uuid:3b4c5d6e-7f80-4a91-b2c3-d4e5f6a7b8c9", + "version": 1, + "metadata": { + "timestamp": "2026-09-20T10:00:00Z" + }, + "components": [ + { + "bom-ref": "comp-light-controller", + "type": "firmware", + "name": "acme-light-controller", + "version": "4.2.0" + } + ], + "blueprints": [ + { + "bom-ref": "bp-headlamp", + "name": "Adaptive headlamp system", + "modelTypes": [ + "architecture" + ], + "assets": [ + { + "bom-ref": "asset-light-control", + "componentRef": "comp-light-controller", + "classification": { + "criticality": "high", + "safetyIntegrityLevels": [ + { + "scheme": "ISO-26262", + "level": "asil-b" + } + ] + } + }, + { + "bom-ref": "asset-fn-glare-free", + "type": "function", + "name": "Glare-free high beam" + } + ], + "actors": [ + { + "bom-ref": "actor-oncoming-driver", + "party": { + "roles": [ + { + "role": "subject" + } + ], + "persona": { + "archetype": { + "name": "road-user", + "description": "A person on or near the road who is exposed to the vehicle's behaviour." + }, + "description": "Oncoming driver." + } + }, + "description": "A driver of an oncoming vehicle exposed to the headlamp output." + } + ] + } + ], + "threats": { + "threats": [ + { + "bom-ref": "threat-can-spoof", + "name": "Spoofed light control message on the body CAN", + "origin": "adversarial", + "categories": [ + { + "taxonomy": "STRIDE", + "category": "spoofing" + } + ], + "affectedAssets": [ + "asset-light-control" + ] + } + ], + "scenarios": [ + { + "bom-ref": "ts-can-spoof", + "name": "Attacker injects light control frames from a compromised body ECU", + "threats": [ + "threat-can-spoof" + ], + "attackVector": { + "type": "adjacent", + "complexity": "low", + "privileges": "low", + "userInteraction": "none" + }, + "likelihood": { + "level": "medium", + "rationale": "Attack feasibility rated medium: hours of elapsed time, proficient expertise, public CAN knowledge, standard equipment." + }, + "affectedAssets": [ + "asset-light-control" + ], + "damageScenarios": [ + "ds-road-users-blinded" + ], + "relatedRisks": [ + "risk-can-spoof-blinding" + ] + } + ] + }, + "risks": { + "damageScenarios": [ + { + "bom-ref": "ds-road-users-blinded", + "name": "Driver or other road users blinded", + "description": "Incorrect headlamp operation causes loss of visibility for the driver or glare for oncoming traffic, leading to a collision.", + "affects": [ + "asset-fn-glare-free", + "asset-light-control", + "actor-oncoming-driver" + ], + "impacts": [ + { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety" + ], + "description": "Loss of visibility at speed can cause a fatal collision. Severe on the ISO/SAE 21434 scale.", + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15.5 impact rating." + } + }, + { + "level": "major", + "polarity": "harm", + "categories": [ + "operational" + ], + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15.5 impact rating." + } + }, + { + "level": "moderate", + "polarity": "harm", + "categories": [ + "financial" + ], + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15.5 impact rating." + } + } + ], + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-automotive.example/hara/HL-2026-004" + } + ] + } + ], + "risks": [ + { + "bom-ref": "risk-can-spoof-blinding", + "name": "CAN spoofing leads to road users blinded", + "statement": "If an attacker injects light control frames on the body CAN, the headlamps can be driven to blind the driver or oncoming traffic.", + "domains": [ + { + "type": "safety" + }, + { + "type": "security" + } + ], + "affects": [ + "asset-light-control" + ], + "relatedThreats": [ + "ts-can-spoof" + ], + "relatedDamageScenarios": [ + "ds-road-users-blinded" + ], + "inherentRisk": { + "likelihood": { + "level": "medium" + }, + "impact": { + "level": "catastrophic", + "polarity": "harm", + "categories": [ + "safety" + ] + }, + "score": { + "level": "high", + "score": 4, + "methodology": { + "name": "ISO/SAE 21434", + "description": "Clause 15 risk value from impact rating and attack feasibility rating." + } + }, + "rationale": "Medium feasibility combined with severe safety impact." + }, + "responses": [ + { + "bom-ref": "resp-can-auth", + "strategy": "reduce", + "description": "Authenticate light control frames and rate-limit diagnostic writes." + } + ], + "status": "assessed" + } + ] + } +} From 7312c7fbf0df261df11dab721e5522fe2f4d0571 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Sun, 20 Sep 2026 21:35:07 -0500 Subject: [PATCH 6/7] refactor: align threat and risk models with ISO 31000, ISO/SAE 21434, and ISO 26262 Threat scenarios carry feasibility only, risks pair them with damage scenarios and reference one way, and naming, statuses, and scales are now unified across the two models. Signed-off-by: Steve Springett --- .../cyclonedx-blueprint-2.0.schema.json | 9 +++ .../modules/cyclonedx-risk-2.0.schema.json | 65 +++++++++++------- .../modules/cyclonedx-threat-2.0.schema.json | 68 +++++-------------- ...nvalid-threatmodel-missing-bomref-2.0.json | 2 +- .../2.0/valid-risk-damage-scenario-2.0.json | 41 ++++++++--- .../valid-safety-impact-assessment-2.0.json | 12 ++-- .../2.0/valid-safety-impact-behavior-2.0.json | 9 +-- .../2.0/valid-threatmodel-simple-2.0.json | 9 +-- 8 files changed, 114 insertions(+), 101 deletions(-) diff --git a/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json b/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json index 5f163743b..2397c587d 100644 --- a/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-blueprint-2.0.schema.json @@ -1919,6 +1919,15 @@ }, "description": "The safety integrity classifications of this asset in the context of the blueprint. An asset may carry classifications from more than one scheme, for example where an element classified under IEC 61508 is also mapped to an automotive ASIL. The classification identifies the safety significance of the context so that the impact of a change on it can be assessed." }, + "riskAttributes": { + "type": "array", + "title": "Risk Attributes", + "uniqueItems": true, + "items": { + "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/riskAttribute" + }, + "description": "The security and privacy attributes of this asset that are worth protecting, such as integrity or availability, whose compromise leads to damage. Corresponds to the cybersecurity properties of an asset in ISO/SAE 21434 and to the security objectives of FIPS 199." + }, "classification": { "$ref": "cyclonedx-data-2.0.schema.json#/$defs/dataClassification" }, diff --git a/schema/2.0/modules/cyclonedx-risk-2.0.schema.json b/schema/2.0/modules/cyclonedx-risk-2.0.schema.json index d767f954c..66b6a0cdf 100644 --- a/schema/2.0/modules/cyclonedx-risk-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-risk-2.0.schema.json @@ -70,9 +70,9 @@ "privacy", "operational", "financial", - "compliance", + "regulatory", "strategic", - "reputational", + "reputation", "safety", "environmental", "supply-chain", @@ -89,9 +89,9 @@ "privacy": "Data protection and privacy risks.", "operational": "Business operations and continuity risks.", "financial": "Financial loss and economic impact risks.", - "compliance": "Regulatory and legal compliance risks.", + "regulatory": "Regulatory and legal compliance risks.", "strategic": "Strategic business and market risks.", - "reputational": "Brand and reputation damage risks.", + "reputation": "Brand and reputation damage risks.", "safety": "Human safety and physical security risks.", "environmental": "Environmental impact and sustainability risks.", "supply-chain": "Supply chain and third-party risks.", @@ -338,24 +338,22 @@ }, "status": { "title": "Status", - "description": "The lifecycle status of the risk. Use the custom option for a status specific to an organization's risk process.", + "description": "The lifecycle status of the risk. The status tracks progress through the risk process; the disposition chosen, such as reduce, share, or accept, is recorded on the responses. Use the custom option for a status specific to an organization's risk process.", "oneOf": [ { "title": "Predefined Risk Status", "enum": [ "identified", "assessed", - "mitigated", - "accepted", - "transferred", + "treated", + "monitored", "retired" ], "meta:enum": { - "identified": "Risk has been identified but not yet evaluated.", - "assessed": "Risk has been assessed and prioritized.", - "mitigated": "Responses are in place reducing this risk.", - "accepted": "Risk has been formally accepted.", - "transferred": "Risk has been transferred to another party.", + "identified": "The risk has been identified and recorded.", + "assessed": "The risk has been analysed and rated.", + "treated": "Responses to the risk have been decided and are being applied. The disposition, such as reduce or accept, is recorded on the responses.", + "monitored": "The risk and its responses are under ongoing monitoring and review.", "retired": "Risk no longer applies." } }, @@ -423,6 +421,23 @@ } } }, + "controllability": { + "type": "object", + "title": "Controllability", + "additionalProperties": false, + "description": "The ability of the people involved to avoid the harm once the event occurs, used as a third axis by functional safety methodologies such as the hazard analysis and risk assessment of [ISO 26262](https://www.iso.org/standard/68383.html), which derives an integrity level from severity, exposure, and controllability.", + "properties": { + "score": { + "type": "number", + "minimum": 0, + "description": "The controllability value on the scale defined by the methodology. For ISO 26262, a higher class indicates that the harm is harder to avoid." + }, + "description": { + "type": "string", + "description": "A narrative explanation of the controllability assessment." + } + } + }, "confidence": { "type": "number", "minimum": 0, @@ -532,8 +547,11 @@ "control-effectiveness", "detectability", "discoverability", + "elapsed-time", + "equipment", "exploit-maturity", "exposure", + "knowledge", "motivation", "opportunity", "targeting", @@ -546,8 +564,11 @@ "control-effectiveness": "Strength, reliability, and coverage of existing preventive, detective, or corrective controls that reduce the probability of successful exploitation. Corresponds to resistance strength in FAIR.", "detectability": "Likelihood that the activity is detected before the risk is realized. Lower detectability increases the chance of a successful action. Aligns with the OWASP Risk Rating intrusion detection factor and the FMEA detection axis.", "discoverability": "Ease with which the weakness or opportunity can be found by a potential actor. Aligns with the OWASP Risk Rating ease of discovery factor.", + "elapsed-time": "The time an attacker needs to identify and exploit the weakness, one of the attack potential factors of [ISO/IEC 18045](https://www.iso.org/standard/72889.html) used by attack feasibility ratings such as ISO/SAE 21434.", + "equipment": "The equipment an attacker needs, from standard to bespoke, one of the attack potential factors of [ISO/IEC 18045](https://www.iso.org/standard/72889.html).", "exploit-maturity": "Availability, reliability, and sophistication of known exploits, attack toolkits, or proof-of-concept code targeting the identified weakness.", "exposure": "Degree to which the target asset, system, or service is visible, discoverable, or reachable by potential threat actors.", + "knowledge": "The knowledge of the target an attacker needs, from public to critical, one of the attack potential factors of [ISO/IEC 18045](https://www.iso.org/standard/72889.html).", "motivation": "Level of incentive, intent, or determination driving the threat actor to pursue exploitation, including financial gain, ideology, or competitive advantage.", "opportunity": "Availability of the conditions, timing, or circumstances required for the threat actor to act, including access windows, environmental factors, and resource availability.", "targeting": "Degree to which the threat actor specifically selects this asset or organization rather than acting opportunistically. Aligns with the NIST SP 800-30 targeting factor.", @@ -705,14 +726,11 @@ }, "impactCategory": { "title": "Impact Category", - "description": "A category of impact, including harms relevant to AI and societal risk. Use the custom option for categories specific to an organization's risk taxonomy.", + "description": "A category of impact, including harms relevant to AI and societal risk. The security and privacy attributes compromised, such as confidentiality or integrity, are recorded as risk attributes rather than as impact categories. Use the custom option for categories specific to an organization's risk taxonomy.", "oneOf": [ { "title": "Predefined Impact Category", "enum": [ - "confidentiality", - "integrity", - "availability", "financial", "reputation", "regulatory", @@ -731,9 +749,6 @@ "health" ], "meta:enum": { - "confidentiality": "Impact on data confidentiality.", - "integrity": "Impact on data or system integrity.", - "availability": "Impact on service availability.", "financial": "Financial loss or impact.", "reputation": "Reputational damage.", "regulatory": "Regulatory compliance impact.", @@ -890,7 +905,7 @@ "properties": { "level": { "enum": [ - "info", + "negligible", "low", "medium", "high", @@ -898,7 +913,7 @@ ], "description": "The overall qualitative risk level.", "meta:enum": { - "info": "Informational.", + "negligible": "Negligible risk.", "low": "Low risk.", "medium": "Medium risk.", "high": "High risk.", @@ -988,7 +1003,7 @@ "enum": [ "avoid", "reduce", - "transfer", + "share", "accept", "exploit", "enhance" @@ -996,7 +1011,7 @@ "meta:enum": { "avoid": "Eliminate the risk by removing its source or not proceeding with the activity.", "reduce": "Lower the likelihood or impact of the risk through controls.", - "transfer": "Shift the risk to another party, for example through insurance or contract.", + "share": "Share the risk with another party, for example through insurance, contract, or outsourcing. Some frameworks call this transfer.", "accept": "Take no further action and retain the risk.", "exploit": "Pursue an opportunity so that a positive risk occurs.", "enhance": "Increase the likelihood or benefit of a positive risk." @@ -1013,7 +1028,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls that implement this response." + "description": "References using bom-link or bom-ref to the controls that implement this response. Where a control is declared in the same document, its appliesTo property may also record the relationship." }, "status": { "title": "Status", diff --git a/schema/2.0/modules/cyclonedx-threat-2.0.schema.json b/schema/2.0/modules/cyclonedx-threat-2.0.schema.json index c5337b777..10724839e 100644 --- a/schema/2.0/modules/cyclonedx-threat-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-threat-2.0.schema.json @@ -8,7 +8,7 @@ "threats": { "type": "object", "title": "Threats", - "description": "Threat-modelling content, including the documented threats, the scenarios that realize them, the attack patterns and attack trees that describe how they are carried out, and the trust boundaries they cross.", + "description": "Threat-modelling content, including the documented threats, the threat scenarios that realize them, the attack patterns and attack trees that describe how they are carried out, and the trust boundaries they cross. Control references throughout this model point at controls that mitigate the referencing element. Where a control is declared in the same document, its appliesTo property may also record the relationship; the reference here is intended primarily for controls defined elsewhere.", "additionalProperties": false, "properties": { "threats": { @@ -20,9 +20,9 @@ }, "description": "The documented threats. Each describes what can go wrong, independent of any specific actor or occurrence." }, - "scenarios": { + "threatScenarios": { "type": "array", - "title": "Scenarios", + "title": "Threat Scenarios", "uniqueItems": true, "items": { "$ref": "#/$defs/threatScenario" @@ -36,7 +36,7 @@ "items": { "$ref": "#/$defs/attackPattern" }, - "description": "A library of attack patterns, typically aligned with CAPEC, that threats and scenarios can reference." + "description": "A library of attack patterns, typically aligned with CAPEC, that threats and threat scenarios can reference." }, "attackTrees": { "type": "array", @@ -379,14 +379,14 @@ "indicators": { "$ref": "#/$defs/indicators" }, - "affectedAssets": { + "affects": { "type": "array", - "title": "Affected Assets", + "title": "Affects", "uniqueItems": true, "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the kinds of assets this threat affects." + "description": "References using bom-link or bom-ref to the assets that this threat can affect." }, "relatedBusinessObjectives": { "type": "array", @@ -416,7 +416,7 @@ "threatScenario": { "type": "object", "title": "Threat Scenario", - "description": "A specific realization of a threat, in which an actor seeks to cause harm. The scenario references the threat it realizes, supplies the actor by reference to a party, and carries the scenario-specific traits and risk assessment, such as motivation, intent, access level, likelihood, and impact.", + "description": "A specific realization of a threat, in which an actor seeks to cause harm. The scenario references the threats it realizes, supplies the actor by reference to a party, and carries the scenario-specific traits, such as motivation, intent, access level, and likelihood. The consequence is expressed by the damage scenarios it leads to, and the resulting risk is documented under risks, referencing both.", "additionalProperties": false, "required": [ "bom-ref", @@ -534,13 +534,8 @@ "$ref": "#/$defs/exploitability" }, "likelihood": { - "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/likelihood" - }, - "impact": { - "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/impact" - }, - "riskScore": { - "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/riskScore" + "$ref": "cyclonedx-risk-2.0.schema.json#/$defs/likelihood", + "description": "The likelihood that this scenario is realized, which in attack terms is its feasibility. The consequence is carried by the damage scenarios the scenario leads to, and the paired rating by the risk that references both." }, "riskAttributes": { "type": "array", @@ -551,9 +546,9 @@ }, "description": "The security and privacy attributes that this threat would compromise if realized." }, - "affectedAssets": { + "affects": { "type": "array", - "title": "Affected Assets", + "title": "Affects", "uniqueItems": true, "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" @@ -569,15 +564,6 @@ }, "description": "References using bom-link or bom-ref to the damage scenarios, declared under the risks collection, that this scenario can lead to." }, - "relatedRisks": { - "type": "array", - "title": "Related Risks", - "uniqueItems": true, - "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" - }, - "description": "References using bom-link or bom-ref to the risks that this scenario contributes to." - }, "relatedVulnerabilities": { "type": "array", "uniqueItems": true, @@ -989,7 +975,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls that mitigate this node." + "description": "References using bom-link or bom-ref to the controls that mitigate this attack tree node." } } }, @@ -1085,20 +1071,8 @@ "additionalProperties": false, "properties": { "level": { - "title": "Level", - "description": "The maturity of available exploitation capability.", - "enum": [ - "theoretical", - "proof-of-concept", - "functional", - "weaponized" - ], - "meta:enum": { - "theoretical": "Exploitation is theoretically possible but has not been demonstrated.", - "proof-of-concept": "A proof of concept exists.", - "functional": "A functional exploit exists.", - "weaponized": "A weaponized exploit is in use." - } + "$ref": "cyclonedx-vulnerability-2.0.schema.json#/$defs/exploitMaturity", + "description": "The maturity of available exploitation capability, using the same scale as vulnerability exploit maturity." }, "complexity": { "title": "Complexity", @@ -1293,7 +1267,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls in place at this boundary. Intended primarily for referencing externally defined controls. Where the control and boundary are declared together, prefer the control's appliesTo property." + "description": "References using bom-link or bom-ref to the controls that mitigate threats at this trust boundary." }, "properties": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" @@ -1383,7 +1357,7 @@ "items": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" }, - "description": "References using bom-link or bom-ref to the controls that detect or prevent this step." + "description": "References using bom-link or bom-ref to the controls that mitigate this attack path step, by preventing or detecting it." }, "properties": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/properties" @@ -1441,14 +1415,6 @@ }, "description": "References using bom-link or bom-ref to the threats that this path realizes." }, - "relatedRisks": { - "type": "array", - "uniqueItems": true, - "items": { - "$ref": "cyclonedx-common-2.0.schema.json#/$defs/refLinkType" - }, - "description": "References using bom-link or bom-ref to the risks that this path contributes to." - }, "externalReferences": { "$ref": "cyclonedx-common-2.0.schema.json#/$defs/externalReferences" }, diff --git a/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json b/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json index 49e07bb83..0a0fdf7d8 100644 --- a/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json +++ b/tools/src/test/resources/2.0/invalid-threatmodel-missing-bomref-2.0.json @@ -2,7 +2,7 @@ "specFormat": "CycloneDX", "specVersion": "2.0", "threats": { - "scenarios": [ + "threatScenarios": [ { "name": "Scenario missing its required bom-ref", "threats": [ diff --git a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json index 2d1f48ce7..5e0e01c9c 100644 --- a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json +++ b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json @@ -34,6 +34,10 @@ "scheme": "ISO-26262", "level": "asil-b" } + ], + "riskAttributes": [ + "integrity", + "availability" ] } }, @@ -77,12 +81,12 @@ "category": "spoofing" } ], - "affectedAssets": [ + "affects": [ "asset-light-control" ] } ], - "scenarios": [ + "threatScenarios": [ { "bom-ref": "ts-can-spoof", "name": "Attacker injects light control frames from a compromised body ECU", @@ -97,16 +101,33 @@ }, "likelihood": { "level": "medium", - "rationale": "Attack feasibility rated medium: hours of elapsed time, proficient expertise, public CAN knowledge, standard equipment." + "rationale": "Attack feasibility rated medium: hours of elapsed time, proficient expertise, public CAN knowledge, standard equipment.", + "factors": [ + { + "name": "Elapsed time", + "type": "elapsed-time", + "level": "medium", + "description": "Hours." + }, + { + "name": "Knowledge of the item", + "type": "knowledge", + "level": "low", + "description": "Public CAN protocol knowledge." + }, + { + "name": "Equipment", + "type": "equipment", + "level": "low", + "description": "Standard tools." + } + ] }, - "affectedAssets": [ + "affects": [ "asset-light-control" ], "damageScenarios": [ "ds-road-users-blinded" - ], - "relatedRisks": [ - "risk-can-spoof-blinding" ] } ] @@ -207,7 +228,11 @@ "description": "Clause 15 risk value from impact rating and attack feasibility rating." } }, - "rationale": "Medium feasibility combined with severe safety impact." + "rationale": "Medium feasibility combined with severe safety impact.", + "controllability": { + "score": 3, + "description": "Drivers cannot readily counter sudden loss of low beam at speed; ISO 26262 class C3." + } }, "responses": [ { diff --git a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json index 689c6ba22..6c9067266 100644 --- a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json +++ b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json @@ -149,10 +149,12 @@ "level": "catastrophic", "polarity": "harm", "categories": [ - "safety", - "integrity" + "safety" ], - "description": "Incorrect drug delivery to a patient." + "description": "Incorrect drug delivery to a patient.", + "riskAttributes": [ + "integrity" + ] } }, "residualRisk": { @@ -163,7 +165,9 @@ "level": "catastrophic", "polarity": "harm", "categories": [ - "safety", + "safety" + ], + "riskAttributes": [ "integrity" ] }, diff --git a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json index 3a6f97c20..f94994894 100644 --- a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json +++ b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json @@ -85,23 +85,20 @@ "behaviors": [ "bi-suppresses-error" ], - "affectedAssets": [ + "affects": [ "asset-dosing-controller" ] } ], - "scenarios": [ + "threatScenarios": [ { "bom-ref": "ts-overdose-unalarmed", "name": "Over-limit dose delivered without alarm", "threats": [ "threat-silent-limit-failure" ], - "affectedAssets": [ + "affects": [ "asset-dosing-controller" - ], - "relatedRisks": [ - "risk-overdose" ] } ] diff --git a/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json b/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json index d8d14f032..675d419a4 100644 --- a/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json +++ b/tools/src/test/resources/2.0/valid-threatmodel-simple-2.0.json @@ -55,7 +55,7 @@ "relatedVulnerabilities": [ "vuln-weak-auth" ], - "affectedAssets": [ + "affects": [ "asset-datastore" ], "relatedBusinessObjectives": [ @@ -66,7 +66,7 @@ ] } ], - "scenarios": [ + "threatScenarios": [ { "bom-ref": "ts-credential-theft", "name": "APT credential theft via spear phishing", @@ -92,11 +92,8 @@ "confidentiality", "authentication" ], - "affectedAssets": [ + "affects": [ "asset-datastore" - ], - "relatedRisks": [ - "risk-account-takeover" ] } ], From fd6ea256af07046b3a8331c2954bd4f2154d170b Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Thu, 15 Oct 2026 17:45:47 -0500 Subject: [PATCH 7/7] Aligned test cases to match recent changes in main. Signed-off-by: Steve Springett --- .../2.0/valid-risk-damage-scenario-2.0.json | 18 ++++---- .../valid-safety-impact-assessment-2.0.json | 42 ++++++++++--------- .../2.0/valid-safety-impact-behavior-2.0.json | 30 ++++++------- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json index 5e0e01c9c..ba5ae67bf 100644 --- a/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json +++ b/tools/src/test/resources/2.0/valid-risk-damage-scenario-2.0.json @@ -8,14 +8,16 @@ "metadata": { "timestamp": "2026-09-20T10:00:00Z" }, - "components": [ - { - "bom-ref": "comp-light-controller", - "type": "firmware", - "name": "acme-light-controller", - "version": "4.2.0" - } - ], + "definitions":{ + "components": [ + { + "bom-ref": "comp-light-controller", + "type": "firmware", + "name": "acme-light-controller", + "version": "4.2.0" + } + ] + }, "blueprints": [ { "bom-ref": "bp-headlamp", diff --git a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json index 6c9067266..f9f670c74 100644 --- a/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json +++ b/tools/src/test/resources/2.0/valid-safety-impact-assessment-2.0.json @@ -8,26 +8,28 @@ "metadata": { "timestamp": "2026-09-17T09:00:00Z" }, - "components": [ - { - "bom-ref": "comp-pump-firmware", - "type": "firmware", - "name": "acme-pump-firmware", - "version": "3.2.0", - "externalReferences": [ - { - "type": "hazard-analysis", - "url": "https://plm.acme-medical.example/safety/RA-2026-117" - } - ] - }, - { - "bom-ref": "comp-globex-tls", - "type": "library", - "name": "globex-tls", - "version": "1.4.2" - } - ], + "definitions":{ + "components": [ + { + "bom-ref": "comp-pump-firmware", + "type": "firmware", + "name": "acme-pump-firmware", + "version": "3.2.0", + "externalReferences": [ + { + "type": "hazard-analysis", + "url": "https://plm.acme-medical.example/safety/RA-2026-117" + } + ] + }, + { + "bom-ref": "comp-globex-tls", + "type": "library", + "name": "globex-tls", + "version": "1.4.2" + } + ] + }, "dependencies": [ { "ref": "comp-pump-firmware", diff --git a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json index f94994894..8f99a8a40 100644 --- a/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json +++ b/tools/src/test/resources/2.0/valid-safety-impact-behavior-2.0.json @@ -8,20 +8,22 @@ "metadata": { "timestamp": "2026-09-18T09:00:00Z" }, - "components": [ - { - "bom-ref": "comp-dosing-controller", - "type": "firmware", - "name": "acme-dosing-controller", - "version": "2.7.0" - }, - { - "bom-ref": "comp-runtime-monitor", - "type": "application", - "name": "globex-runtime-monitor", - "version": "5.1.3" - } - ], + "definitions":{ + "components": [ + { + "bom-ref": "comp-dosing-controller", + "type": "firmware", + "name": "acme-dosing-controller", + "version": "2.7.0" + }, + { + "bom-ref": "comp-runtime-monitor", + "type": "application", + "name": "globex-runtime-monitor", + "version": "5.1.3" + } + ] + }, "blueprints": [ { "bom-ref": "bp-pump",