Skip to content

Proposal: Safety Relevance Metadata for CycloneDX #954

Closed

Description

@devashridatta-dotcom

Summary

This proposal introduces an optional Safety Relevance metadata property for CycloneDX components.

The goal is to capture whether a component participates in safety-critical or mission-critical functions where compromise, malfunction, or misuse could contribute to:

  • Physical harm
  • Human safety risks
  • Environmental damage
  • Critical infrastructure disruption
  • Societal impact

The proposal complements existing CycloneDX capabilities such as Vulnerability Disclosure, VEX, AI BOM, and dependency analysis by adding contextual information about the operational consequences of component failure.

Motivation

CycloneDX provides rich metadata describing:

  • Component identity
  • Dependencies
  • Vulnerabilities
  • VEX assertions
  • Services
  • AI and machine learning artifacts

However, it does not currently express whether a component is part of a safety-critical system.

Organizations in automotive, healthcare, robotics, industrial control systems, energy, and AI increasingly require this context to:

  • Prioritize remediation
  • Interpret VEX results
  • Build safety cases
  • Meet regulatory obligations
  • Improve risk governance

Initial Proposal

Introduce optional metadata properties:

  • cyclonedx:safety-relevance
  • cyclonedx:safety-domain
  • cyclonedx:safety-impact

Example:

safety-relevance = Critical

safety-domain = Medical

safety-impact = HumanSafety

Example Classification

  • None
  • Indirect
  • Critical
  • Unknown

Questions for the Community

  1. Should Safety Relevance begin as custom properties or as a first-class schema object?
  2. Are there existing use cases in medical, automotive, AI, or industrial systems?
  3. How should Safety Relevance interact with VEX and vulnerability analysis?
  4. Would a common taxonomy benefit downstream tooling and SBOM consumers?

Next Steps

If there is interest, I can:

  • Draft a formal schema proposal
  • Provide example BOMs
  • Develop mappings to VEX and AI BOM
  • Collaborate with the community on taxonomy and governance

Activity

  1. stevespringett commented on Jun 19, 2026

    @stevespringett
    Member

    Thanks for this proposal, @devashridatta-dotcom. Safety relevance is squarely in scope for where CycloneDX is heading, and a good deal of what you describe is already taking shape in the 2.0 line (in development), so this is well-timed. Here is where each part maps today and where the gap is.

    What already exists in 2.0

    Safety impact (physical harm, human safety, environmental damage, societal impact): the 2.0 risk model already enumerates these as impact categories. impact.categories includes safety, physical, environmental, societal, health, and psychological, and the risk domain taxonomy includes safety, environmental, health, societal, and human-rights. The consequence types your proposal lists are first-class.

    Safety domain (Medical, Automotive, and so on): the 2.0 perspective model carries a domain taxonomy with a dedicated safety cluster, including automotive-safety, aviation-safety, functional-safety, machinery-safety, maritime-safety, nuclear-safety, patient-safety, process-safety, railway-safety, and environmental-safety, alongside sector domains such as healthcare, medical-devices, critical-infrastructure, industrial-control-systems, robotics, and energy-utilities. Several reference the relevant standards (for example automotive-safety notes ISO 26262 and ASIL).

    Safety relevance level and component linkage: a component's safety weight is expressible through criticality (minimal to critical), which a blueprint attaches to an asset through assetClassification, and through a risk whose affects references the component while carrying a safety domain and a safety or physical impact rating. So "this component participates in a safety-critical function, and here is the consequence if it fails" is representable now, with the degree carried by the rating rather than a single flag.

    VEX and vulnerability interaction (your question 3): this is already wired. A risk can reference both the affected component (affects) and the vulnerabilities that inform it (relatedVulnerabilities), and the vulnerability model carries the VEX analysis. That lets a consumer prioritize remediation by safety impact and interpret VEX in a safety context, which is the workflow you describe.

    Where the gap is

    What 2.0 does not yet model first-class is a standards-aligned safety integrity level. Your None / Indirect / Critical scale is a coarse proxy for what safety-critical industries express as ASIL (ISO 26262), SIL (IEC 61508), DAL (DO-178C), or software safety class (IEC 62304). A common, machine-readable safety-integrity classification, attachable to a component or asset and mappable to those standards, is the genuinely net-new piece, and it is where a common taxonomy would most help downstream tooling (your question 4).

    On your questions

    1. Custom properties or first-class: I would not start with cyclonedx:* custom properties, since the substance (impact, domain, criticality, VEX linkage) is already first-class in 2.0 and custom properties would fragment it. The first-class addition worth designing is the safety-integrity classification.
    2. Use cases: yes, across automotive (ISO 26262), aviation (DO-178C), industrial (IEC 61508), medical (IEC 62304), rail (EN 5012x), and nuclear. The perspective safety domains were added with these in mind.
    3. VEX interaction: covered by risk.relatedVulnerabilities plus the VEX analysis on the vulnerability, as above.
    4. Common taxonomy: yes. The impact and domain taxonomies already exist; a safety-integrity-level taxonomy is the high-value addition.

    Suggested next step

    Rather than a separate component metadata block, the most durable path is to use the existing risk, perspective, and criticality constructs for impact, domain, and component linkage, and to collaborate on a small safety-integrity classification (ASIL, SIL, DAL, and IEC 62304 mappings) targeted at the 2.0 line. Example BOMs showing a safety-critical component expressed with risk plus perspective plus criticality today, alongside a sketch of the safety-integrity field, would be a great starting point.

  2. devashridatta-dotcom commented on Jun 19, 2026

    @devashridatta-dotcom
    Author

    Thank you for the detailed explanation and for mapping the proposal to the CycloneDX 2.0 model.

    This is very helpful. After reading your response, I agree that much of what I described is already expressible through the existing constructs of risk, perspective, criticality, and VEX. The impact categories, safety domains, and risk-to-component/vulnerability relationships appear to provide the right foundation.

    The gap you highlighted around a standards-aligned safety integrity classification is particularly interesting. My original None / Indirect / Critical scale was intended as a simple way to express whether a component participates in a safety-critical function, but I agree that safety-critical industries already have richer models such as ASIL (ISO 26262), SIL (IEC 61508), DAL (DO-178C), and IEC 62304 software safety classes.

    A common, machine-readable abstraction that can represent and map these integrity levels across domains seems like a valuable addition for downstream tooling and policy engines.

    I’ll spend some time putting together a few example BOMs showing:

    • how safety-related components can already be represented using the current 2.0 constructs, and
    • what a possible Safety Integrity Classification model could look like while remaining compatible with those constructs.

    Thanks again for the guidance. This gives me a much clearer direction for refining the proposal.

  3. stevespringett commented on Jul 11, 2026

    @stevespringett
    Member

    @devashridatta-dotcom Thanks for the continued work on this, and for the SRAP v0.1 gist and the routing through ossf/tac#624. I have mapped the proposal, field by field, against CycloneDX 2.0, which is in active development and approaching its RFC period. The short version: nearly everything SRAP asks for is already first-class in the 2.0 line, and the one element that is genuinely missing is small. We may have a solution that fills the gaps with very little change to CycloneDX 2.0 at all.

    Where each SRAP field lands in 2.0 today:

    SRAP field CycloneDX 2.0
    consequence_class Risk impact categories. safety, physical, health, environmental, and societal are first-class values, and the perspective model carries a dedicated safety domain taxonomy (patient-safety, automotive-safety, functional-safety, and others).
    declared_scope A blueprint: a structured, independently signable model of the system in its deployment context. This also answers the open scope-format question. Rather than free text or a PURL convention, the scope is a referenceable document whose assets point at the exact components they represent.
    integration_scope Blueprint data flows and use cases, plus the behavior model, express "participates in the call path of this safety function" directly.
    classification_source The party model. Parties carry roles such as manufacturer, integrator, operator, auditor, and regulator, and they sign the documents that carry their assertions, so authority is cryptographically attributable rather than a self-labeled string.
    evidence_basis Attestations (CDXA claims and evidence) plus external references to the underlying artifacts.
    known_unknowns, review_status Annotations attach to any object, and blueprint scope declares exclusions explicitly, so "the bootloader TLS path has not been assessed" is recordable today.
    safety_relevance level criticality plus a rated risk today, and the integrity-level classification below replaces the coarse none/indirect/critical scale with what regulated industries actually exchange.

    The genuinely net-new piece is the one the gist itself flags: a standards-aligned safety integrity classification. We have a drafted and validated schema change for it. It is a small {scheme, level} object in which the scheme structurally gates the permitted levels (ISO 26262 QM through ASIL D, IEC 61508 SIL 1 to 4, DO-178C DAL A to E, IEC 62304 Class A to C, EN 50128 SIL 0 to 4, plus a custom option for schemes beyond those five), reusing the same validation pattern the 2.0 threat model uses to gate categories by taxonomy. It attaches to an asset's classification within a blueprint and to requirements. Attaching it in the blueprint rather than on the bare component is deliberate, and it is your own core argument made structural: an integrity level is a property of a component in a system context, asserted by the party with system knowledge.

    The OpenSSL infusion pump record from your materials, expressed in 2.0:

    {
      "componentRef": "comp-openssl",
      "type": "module",
      "classification": {
        "criticality": "critical",
        "safetyIntegrityLevels": [
          { "scheme": "IEC-62304", "level": "class-c" }
        ]
      }
    }

    A validator rejects { "scheme": "ISO-26262", "level": "sil-3" } outright, so the vocabulary is enforced by schema rather than by tooling convention.

    Three enum additions ride along with it: EPSS as a first-class vulnerability scoring method, and hazard-analysis and safety-case external reference types for the evidence artifacts SRAP points at. Everything is additive, roughly 230 lines of schema across four files, and a complete worked example (the pump deployment, including the known unknown declared as an annotation and a scope exclusion) validates against the prototype.

    On the original questions in this issue: custom properties are the wrong vehicle, since the substance is already first-class and properties would fragment it. The taxonomy that most helps downstream tooling is the scheme and level vocabulary above, and I would like to keep that vocabulary aligned with the SPDX Safety Profile work so both ecosystems name levels identically even where the carriers differ. Alignment, not competition.

    If you can review the scheme set and the level vocabularies against what you are seeing in the ELISA and SPDX Safety Profile discussions, that feedback would land at exactly the right time given where 2.0 is in its lifecycle.

    fragment-safetyIntegrityLevel.json

    meridian-infusion-pump.cdx.json

    proposed-changes.patch

  4. devashridatta-dotcom commented on Jul 11, 2026

    @devashridatta-dotcom
    Author

    @stevespringett — this is exemplary. Thank you for the field-by-field mapping and for building the schema fragment, the worked example, and the patch. Seeing the infusion pump record expressed in 2.0 makes the integration path concrete in a way the proposal alone could not.
    The community discussion that followed the July 10 SBOM Everywhere SIG presentation is being tracked at ossf/sbom-everywhere#144, where Chris Blask has contributed additional schema refinements — including assertion provenance, safetyGoalRef / safetyFunctionRef, relationship roles (implements/supports/monitors / isolates/recovers), and structured knownUnknowns. The thread may be useful context as you finalize the 2.0 schema, particularly on the governance and provenance layer.

    A few reactions from the ELISA and SPDX Safety Profile discussions on July 10:
    On the scheme/level vocabulary: The five schemes you've defined — ISO 26262, IEC 61508, DO-178C, IEC 62304, EN 50128 cover the domains that came up in both the SBOM Everywhere and SPDX Safety Profile sessions. Kate Stewart specifically noted she wants to keep CycloneDX and SPDX level naming identical to avoid cross-ecosystem fragmentation. Your statement "alignment, not competition" maps exactly to what she said.
    On the blueprint as scope carrier: Allan Friedman's relationship-based framing from the July 10 session that safety relevance should be expressed as a relationship from system to component rather than a property on the component aligns perfectly with attaching the integrity level to an asset classification within a blueprint. This is the structural answer to the question he raised.
    On known unknowns: The annotation approach for declaring unassessed paths is exactly what the SBOM Everywhere discussion converged on. Pavel Shukhman (Reliza) specifically raised the need to express "this path has not been assessed" as a first-class state.
    One question: For the custom scheme option, is there a mechanism to register custom schemes in a versioned taxonomy, or is it free text? This came up in the SPDX Safety Profile discussion as a concern for tooling interoperability.
    I will review the patch and the full example against the SPDX Safety Profile draft vocabulary and report back. Will also share this with Kate Stewart so she can assess alignment from the SPDX side.

  5. devashridatta-dotcom commented on Jul 11, 2026

    @devashridatta-dotcom
    Author

    Thank you again for the detailed guidance. Following your suggested path, I've put together two example BOMs showing the same OpenSSL component expressed using existing CycloneDX 2.0 constructs risk, perspective, assetClassification, and criticality alongside a sketch of how the safetyIntegrity field would attach to those constructs.
    Example 1 Automotive (ISO 26262 / ASIL-D)

    {
      "bomFormat": "CycloneDX",
      "specVersion": "2.0",
      "metadata": {
        "timestamp": "2026-07-11T00:00:00Z",
        "component": {
          "type": "firmware",
          "name": "brake-by-wire-ecu",
          "version": "3.1.2",
          "manufacturer": "acme-automotive"
        }
      },
      "components": [
        {
          "type": "library",
          "name": "openssl",
          "version": "3.2.1",
          "purl": "pkg:generic/openssl@3.2.1",
          "bom-ref": "openssl-3.2.1"
        }
      ],
      "blueprints": [
        {
          "bom-ref": "bp-brake-ecu",
          "assetClassification": {
            "criticality": "critical"
          },
          "component": { "ref": "openssl-3.2.1" }
        }
      ],
      "perspectives": [
        {
          "bom-ref": "persp-automotive",
          "domains": [
            {
              "name": "automotive-safety",
              "description": "ISO 26262 — road vehicles functional safety",
              "standards": ["ISO 26262"]
            }
          ]
        }
      ],
      "risks": [
        {
          "bom-ref": "risk-brake-openssl",
          "affects": [
            { "ref": "openssl-3.2.1" }
          ],
          "domain": { "ref": "persp-automotive" },
          "impact": {
            "categories": ["safety", "physical"],
            "rating": "critical"
          },
          "relatedVulnerabilities": [],
          "description": "Compromise of OpenSSL in brake-by-wire TLS path could interfere with actuator command integrity"
        }
      ],
      "x-safetyIntegrity": {
        "_comment": "SIC sketch — proposed net-new field per #955",
        "ref": "openssl-3.2.1",
        "classification": {
          "scheme": "ISO26262",
          "level": "ASIL-D"
        },
        "normalizedLevel": "CRITICAL",
        "mitigationModifier": {
          "redundancyPresent": true,
          "isolationLevel": "hardware-enforced",
          "description": "dual-channel lockstep CPU with hardware watchdog"
        },
        "assertionBasis": {
          "assertedBy": "acme-automotive",
          "method": "certified",
          "reference": "TÜV-SÜD-2024-1187",
          "assertionDate": "2024-11-01"
        }
      }
    }

    Example 2 Medical (IEC 62304 / Class-C)

    {
      "bomFormat": "CycloneDX",
      "specVersion": "2.0",
      "metadata": {
        "timestamp": "2026-07-11T00:00:00Z",
        "component": {
          "type": "device",
          "name": "infusion-pump-controller",
          "version": "2.4.0",
          "manufacturer": "medtech-inc"
        }
      },
      "components": [
        {
          "type": "library",
          "name": "openssl",
          "version": "3.2.1",
          "purl": "pkg:generic/openssl@3.2.1",
          "bom-ref": "openssl-3.2.1"
        }
      ],
      "blueprints": [
        {
          "bom-ref": "bp-pump-ctrl",
          "assetClassification": {
            "criticality": "critical"
          },
          "component": { "ref": "openssl-3.2.1" }
        }
      ],
      "perspectives": [
        {
          "bom-ref": "persp-medical",
          "domains": [
            {
              "name": "patient-safety",
              "description": "IEC 62304 — medical device software lifecycle",
              "standards": ["IEC 62304", "FDA 21 CFR Part 820"]
            }
          ]
        }
      ],
      "risks": [
        {
          "bom-ref": "risk-pump-openssl",
          "affects": [
            { "ref": "openssl-3.2.1" }
          ],
          "domain": { "ref": "persp-medical" },
          "impact": {
            "categories": ["safety", "health"],
            "rating": "critical"
          },
          "relatedVulnerabilities": [],
          "description": "Compromise of OpenSSL in drug delivery TLS path could interfere with infusion rate commands — potential patient harm"
        }
      ],
      "x-safetyIntegrity": {
        "_comment": "SIC sketch — proposed net-new field per #955",
        "ref": "openssl-3.2.1",
        "classification": {
          "scheme": "IEC62304",
          "level": "Class-C"
        },
        "normalizedLevel": "CRITICAL",
        "mitigationModifier": {
          "redundancyPresent": false,
          "isolationLevel": "software-only",
          "description": "software watchdog with alarm escalation only"
        },
        "assertionBasis": {
          "assertedBy": "medtech-inc",
          "method": "self-declared",
          "reference": "FDA-510k-2024-K241892",
          "assertionDate": "2025-01-15"
        }
      }
    }
  6. devashridatta-dotcom commented on Jul 12, 2026

    @devashridatta-dotcom
    Author

    On reflection, I have placed x-safetyIntegrity as a top-level extension in the examples above for readability, but per your guidance, the correct attachment point is within the blueprint's assetClassification block, matching your meridian-infusion-pump.cdx.json example. The corrected automotive example:

    {
    "blueprints": [
    {
    "bom-ref": "bp-brake-ecu",
    "assetClassification": {
    "criticality": "critical",
    "safetyIntegrityLevels": [
    { "scheme": "ISO-26262", "level": "ASIL-D" }
    ]
    },
    "component": { "ref": "openssl-3.2.1" }
    }
    ]
    }
  7. devashridatta-dotcom commented on Jul 12, 2026

    @devashridatta-dotcom
    Author

    One open question from the cross-ecosystem alignment work in ossf/sbom-everywhere#144 that I would like to raise here for CycloneDX's input:
    Token case normalization proposed shared regex pattern
    The SRAP sidecar and SPDX Safety Profile preserve native regulatory typography (IEC 62304, Class C, ASIL-D). CycloneDX 2.0 enforces lowercase kebab-case (iec-62304, class-c, asil-d). Policy engines translating between formats currently have no agreed normalization rule.
    Proposed regex patterns as a shared reference:

    iso[\s-]?26262        →  iso-26262  /  ISO 26262
    iec[\s-]?61508        →  iec-61508  /  IEC 61508
    iec[\s-]?62304        →  iec-62304  /  IEC 62304
    do[\s-]?178c          →  do-178c    /  DO-178C
    en[\s-]?50128         →  en-50128   /  EN 50128
    asil[\s-]?[abcdABCD]  →  asil-d     /  ASIL-D
    sil[\s-]?[01234]      →  sil-4      /  SIL-4
    class[\s-]?[abcABC]   →  class-c    /  Class C
    dal[\s-]?[abcdeABCDE] →  dal-a      /  DAL-A
    qm                     →  qm         /  QM
    

    The SRAP validator (srap_validator.py v0.2) implements these patterns and normalizes to CycloneDX kebab-case at output. The question for CycloneDX: should the 2.0 schema accept these patterns via a regex constraint, or should a normalization pre-processor be the agreed standard approach before schema validation?

  8. stevespringett commented on Jul 12, 2026

    @stevespringett
    Member

    Preprocessor, not regex in the schema. 2.0 keeps exact match enums with one canonical token per value; srap_validator.py normalizing at output is the right division of labor.

    Three structural reasons. The scheme gates its permitted levels through conditional validation on exact tokens, which is what lets a validator reject {"scheme": "ISO-26262", "level": "sil-3"}; patterns dissolve that gating. meta:enum documentation keys on exact strings. And multiple accepted spellings of one fact break comparison, deduplication, signing, and the reversible rename into generated formats such as Protocol Buffers.

    One correction to the table: CycloneDX does not lowercase everything. Standard identifiers keep canonical casing, so schemes are ISO-26262, IEC-62304, and so on; only levels are kebab (asil-d, class-c). ASIL-D as a level fails the draft schema.

    Native typography already has a first class home: the perspective model maps JSONPath expressions to a nativeName, so a functional safety perspective renders asil-d as "ASIL D" without touching the machine vocabulary. We can publish a canonical functional safety perspective alongside the schema and carry your regex table as informative crosswalk material. Shared vocabulary and crosswalk, per serialization token rules: that is the achievable form of naming alignment.

  9. stevespringett commented on Jul 12, 2026

    @stevespringett
    Member

    Related to #955

  10. devashridatta-dotcom commented on Jul 12, 2026

    @devashridatta-dotcom
    Author

    Thank you for the correction on scheme casing and the preprocessor guidance. Updating the SRAP sidecar specification and validator accordingly scheme identifiers keep canonical casing (ISO-26262, IEC-62304) and only levels are kebab (asil-d, class-c).
    To make the SRAP to CycloneDX 2.0 mapping explicit, here is the full field-by-field reference based on your guidance on this thread and the three attached files which you shared

    SRAP sidecar field               CycloneDX 2.0 construct
    ───────────────────────────────  ──────────────────────────────────────────────────
    component_ref (purl)             components[].bom-ref + purl
    system_context                   blueprints[].bom-ref
    Independently signable scope carrier.
    Blueprint scope carries exclusions —
    equivalent to declared known unknowns in SRAP.
    safety_classifications[].scheme  blueprints[].assets[].classification
    .safetyIntegrityLevels[].scheme
    ISO-26262 | IEC-61508 | IEC-62304 |
    DO-178C | EN-50128 | custom {name, description}
    safety_classifications[].level   blueprints[].assets[].classification
    .safetyIntegrityLevels[].level
    asil-d | class-c | sil-2 | dal-a
    (kebab-case only — exact enum per scheme)
    failure_profile                  risks[].impact.categories
    safety | physical | health | environmental
    + risks[].impact.rating
    known_unknowns[]                 blueprints[].annotations[]
    with subjects[] referencing asset bom-refs
    + blueprint scope exclusions (prose)
    evidence_refs[]                  externalReferences[]
    types: hazard-analysis | safety-case
    (both added as first-class types in the patch)
    asserted_by / authority_role     components[].parties[].organization
    + parties[].roles[].role
    manufacturer | integrator | operator |
    auditor | regulator
    (cryptographically attributable)
    lifecycle                        Signature lifecycle on blueprint document
    safety_relationship.role         Blueprint data flows + behavior model
    (SRAP-native convenience layer —
    no direct CDX role enum)
    safety_goal_ref                  Not yet in CDX 2.0 
    safety_function_ref              Not yet in CDX 2.0 
    mitigation_controls              CDXA attestations + external references
    
    

    safety_goal_ref and safety_function_ref were contributed by Chris Blask during schema co-design on ossf/sbom-everywhere#144. They explain why a component matters to a specific safety goal and function the "why it matters" layer that sits above "what classification applies."

  11. devashridatta-dotcom commented on Aug 8, 2026

    @devashridatta-dotcom
    Author

    Update: SRAP was formally presented to the SPDX Functional Safety SIG on August 7, 2026. The group directed repositioning SRAP as a standardised communication format for change impact analysis, which aligns directly with the evidence model in #333.

    Meeting notes: https://docs.google.com/document/d/18BotF5QsrxT0dY4Ibq-SiADd0nYddMJkvHUU0qi4oxE

  12. jkowalleck commented on Aug 10, 2026

    @jkowalleck
    Member

    Meeting notes: https://docs.google.com/document/d/18BotF5QsrxT0dY4Ibq-SiADd0nYddMJkvHUU0qi4oxE

    @devashridatta-dotcom , the file is private - requested viewer/commenter access to it. You should have received my request notes.

  13. devashridatta-dotcom commented on Aug 21, 2026

    @devashridatta-dotcom
    Author

    Update for cross-ecosystem alignment: SPDX 3 model PR spdx/spdx-3-model#1436 has merged.

    The SPDX-side model now includes:

    • SafetyContextRelationship as a lifecycle-scoped relationship
    • optional safetyIntegrityLevel
    • SafetyIntegrityLevelType vocabulary covering ASIL, SIL, DAL, other, and noAssertion

    This aligns with the core modeling direction discussed here: safety integrity and safety relevance are context/relationship-scoped assertions, not intrinsic component properties.

    The useful next alignment point is vocabulary/crosswalk consistency: SPDX now has relationship-scoped ASIL/SIL/DAL labels, while the CycloneDX 2.0 discussion here has focused on scheme/level safety-integrity classification in system context. The SPDX merge gives a concrete counterpart for keeping the ecosystems aligned.

  14. devashridatta-dotcom commented on Aug 29, 2026

    @devashridatta-dotcom
    Author

    Follow-up proposal: document-level profile conformance for SRAP

    Building on this safety relevance proposal, I think the cleanest CycloneDX path is to separate two concerns:

    1. A document-level declaration that a BOM claims conformance to an external profile such as SRAP.
    2. The actual safety relevance assertions, which can live in existing CycloneDX structures such as declarations, claims, evidence, risks, perspectives, definitions, and properties.

    This avoids making "safety relevance" only a component-level property and gives validators a standard hook for profile-specific validation.

    Describe the feature

    Add an optional document-level profile conformance declaration to CycloneDX. Proposed primary location:

    {
      "metadata": {
        "profileConformance": [
          {
            "name": "SRAP",
            "version": "2.2",
            "canonicalId": "https://spdx.dev/profiles/srap/2.2",
            "schema": "https://example.org/srap-cdx-profile-2.2.schema.json",
            "schemaDialect": "https://json-schema.org/draft/2020-12/schema",
            "conformance": "strict",
            "hashes": [
              {
                "alg": "SHA-256",
                "content": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
              }
            ]
          }
        ]
      }
    }

    The declaration means:

    This BOM claims conformance to profile name at version, and the referenced schema defines how the profile-specific content should be validated.

    It does not mean every component in the BOM is safety-relevant. Component-level and assertion-level safety relevance should remain expressed in the BOM content itself.

    For CycloneDX 2.0-dev, SRAP content appears to map naturally to existing structures:

    • declarations.claims for SRAP assertions such as ChangeTrigger, ChangeImpactAnalysis, and RequirementVerification
    • declarations.evidence for supporting evidence
    • root-level risks.risks[] for safety risks
    • root-level perspectives[] for safety context views, using mappings[].expression
    • definitions.standards[].requirements for safety requirements
    • properties or structured ext:* extensions such as ext:spdx.dev:srap for SRAP-specific fields

    Possible solution

    Define a reusable profile conformance object with fields such as:

    • name: short profile identifier, for example SRAP
    • version: profile version
    • canonicalId: stable version-pinned IRI for the profile
    • schema: IRI of the profile JSON Schema document
    • schemaDialect: JSON Schema dialect URI
    • conformance: strict or advisory
    • hashes: cryptographic hashes of the schema document

    In strict mode, I recommend that hashes be required. Without schema integrity checking, a profile declaration can be weakened by substituting the schema source, which is a real attack surface in regulated environments.

    Schema sketch:

    {
      "profileConformance": {
        "type": "array",
        "uniqueItems": true,
        "description": "Declares that this BOM claims conformance to one or more external profiles and identifies the schema used to validate that claim.",
        "items": {
          "type": "object",
          "required": ["name", "version", "schema"],
          "additionalProperties": false,
          "if": {
            "properties": {
              "conformance": { "const": "strict" }
            },
            "required": ["conformance"]
          },
          "then": {
            "required": ["name", "version", "schema", "hashes"],
            "properties": {
              "hashes": { "minItems": 1 }
            }
          },
          "properties": {
            "name": { "type": "string", "minLength": 1 },
            "version": { "type": "string", "minLength": 1 },
            "canonicalId": { "type": "string", "format": "iri-reference" },
            "schema": { "type": "string", "format": "iri-reference" },
            "schemaDialect": { "type": "string", "format": "iri-reference" },
            "conformance": {
              "type": "string",
              "enum": ["strict", "advisory"],
              "default": "advisory"
            },
            "hashes": {
              "type": "array",
              "minItems": 1,
              "items": {
                "$ref": "cyclonedx-common-2.0.schema.json#/$defs/hash"
              }
            }
          }
        }
      }
    }

    Validator behavior could be:

    • Resolve the profile schema from a local schema cache, profile registry, or the declared schema IRI.
    • If hashes are present, verify the resolved schema before applying it.
    • If conformance is strict and hashes are absent, fail validation.
    • If conformance is strict and the schema cannot be resolved, fail validation or return indeterminate for validators that support tri-state results.
    • If conformance is advisory and the schema cannot be resolved, warn and continue base CycloneDX validation.
    • Treat profile validation as an overlay on top of base CycloneDX validation.

    Alternatives

    One alternative is to place this under the existing root-level profiles object as:

    {
      "profiles": {
        "conformanceProfiles": []
      }
    }

    That may be preferable if maintainers want all profile-related concepts grouped together. My only concern is that CycloneDX 2.0-dev already appears to use root-level profiles as a catalog of reusable characterizations such as dataProfiles and threatProfiles, while this proposal is a conformance declaration about the BOM document itself.

    Another alternative is to keep SRAP entirely in properties or ext:* extensions. That works for producers and consumers that already agree out of band, but it does not give validators a standard way to discover which external profile is in use or which schema should be applied.

    Additional context

    This proposal is intentionally not asking CycloneDX maintainers to own SRAP semantics. The SRAP companion schema could be maintained by SRAP maintainers, an SPDX Functional Safety group, or another external profile owner. CycloneDX would only provide the standard declaration hook.

    This would also help organizations that exchange CycloneDX BOMs but do not exchange SPDX documents. They could still preserve SRAP-style safety relevance assertions in CycloneDX while making the profile claim and validation rules explicit.

    Open questions for maintainers:

    1. Should this live at metadata.profileConformance, or under root profiles as profiles.conformanceProfiles?
    2. Should strict conformance require hashes? I recommend yes.
    3. Should CycloneDX define a registry pattern for known external profiles, or accept any resolvable IRI?
    4. Should profile validation be specified as validator behavior, or left as non-normative guidance?
    5. Should the SRAP mapping guidance explicitly recommend risks and perspectives for CycloneDX 2.0-dev?
  15. devashridatta-dotcom commented on Sep 1, 2026

    @devashridatta-dotcom
    Author

    Revised Proposal Based on discussion:

    Proposed direction

    1. Keep base CycloneDX as the carrier.
    2. Keep SRAP semantics in an external profile schema unless TC54 decides a field belongs in core.
    3. Use existing 2.0 structures for impact, domain, component linkage, VEX linkage, evidence, and requirements.
    4. Keep the native CycloneDX change small: standards-aligned safety integrity classification appears to be the genuinely missing field.
    5. Use srap:* or ext:* only as compatibility/profile terms, not cyclonedx:* draft properties.

    Field-level mapping

    SRAP concept CycloneDX carrier today Field/profile term to define
    Profile declaration metadata.profileConformance or profiles.conformanceProfiles name, version, canonicalId, schema, conformance, hashes
    Safety context relationship Claims, risks, perspectives, blueprint asset classification, requirement references SafetyContextRelationship, relationshipType, scope, from, to
    Safety integrity classification Candidate native field on contextual asset classification and requirements safetyIntegrityLevels[] with { scheme, level }
    Change trigger Vulnerability, supplier notice, formulation/build/deployment change, external reference, or evidence record ChangeTrigger, triggerType, source, triggerRef
    Change impact analysis Risk entry plus claims/evidence/attestation mapping ChangeImpactAnalysis, status, impactLevel, affectedRefs, rationale
    Requirement verification declarations.attestations[].map[], conformance, confidence, evidence RequirementVerification, verificationMethod, evaluationResult
    Evidence relationship declarations.claims[].evidence[], counterEvidence[], and external references EvidenceRelationship, supports, contradicts, investigates, verifies

    Compatibility path

    For CycloneDX 1.7 and current tooling, SRAP can be represented without changing the base schema by using metadata.properties, component.properties, definitions.standards[].requirements[], declarations.claims[], declarations.attestations[].map[], and declarations.evidence[].

    For CycloneDX 2.0, I think the proposal should avoid adding a separate safety metadata block. The preferred direction seems to be using risks, perspectives, blueprints, criticality, declarations, claims, attestations, and evidence, with only the missing safety integrity classification vocabulary added or standardized.

    Open questions

    1. Should profileConformance live under metadata, or under root-level profiles?
    2. Should strict profile conformance require schema hashes?
    3. Should safetyIntegrityLevels[] attach to blueprint asset classification, requirements, or both?
    4. Should SRAP profile validation be specified normatively, or as validator guidance layered on top of base CycloneDX validation?
    5. Should the SRAP vocabulary be maintained outside CycloneDX, with CycloneDX only standardizing the profile hook and reusable safety integrity fields?

    This keeps SRAP aligned with SPDX safety work while respecting CycloneDX's existing model and 2.0 direction.

  16. devashridatta-dotcom commented on Sep 1, 2026

    @devashridatta-dotcom
    Author

    Alignment update: #1041 as the narrow implementation candidate

    I updated PR #1041 to align with the direction discussed here.

    The key change in framing is that #1041 is intentionally narrow. It does not try to add the full SRAP vocabulary to CycloneDX core, and it does not treat safety relevance as a flat component-level property. Instead, it focuses on the small native gap identified in this discussion: standards-aligned safety integrity classification.

    How I see the split now

    Existing CycloneDX carriers

    For the broader SRAP model, CycloneDX 2.0 already appears to provide the right carriers:

    • risks for safety impact and risk linkage.
    • perspectives and blueprints for system/context views.
    • criticality for contextual asset importance.
    • vulnerabilities and VEX analysis for vulnerability impact.
    • declarations, claims, attestations, and evidence for assertion and evidence chains.
    • definitions.requirements for safety requirements.

    Narrow native gap

    The piece that still appears useful in CycloneDX core is a reusable, machine-readable safety integrity classification:

    {
      "safetyIntegrityLevels": [
        {
          "scheme": "ISO-26262",
          "level": "asil-d"
        }
      ]
    }

    PR #1041 currently models this with scheme-gated levels for ISO 26262, IEC 61508, DO-178C, IEC 62304, and EN 50128, plus a custom scheme option.

    This keeps CycloneDX aligned with automotive/product-risk work while allowing SRAP to stay compatible with SPDX safety work at the profile layer.

    Question for maintainers: is #1041 the right narrow shape to prepare for RFC, while #954 continues as the design thread for broader SRAP profile guidance?

  17. kaylinloose commented on Sep 23, 2026

    @kaylinloose

    @devashridatta-dotcom I think that in addition to the consequence classes you have listed you should consider adding information disclosure and denial of service. For some softwares and their components those are the worst things that can happen, it doesn't necessarily concern physical safety as much as privacy. I think this is a really great addition thank you.

  18. devashridatta-dotcom commented on Sep 23, 2026

    @devashridatta-dotcom
    Author

    @kaylinloose Thank you, that is a good point. I agree that information disclosure and denial of service are important consequences, especially for software where the primary harm is privacy loss, confidentiality loss, or service unavailability rather than physical safety.

    I think the clean CycloneDX mapping is to represent those through the broader risk model rather than as safety integrity levels themselves:

    • Information disclosure maps to risk attributes such as confidentiality and privacy, with impact categories such as privacy, regulatory, or financial depending on the case.
    • Denial of service maps to availability, with impact categories such as operational, and potentially safety or health if service loss can lead to harm.

    So I agree these should be considered in the examples and guidance. For SRAC/safety, they become especially important when the disclosure or service loss affects a safety-relevant context.

  19. jkowalleck commented on Sep 28, 2026

    @jkowalleck
    Member

    RFC notice sent on 21 September 2026.
    RFC period ends on 19 October 2026.

  20. devashridatta-dotcom commented on Oct 20, 2026

    @devashridatta-dotcom
    Author

    Thank you to everyone who contributed to this discussion and implementation. PR #1120 has now merged into 2.0-dev; it explicitly closes this issue and supersedes my implementation proposal #1041. Closing this issue as completed. Any remaining SRAP profile guidance or examples can be tracked separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions