# Signal Vocabulary — canonical signal id + aliases + KIND. One language, but TWO kinds of signal. # # The same fact ("SBOM present") can arrive as CycloneDX, SPDX, a GitHub Action, a Maven plugin, a # document upload or a customer statement — for the Silent Pass they are ALL `sbom_present`. This file # reduces producer dialects to one canonical signal — same pattern as the regulation-alias vocabulary, # MCAPs and Requirement Sources: many inputs, one language. No scanner-specific logic reaches the Silent # Pass. Pure DATA, injected into normalize_signals(). No real names. # # KIND is the load-bearing distinction (default: observation): # observation = "I SAW X" — a repo with an SBOM, a published security.txt, a risk-assessment PDF. # requirement = "someone DEMANDS X" — a tender clause `requires_sbom`, an OEM spec `supplier_requires_psirt`. # A DEMANDED SBOM is NOT a PRESENT SBOM. `kind` lives on the canonical entry (AUTHORITATIVE), so even a # mislabelled producer signal cannot collapse the two. The Silent Pass consumes ONLY observations; # requirement signals are preserved (requirements_seen) and drive the required-set / prioritisation later # (Requirement Source). This is the Observation-vs-Requirement split the Verification Platform rests on. signals: # ── OBSERVATIONS — "I saw X" (kind: observation, the default) ──────────────────────────────── - {id: sbom_present, aliases: [cyclonedx_found, spdx_found, sbom_in_repo, sbom_uploaded]} - {id: cvd_policy_present, aliases: [security_txt, vdp_found, cvd_policy_pdf, psirt_page, coordinated_disclosure_policy]} - {id: signed_releases, aliases: [signed_artifacts, cosign_found, gpg_signed_releases, code_signing_cert, secure_boot]} - {id: github_actions_ci, aliases: [ci_pipeline, gitlab_ci, jenkins_pipeline, build_automation]} - {id: dependency_scanning, aliases: [dependabot, renovate, snyk_found, trivy_in_ci, sca_tool]} - {id: ce_marking_on_site, aliases: [ce_logo_detected, ce_mark_image]} - {id: ce_conformity_doc, aliases: [declaration_of_conformity_doc, ce_doc_uploaded, conformity_pdf]} - {id: support_lifecycle_page, aliases: [eol_policy_page, lifecycle_doc, support_period_stated]} - {id: security_policy_page, aliases: [isms_statement, iso27001_badge, security_overview_page]} - {id: product_risk_assessment_doc, aliases: [risk_assessment_pdf, hazard_analysis_doc, tara_doc]} - {id: patch_policy_doc, aliases: [patch_management_policy, update_policy_pdf]} - {id: incident_response_plan_doc, aliases: [irp_doc, incident_playbook]} # product facts (also observations: an observed product property that drives scope) - {id: cloud_connectivity, aliases: [cloud_hosted, saas, internet_facing, connected_product]} - {id: plc_sps, aliases: [plc_detected, sps_steuerung, industrial_controller]} - {id: embedded_software, aliases: [firmware_present, embedded_device]} - {id: wireless_radio, aliases: [bluetooth, wifi_module, radio_equipment, funkmodul]} - {id: remote_access, aliases: [remote_maintenance, vpn_access, teleservice, fernwartung]} - {id: generates_usage_data, aliases: [telemetry_collected, usage_analytics]} # ── REQUIREMENTS — "someone DEMANDS X" (kind: requirement; NEVER read as present) ───────────── # Preserved + visible, but the Silent Pass does NOT turn them into detected capabilities. A tender / # OEM spec / law lands here; a scanner / repo / document lands above. Intentionally UNMAPPED in # intake_signal_map.yaml — they describe the target, not the present state. - {id: sbom_required, kind: requirement, aliases: [requires_sbom, sbom_in_tender, tender_requires_sbom]} - {id: psirt_required, kind: requirement, aliases: [supplier_requires_psirt, requires_psirt, requires_cvd, oem_requires_psirt]} - {id: signed_updates_required, kind: requirement, aliases: [requires_signed_updates, supplier_requires_signed_updates]}