Files
breakpilot-compliance/backend-compliance/compliance/reasoning/rules_obligations_cra.py
T
Benjamin Admin 1607c89459 feat(reasoning): Regulatory Reasoning Engine MVP (scope/obligations/implementation/interpretation)
Deterministic reasoning layer ON TOP of the Legal Knowledge Graph (obligation
registry) and the Compliance Execution Graph (control mapping/evidence). Answers
which regulations apply to a concrete product, which obligations follow, whether
the customer's implementation covers them, and whether a customer interpretation
is too narrow/broad/plausible.

- ProductProfile with tri-state facts (Optional[bool]=None => uncertain, never
  false security); safe predicate evaluator (no eval).
- 6 regulation triggers (CRA/MaschinenVO/RED/EMV/DataAct/NIS2) with missing-fact
  prompts; 24 obligation scope rules.
- CRA obligation_ids RE-USED verbatim from the registry (93 ids) — never re-minted
  (control_uuid trap); Machine/Data-Act flagged proposed=True.
- required_evidence constrained to the framework-agnostic shared evidence catalog;
  capabilities echo the planned Obligation->Capability layer.
- Overlap groups (CRA<->MaschinenVO cyber-safety) + evidence-for-multiple (USP).
- 4 endpoints POST /reasoning/{scope,obligations,implementation-assessment,
  interpretation-assessment}; thin handlers, registered in api/__init__.py.
- 22 tests (5 machine-builder scenarios + 10 acceptance questions). No DB
  migration, no RAG, no new controls.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-25 19:30:53 +02:00

272 lines
12 KiB
Python

"""CRA obligation scope rules.
`obligation_id`s in the six CRA-P1 families (sbom/vuln/authentication/logging/
remote_access/updates) are RE-USED verbatim from the Legal-KG registry
(`obligations/obligation_join_keys.json`) — never re-minted (control_uuid trap,
memory `project_compliance_graph.md`). Cross-cutting CRA *process* obligations
(risk assessment, technical documentation, CE, instructions, secure-by-design
umbrella) are not yet in the registry and are flagged `proposed=True`.
"""
from __future__ import annotations
from typing import List
from .enums import AuthorityLevel, Confidence
from .rules_types import ObligationRule
_HAS_SW = ("has_software", "eq", True)
_EU = ("eu_market", "eq", True)
_REMOTE_OR_CLOUD = {"any": [("has_remote_access", "eq", True), ("has_cloud_connection", "eq", True)]}
_LM = AuthorityLevel.LEGAL_TEXT
CRA_OBLIGATIONS: List[ObligationRule] = [
ObligationRule(
obligation_id="sbom_creation",
title="Software Bill of Materials erstellen",
source_regulation="CRA",
obligation_text="Eine SBOM erstellen, die mindestens die obersten Abhängigkeiten des Produkts dokumentiert.",
legal_basis_refs=["CRA Annex I Part II (1)"],
authority_level=_LM,
family="sbom",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["software_bill_of_materials"],
required_evidence=["sbom", "repo_scan"],
lifecycle_phase=["development", "placing_on_market", "maintenance"],
registry_anchor=True,
),
ObligationRule(
obligation_id="provide_security_updates",
title="Sicherheitsupdates bereitstellen",
source_regulation="CRA",
obligation_text="Sicherheitsrelevante Updates zeitnah und über den Supportzeitraum bereitstellen.",
legal_basis_refs=["CRA Annex I (2)(c)", "CRA Art. 13"],
authority_level=_LM,
family="updates",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["secure_updates"],
required_evidence=["policy", "ticket", "test_report"],
lifecycle_phase=["maintenance", "update"],
overlap_group_id="SECURITY_UPDATES",
registry_anchor=True,
),
ObligationRule(
obligation_id="support_period_maintenance",
title="Supportzeitraum definieren und einhalten",
source_regulation="CRA",
obligation_text="Einen angemessenen Supportzeitraum festlegen, in dem Schwachstellen behandelt werden.",
legal_basis_refs=["CRA Art. 13(8)"],
authority_level=_LM,
family="updates",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["secure_updates"],
required_evidence=["policy"],
lifecycle_phase=["placing_on_market", "maintenance", "update"],
registry_anchor=True,
),
ObligationRule(
obligation_id="signed_update_integrity",
title="Integrität von Updates sicherstellen",
source_regulation="CRA",
obligation_text="Updates signieren und ihre Integrität bei der Verteilung verifizieren.",
legal_basis_refs=["CRA Annex I (1)(3)(f)"],
authority_level=_LM,
family="updates",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["software_integrity"],
required_evidence=["config_export", "test_report"],
lifecycle_phase=["development", "maintenance", "update"],
overlap_group_id="SECURITY_UPDATES",
registry_anchor=True,
),
ObligationRule(
obligation_id="vuln_handling_process",
title="Schwachstellenbehandlungs-Prozess",
source_regulation="CRA",
obligation_text="Einen dokumentierten Prozess zur Identifikation, Bewertung und Behebung von Schwachstellen betreiben.",
legal_basis_refs=["CRA Art. 13(8)", "CRA Annex VII"],
authority_level=_LM,
family="vuln",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["vulnerability_management"],
required_evidence=["policy", "ticket"],
lifecycle_phase=["development", "operation", "maintenance"],
overlap_group_id="VULNERABILITY_HANDLING",
registry_anchor=True,
),
ObligationRule(
obligation_id="coordinated_vulnerability_disclosure",
title="Coordinated Vulnerability Disclosure",
source_regulation="CRA",
obligation_text="Eine Richtlinie zur koordinierten Offenlegung von Schwachstellen bereitstellen.",
legal_basis_refs=["CRA Annex I Part II (5)"],
authority_level=_LM,
family="vuln",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["coordinated_disclosure"],
required_evidence=["policy"],
lifecycle_phase=["operation", "maintenance"],
overlap_group_id="VULNERABILITY_HANDLING",
registry_anchor=True,
),
ObligationRule(
obligation_id="exploited_vuln_reporting_authorities",
title="Meldung aktiv ausgenutzter Schwachstellen / Vorfälle",
source_regulation="CRA",
obligation_text="Aktiv ausgenutzte Schwachstellen und schwerwiegende Vorfälle an die zuständigen Behörden melden.",
legal_basis_refs=["CRA Art. 14", "CRA Art. 16"],
authority_level=_LM,
family="vuln",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["incident_reporting"],
required_evidence=["policy", "ticket"],
lifecycle_phase=["operation", "maintenance"],
registry_anchor=True,
),
ObligationRule(
obligation_id="user_authentication_required",
title="Authentifizierung vorsehen",
source_regulation="CRA",
obligation_text="Den Zugang über einen geeigneten Authentifizierungsmechanismus schützen.",
legal_basis_refs=["CRA Annex I (2)(d)"],
authority_level=_LM,
family="authentication",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["authentication"],
required_evidence=["config_export", "pentest"],
lifecycle_phase=["development", "operation"],
registry_anchor=True,
),
ObligationRule(
obligation_id="no_default_credentials",
title="Keine unveränderlichen Standard-Zugangsdaten",
source_regulation="CRA",
obligation_text="Sichere Standardkonfiguration; keine fest hinterlegten oder unveränderlichen Standard-Passwörter.",
legal_basis_refs=["CRA Annex I (2)(a)", "CRA Annex I (2)(b)"],
authority_level=_LM,
family="authentication",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["secure_by_default"],
required_evidence=["config_export", "test_report"],
lifecycle_phase=["development", "placing_on_market"],
registry_anchor=True,
),
ObligationRule(
obligation_id="event_logging_security_events",
title="Sicherheitsrelevante Ereignisse protokollieren",
source_regulation="CRA",
obligation_text="Sicherheitsrelevante Ereignisse und Zugriffe aufzeichnen, um Vorfälle nachvollziehen zu können.",
legal_basis_refs=["CRA Annex I Part I (2)(k)"],
authority_level=_LM,
family="logging",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["security_logging"],
required_evidence=["config_export", "audit_log"],
lifecycle_phase=["operation", "maintenance"],
registry_anchor=True,
),
ObligationRule(
obligation_id="remote_access_attack_surface_min",
title="Angriffsfläche minimieren",
source_regulation="CRA",
obligation_text="Die Angriffsfläche begrenzen, insbesondere exponierte Remote-/Cloud-Schnittstellen.",
legal_basis_refs=["CRA Annex I (1)(2)(a)"],
authority_level=_LM,
family="remote_access",
applies_if={"all": [_REMOTE_OR_CLOUD, _EU]},
required_capabilities=["secure_by_default"],
required_evidence=["config_export", "repo_scan", "pentest"],
lifecycle_phase=["development", "operation"],
registry_anchor=True,
),
ObligationRule(
obligation_id="remote_access_confidentiality_integrity",
title="Vertraulichkeit/Integrität der Fernverbindung",
source_regulation="CRA",
obligation_text="Daten bei Fernzugriff/Cloud-Anbindung verschlüsselt und integritätsgeschützt übertragen.",
legal_basis_refs=["CRA Annex I (1)(2)(b)", "CRA Annex I (1)(2)(c)"],
authority_level=_LM,
family="remote_access",
applies_if={"all": [_REMOTE_OR_CLOUD, _EU]},
required_capabilities=["secure_communication"],
required_evidence=["config_export", "pentest"],
lifecycle_phase=["operation"],
registry_anchor=True,
),
# --- Cross-cutting CRA process obligations (not yet in registry) ---------
ObligationRule(
obligation_id="cra_secure_by_design",
title="Security by Design",
source_regulation="CRA",
obligation_text="Das Produkt so entwerfen, entwickeln und herstellen, dass ein angemessenes Cybersicherheitsniveau gewährleistet ist.",
legal_basis_refs=["CRA Annex I Part I (1)"],
authority_level=_LM,
family="cra_process",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["secure_by_default", "risk_assessment"],
required_evidence=["policy", "test_report"],
lifecycle_phase=["development", "placing_on_market"],
proposed=True,
),
ObligationRule(
obligation_id="cra_risk_assessment",
title="Cybersicherheits-Risikobewertung",
source_regulation="CRA",
obligation_text="Eine Cybersicherheits-Risikobewertung durchführen und dokumentieren; in die technische Dokumentation aufnehmen.",
legal_basis_refs=["CRA Art. 13(2)", "CRA Annex I Part I (1)"],
authority_level=_LM,
family="cra_process",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["risk_assessment"],
required_evidence=["policy"],
lifecycle_phase=["development", "placing_on_market"],
overlap_group_id="RISK_ASSESSMENT",
proposed=True,
),
ObligationRule(
obligation_id="cra_technical_documentation",
title="Technische Dokumentation",
source_regulation="CRA",
obligation_text="Technische Dokumentation erstellen und aktuell halten, die Konformität mit den Anforderungen belegt.",
legal_basis_refs=["CRA Art. 31", "CRA Annex VII"],
authority_level=_LM,
family="cra_process",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["technical_documentation"],
required_evidence=["policy"],
lifecycle_phase=["placing_on_market", "maintenance"],
overlap_group_id="TECHNICAL_DOCUMENTATION",
proposed=True,
),
ObligationRule(
obligation_id="cra_ce_conformity_assessment",
title="Konformitätsbewertung / CE-Kennzeichnung",
source_regulation="CRA",
obligation_text="Vor dem Inverkehrbringen das passende Konformitätsbewertungsverfahren durchlaufen und CE kennzeichnen.",
legal_basis_refs=["CRA Art. 32", "CRA Art. 28"],
authority_level=_LM,
family="cra_process",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["conformity_assessment"],
required_evidence=["test_report", "policy"],
lifecycle_phase=["placing_on_market"],
overlap_group_id="CE_CONFORMITY",
proposed=True,
),
ObligationRule(
obligation_id="cra_instructions_for_use",
title="Informationen und Anweisungen für Nutzer",
source_regulation="CRA",
obligation_text="Nutzern verständliche Sicherheitsinformationen und -anweisungen bereitstellen (z. B. zu Updates und Support-Ende).",
legal_basis_refs=["CRA Annex II"],
authority_level=_LM,
family="cra_process",
applies_if={"all": [_HAS_SW, _EU]},
required_capabilities=["technical_documentation"],
required_evidence=["policy"],
lifecycle_phase=["placing_on_market"],
overlap_group_id="INSTRUCTIONS_FOR_USE",
proposed=True,
),
]