feat(cra): Phase 5 — Technical Doc + DoC Generator (Annex V + VII)
CI / detect-changes (push) Successful in 11s
CI / branch-name (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 15s
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 16s
CI / go-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m1s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 39s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / detect-changes (push) Successful in 11s
CI / branch-name (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 15s
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 16s
CI / go-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m1s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 39s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
Migration 122: compliance_cra_documents with versioning + approval workflow
- doc_type whitelist: doc_eu_conformity, doc_technical, doc_cvd_policy,
doc_update_policy, doc_sbom_report
- Status state machine: draft → reviewed → approved (+ superseded)
- Snapshot generation_context for audit trail
New module cra_doc_templates.py — pure-function generators (no DB access):
- doc_eu_conformity: EU DoC structured per CRA Annex VII (all 7 mandatory fields)
- doc_technical: Technische Dokumentation per CRA Annex V
- doc_cvd_policy: ISO/IEC 29147-compliant CVD policy with SLA table
- doc_update_policy: Patch/Update policy with Lifecycle + CSAF reference
- doc_sbom_report: Latest SBOM summary with top-10 components
Returns (title, markdown_content, requirements_coverage) — coverage tracks
how many mandatory fields are filled vs placeholders.
Backend endpoints:
- POST /documents/generate — generates doc, supersedes previous version,
increments version number atomically
- GET /documents — lists all 5 doc types (also "not_generated" stubs)
- GET /documents/{id} — full content_md
- POST /documents/{id}/approve — set status + signed_by + signed_at
Frontend:
- /documents page: 5 doc-type cards with Generate/Re-Generate buttons,
inline Markdown preview with .md download, 2-step approval flow
(reviewed → approved with signature)
- Optional params form: manufacturer, notified_body, security_contact
- Dashboard: +1 button (Dokumente, 7 buttons total)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,444 @@
|
||||
"""
|
||||
CRA Document Templates — generates Markdown documents from project state.
|
||||
|
||||
Each template takes a project dict + optional context (sboms, vulnerabilities,
|
||||
checks) and returns (title, markdown_content). Pure functions, no DB access.
|
||||
|
||||
Templates implement:
|
||||
- doc_eu_conformity — EU Declaration of Conformity (CRA Annex VII)
|
||||
- doc_technical — Technische Dokumentation (CRA Annex V)
|
||||
- doc_cvd_policy — Coordinated Vulnerability Disclosure Policy
|
||||
- doc_update_policy — Update / Patch Policy
|
||||
- doc_sbom_report — SBOM-Zusammenfassung
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
|
||||
PATH_LABELS = {
|
||||
"self_assessment": "Modul A — Self-Assessment durch Hersteller",
|
||||
"harmonized_standard": "Modul B — Harmonisierte Norm",
|
||||
"eucc": "Modul H — EUCC-Zertifizierung",
|
||||
"notified_body": "Modul C — Konformitaetsbewertung durch Notified Body",
|
||||
}
|
||||
|
||||
CLASS_LABELS = {
|
||||
"NOT_IN_SCOPE": "Nicht im CRA-Scope",
|
||||
"STANDARD": "Standard-Produkt mit digitalen Elementen",
|
||||
"IMPORTANT_I": "Wichtiges Produkt — Annex III Klasse I",
|
||||
"IMPORTANT_II": "Wichtiges Produkt — Annex III Klasse II",
|
||||
"CRITICAL": "Kritisches Produkt — Annex IV",
|
||||
}
|
||||
|
||||
|
||||
def _today() -> str:
|
||||
return datetime.utcnow().strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
def _fmt_or_placeholder(v: Optional[str], placeholder: str = "[zu ergaenzen]") -> str:
|
||||
return v if v else placeholder
|
||||
|
||||
|
||||
def doc_eu_conformity(project: dict, *, manufacturer: Optional[str] = None,
|
||||
notified_body: Optional[str] = None) -> tuple[str, str]:
|
||||
"""EU Declaration of Conformity nach CRA Annex VII.
|
||||
|
||||
Pflichtfelder gemaess CRA Art. 28 + Annex VII:
|
||||
1. Produkt + Modell + eindeutige Kennung
|
||||
2. Hersteller + Anschrift
|
||||
3. (Optional) Bevollmaechtigter
|
||||
4. Konformitaetserklaerung mit Bezug auf CRA
|
||||
5. Verweis auf angewandte harmonisierte Normen
|
||||
6. Notified Body (falls Modul C)
|
||||
7. Datum + Ort + Unterschrift
|
||||
"""
|
||||
name = project.get("name", "[zu ergaenzen]")
|
||||
classification = project.get("cra_classification", "unbewertet")
|
||||
path = project.get("conformity_path", "self_assessment")
|
||||
path_label = PATH_LABELS.get(path, path)
|
||||
class_label = CLASS_LABELS.get(classification, classification)
|
||||
desc = project.get("description") or project.get("intended_use") or ""
|
||||
|
||||
title = f"EU-Konformitaetserklaerung — {name}"
|
||||
|
||||
content = f"""# EU-Konformitaetserklaerung (DoC)
|
||||
**Gemaess Verordnung (EU) 2024/2847 — Cyber Resilience Act, Anhang VII**
|
||||
|
||||
---
|
||||
|
||||
## 1. Eindeutige Kennung des Produkts
|
||||
|
||||
**Produktname:** {name}
|
||||
**Modell / Typ:** {_fmt_or_placeholder(project.get('primary_language'), 'Software-Produkt')}
|
||||
**Repository / Source:** {_fmt_or_placeholder(project.get('repo_url'), '[Repo-URL ergaenzen]')}
|
||||
**Beschreibung:** {desc or '[Produktbeschreibung ergaenzen]'}
|
||||
|
||||
## 2. Hersteller
|
||||
|
||||
**Name:** {_fmt_or_placeholder(manufacturer, '[Hersteller-Name + Adresse ergaenzen]')}
|
||||
**Anschrift:** [zu ergaenzen]
|
||||
**Kontakt:** [zu ergaenzen]
|
||||
|
||||
## 3. Bevollmaechtigter (Authorised Representative)
|
||||
|
||||
[Falls Hersteller nicht in EU ansaessig — sonst entfallen]
|
||||
|
||||
## 4. Konformitaetserklaerung
|
||||
|
||||
Die alleinige Verantwortung fuer die Ausstellung dieser Konformitaetserklaerung
|
||||
traegt der Hersteller. Der Gegenstand der oben beschriebenen Erklaerung
|
||||
**erfuellt die einschlaegigen Harmonisierungsrechtsvorschriften der Union**:
|
||||
|
||||
- **Verordnung (EU) 2024/2847** (Cyber Resilience Act) — vollstaendig
|
||||
einschliesslich der **wesentlichen Cybersicherheitsanforderungen nach
|
||||
Anhang I**.
|
||||
|
||||
**CRA-Klassifizierung:** {class_label}
|
||||
**Angewandtes Konformitaetsbewertungsverfahren:** {path_label}
|
||||
|
||||
## 5. Verweise auf angewandte harmonisierte Normen und technische Spezifikationen
|
||||
|
||||
- Harmonisierte Norm: DIN EN 40000-1-2 (Entwurf, Stand 11/2025)
|
||||
- ETSI EN 303 645 (Consumer-IoT-Cybersicherheit)
|
||||
- ISO/IEC 29147 (Vulnerability Disclosure)
|
||||
- ISO/IEC 30111 (Vulnerability Handling Processes)
|
||||
- ENISA Technical Implementation Guidance (NIS2-Bezug)
|
||||
|
||||
## 6. Notified Body
|
||||
|
||||
{'_' if not notified_body else notified_body}
|
||||
{'Identifikationsnummer: [zu ergaenzen]' if notified_body else '(keine — Self-Assessment durch Hersteller)'}
|
||||
|
||||
## 7. Zusatzangaben
|
||||
|
||||
Diese Konformitaetserklaerung wurde unterzeichnet im Namen von:
|
||||
|
||||
**Ort, Datum:** [zu ergaenzen], {_today()}
|
||||
**Name, Funktion:** [zu ergaenzen]
|
||||
**Unterschrift:** ___________________________
|
||||
|
||||
---
|
||||
|
||||
*Diese Erklaerung wurde automatisch aus dem BreakPilot CRA-Modul generiert.
|
||||
Pflichtangaben sind als `[zu ergaenzen]` markiert und muessen vor Inverkehrbringen
|
||||
ausgefuellt + manuell unterzeichnet werden.*
|
||||
"""
|
||||
coverage = {
|
||||
"doc_type": "doc_eu_conformity",
|
||||
"annex_anchor": "CRA Anhang VII",
|
||||
"fields_required": 7,
|
||||
"fields_filled": sum(1 for v in [name, classification, path, desc] if v and not str(v).startswith("[")),
|
||||
}
|
||||
return title, content, coverage
|
||||
|
||||
|
||||
def doc_technical(project: dict) -> tuple[str, str, dict]:
|
||||
"""Technische Dokumentation nach CRA Annex V."""
|
||||
name = project.get("name", "[Produktname]")
|
||||
desc = project.get("description") or project.get("intended_use") or ""
|
||||
|
||||
title = f"Technische Dokumentation — {name}"
|
||||
content = f"""# Technische Dokumentation
|
||||
**{name}**
|
||||
Gemaess Verordnung (EU) 2024/2847 (CRA), Anhang V
|
||||
|
||||
Generiert am: {_today()}
|
||||
|
||||
---
|
||||
|
||||
## 1. Allgemeine Beschreibung des Produkts
|
||||
|
||||
**Produktname:** {name}
|
||||
**Verwendungszweck:** {_fmt_or_placeholder(project.get('intended_use'))}
|
||||
**Hauptfunktionen:** {desc or '[ergaenzen]'}
|
||||
|
||||
### 1.1 Technische Eigenschaften
|
||||
|
||||
- **Primaere Programmiersprache:** {_fmt_or_placeholder(project.get('primary_language'))}
|
||||
- **Enthaelt Firmware:** {'Ja' if project.get('has_firmware') else 'Nein'}
|
||||
- **Internet-Konnektivitaet:** {'Ja' if project.get('connected_to_internet') else 'Nein'}
|
||||
- **Software-Updates:** {'Ja' if project.get('has_software_updates') else 'Nein'}
|
||||
- **Verarbeitet personenbezogene Daten:** {'Ja' if project.get('processes_personal_data') else 'Nein'}
|
||||
- **Kritische Infrastruktur:** {'Ja' if project.get('is_critical_infra_supplier') else 'Nein'}
|
||||
|
||||
## 2. Konzeption, Entwicklung und Produktion
|
||||
|
||||
### 2.1 Cybersicherheits-Risikobewertung (CRA Art. 13(2))
|
||||
|
||||
Risikobewertung wurde durchgefuehrt fuer die Klassifikation
|
||||
**{CLASS_LABELS.get(project.get('cra_classification', ''), 'unbewertet')}**.
|
||||
|
||||
### 2.2 Secure-by-Design-Massnahmen
|
||||
|
||||
Siehe `doc_eu_conformity` Abschnitt 4 fuer die Einhaltung von Anhang I.
|
||||
Detail-Mapping (40 atomare Annex-I-Anforderungen) ist im BreakPilot
|
||||
CRA-Modul unter `/sdk/cra/{{projectId}}/requirements` einsehbar.
|
||||
|
||||
## 3. Bewertung der Konformitaet
|
||||
|
||||
### 3.1 Verfahren
|
||||
{PATH_LABELS.get(project.get('conformity_path', ''), 'Nicht festgelegt')}
|
||||
|
||||
### 3.2 Klassifikation
|
||||
|
||||
**{CLASS_LABELS.get(project.get('cra_classification', ''), 'unbewertet')}**
|
||||
|
||||
Begruendung:
|
||||
{chr(10).join(f'- {r}' for r in project.get('classification_rationale', []) or ['(keine Rationale erfasst)'])}
|
||||
|
||||
## 4. Kontaktangaben
|
||||
|
||||
**Hersteller:** [zu ergaenzen]
|
||||
**Anschrift:** [zu ergaenzen]
|
||||
**Cybersicherheits-Kontakt:** [zu ergaenzen, siehe CVD-Policy]
|
||||
|
||||
---
|
||||
|
||||
*Diese Datei wurde automatisch aus dem BreakPilot CRA-Modul generiert.
|
||||
Sie ist ein Skelett — Hersteller muss alle `[ergaenzen]`-Stellen fuellen,
|
||||
zusaetzliche Anhaenge (Architekturzeichnungen, Test-Berichte, SBOM) beilegen.*
|
||||
"""
|
||||
coverage = {
|
||||
"doc_type": "doc_technical",
|
||||
"annex_anchor": "CRA Anhang V",
|
||||
"fields_required": 8,
|
||||
"fields_filled": sum(1 for v in [
|
||||
project.get("name"), project.get("intended_use"),
|
||||
project.get("cra_classification"), project.get("conformity_path"),
|
||||
] if v),
|
||||
}
|
||||
return title, content, coverage
|
||||
|
||||
|
||||
def doc_cvd_policy(project: dict, *, security_contact: Optional[str] = None) -> tuple[str, str, dict]:
|
||||
"""Coordinated Vulnerability Disclosure Policy."""
|
||||
name = project.get("name", "[Produkt]")
|
||||
contact = _fmt_or_placeholder(security_contact, "security@[your-domain]")
|
||||
title = f"Coordinated Vulnerability Disclosure Policy — {name}"
|
||||
content = f"""# Coordinated Vulnerability Disclosure (CVD) Policy
|
||||
**{name}**
|
||||
Generiert am: {_today()}
|
||||
|
||||
Diese Policy beschreibt, wie Sicherheitsforscher und Nutzer Schwachstellen
|
||||
verantwortungsvoll an uns melden koennen.
|
||||
|
||||
---
|
||||
|
||||
## Wir freuen uns ueber Schwachstellen-Meldungen
|
||||
|
||||
Wenn Sie eine Sicherheitsluecke in **{name}** entdeckt haben, melden Sie sie
|
||||
bitte vertraulich an unsere Sicherheitsstelle. Wir verpflichten uns:
|
||||
|
||||
- **Eingangsbestaetigung innerhalb von 5 Werktagen**
|
||||
- Kommunikation auf Augenhoehe waehrend der Triage
|
||||
- Koordinierte Veroeffentlichung nach Patch-Verfuegbarkeit
|
||||
- Public Acknowledgement (auf Wunsch)
|
||||
- Kein juristisches Vorgehen gegen Forscher, die diese Policy befolgen
|
||||
|
||||
## Meldekanal
|
||||
|
||||
- **E-Mail:** {contact}
|
||||
- **PGP-Key:** [Fingerprint einfuegen]
|
||||
- **Web:** https://[your-domain]/.well-known/security.txt
|
||||
- **Sprachen:** Deutsch, English
|
||||
|
||||
## Was wir brauchen
|
||||
|
||||
- Eindeutige Produkt-Identifikation: {name} + Version
|
||||
- Reproduktionsschritte (PoC bevorzugt)
|
||||
- Auswirkungsbeschreibung (Confidentiality / Integrity / Availability)
|
||||
- (Optional) Vorschlag fuer Behebung
|
||||
|
||||
## Reaktionszeit-Ziele (SLAs)
|
||||
|
||||
| Severity (CVSS) | Triage | Patch verfuegbar |
|
||||
|---|---|---|
|
||||
| Kritisch (9.0+) | 24h | 30 Tage |
|
||||
| Hoch (7.0-8.9) | 72h | 90 Tage |
|
||||
| Mittel (4.0-6.9) | 7 Tage | 180 Tage |
|
||||
| Niedrig (<4.0) | 14 Tage | naechster Release-Zyklus |
|
||||
|
||||
## Embargo + Disclosure
|
||||
|
||||
Wir bitten Sicherheitsforscher um **Embargo bis Patch ausgeliefert** (typ. 90 Tage).
|
||||
Nach Patch koordinieren wir die Veroeffentlichung gemeinsam (Forscher +
|
||||
Hersteller). CVE-Beantragung erfolgt durch uns.
|
||||
|
||||
## CRA-Bezug
|
||||
|
||||
Diese Policy ist Pflicht gemaess **CRA Anhang I Teil 2(5)** sowie
|
||||
**ISO/IEC 29147**. Bei aktiv ausgenutzten Schwachstellen melden wir nach
|
||||
**CRA Art. 14(2)**:
|
||||
|
||||
- **24h:** Fruehwarnung an ENISA / nationale CSIRT
|
||||
- **72h:** Detaillierter Bericht
|
||||
- **14 Tage:** Abschlussbericht nach Behebung
|
||||
|
||||
---
|
||||
|
||||
*Diese CVD-Policy wurde automatisch generiert. Hersteller-spezifische Angaben
|
||||
(Kontakt, PGP, Domain) muessen ergaenzt werden vor Veroeffentlichung.*
|
||||
"""
|
||||
coverage = {
|
||||
"doc_type": "doc_cvd_policy",
|
||||
"annex_anchor": "CRA Anhang I Teil 2(5), Art. 14",
|
||||
"fields_required": 3,
|
||||
"fields_filled": 1 if security_contact else 0,
|
||||
}
|
||||
return title, content, coverage
|
||||
|
||||
|
||||
def doc_update_policy(project: dict) -> tuple[str, str, dict]:
|
||||
"""Update / Patch Policy."""
|
||||
name = project.get("name", "[Produkt]")
|
||||
title = f"Update- und Patch-Policy — {name}"
|
||||
content = f"""# Update- und Patch-Policy
|
||||
**{name}**
|
||||
Generiert am: {_today()}
|
||||
|
||||
---
|
||||
|
||||
## Lifecycle-Support
|
||||
|
||||
Wir verpflichten uns, **Sicherheits-Updates fuer {name}** waehrend der
|
||||
gesamten erwarteten Nutzungsdauer bereitzustellen, jedoch **mindestens 5 Jahre**
|
||||
ab Inverkehrbringen — gemaess CRA Anhang I, 1(4).
|
||||
|
||||
## Patch-SLA (Severity-basiert)
|
||||
|
||||
| CVSS Score | Severity | Max. Patch-Zeit |
|
||||
|---|---|---|
|
||||
| 9.0–10.0 | Kritisch | **30 Tage** |
|
||||
| 7.0–8.9 | Hoch | 90 Tage |
|
||||
| 4.0–6.9 | Mittel | 180 Tage |
|
||||
| <4.0 | Niedrig | naechster Release |
|
||||
|
||||
## Update-Mechanismus
|
||||
|
||||
- **Distribution:** Ueber sichere HTTPS-Kanaele
|
||||
- **Authentizitaet:** Alle Updates sind digital signiert (X.509)
|
||||
- **Integritaet:** SHA-256-Hash vor Installation geprueft
|
||||
- **Rollback:** Manuelles Rollback auf vorherige Version moeglich
|
||||
- **Manipulationsschutz:** Downgrade auf verwundbare Versionen blockiert
|
||||
|
||||
## Benachrichtigung
|
||||
|
||||
Bei kritischen Updates: aktive Benachrichtigung der Endnutzer ueber
|
||||
{_fmt_or_placeholder(project.get('repo_url'), '[Kommunikationskanal ergaenzen]')}
|
||||
binnen 24h nach Verfuegbarkeit.
|
||||
|
||||
## Security Advisories
|
||||
|
||||
Veroeffentlicht im CSAF-Format (Common Security Advisory Framework) unter:
|
||||
- https://[your-domain]/security/advisories
|
||||
- Maschinenlesbar fuer SCA-Tools
|
||||
|
||||
## End-of-Life
|
||||
|
||||
Mindestens **6 Monate vor EOL** wird der Termin bekannt gegeben. Letztes
|
||||
Sicherheits-Update wird mit der EOL-Ankuendigung ausgeliefert.
|
||||
|
||||
## CRA-Bezug
|
||||
|
||||
Diese Policy erfuellt CRA Anhang I, 1(4) (sichere Updates) und
|
||||
2(3) (Patch-Bereitstellung), sowie Art. 13 (Lifecycle-Support).
|
||||
|
||||
---
|
||||
|
||||
*Hersteller-spezifische Angaben muessen ergaenzt werden.*
|
||||
"""
|
||||
coverage = {
|
||||
"doc_type": "doc_update_policy",
|
||||
"annex_anchor": "CRA Anhang I 1(4) + 2(3), Art. 13",
|
||||
"fields_required": 4,
|
||||
"fields_filled": 1 if project.get("has_software_updates") else 0,
|
||||
}
|
||||
return title, content, coverage
|
||||
|
||||
|
||||
def doc_sbom_report(project: dict, latest_sbom: Optional[dict] = None) -> tuple[str, str, dict]:
|
||||
"""SBOM-Zusammenfassung des aktuellsten Uploads."""
|
||||
name = project.get("name", "[Produkt]")
|
||||
title = f"SBOM-Bericht — {name}"
|
||||
|
||||
if not latest_sbom:
|
||||
body = """## Kein SBOM hochgeladen
|
||||
|
||||
Bitte SBOM (CycloneDX oder SPDX) hochladen unter:
|
||||
`/sdk/cra/{projectId}/sbom`
|
||||
|
||||
CRA Anhang I, Anforderung 23 verlangt ein maschinenlesbares
|
||||
Software Bill of Materials fuer jedes Produkt mit digitalen Elementen.
|
||||
"""
|
||||
fields_filled = 0
|
||||
else:
|
||||
summary = latest_sbom.get("summary") or {}
|
||||
sample = summary.get("sample_components") or summary.get("sample_packages") or []
|
||||
sample_list = "\n".join(f"- `{c.get('name', '?')}` v{c.get('version', '?')}" for c in sample[:10])
|
||||
body = f"""## Aktuelle Version
|
||||
|
||||
- **Datei:** {latest_sbom.get('filename', 'unknown')}
|
||||
- **Format:** {latest_sbom.get('format', '?')} v{latest_sbom.get('spec_version', '?')}
|
||||
- **Hochgeladen:** {latest_sbom.get('uploaded_at', '?')}
|
||||
- **Komponenten:** {latest_sbom.get('component_count', 0)}
|
||||
- **Scan-Status:** {latest_sbom.get('scan_status', '?')}
|
||||
|
||||
## Beispielkomponenten (Top 10)
|
||||
|
||||
{sample_list or '_(keine extrahiert)_'}
|
||||
|
||||
## Schwachstellen-Status
|
||||
|
||||
{'Scan ausstehend — wird durch separates Tool durchgefuehrt.' if latest_sbom.get('scan_status') == 'pending' else 'Siehe `/sdk/cra/{projectId}/vuln` fuer aktive Vulnerabilities.'}
|
||||
"""
|
||||
fields_filled = 4
|
||||
|
||||
content = f"""# SBOM-Bericht
|
||||
**{name}**
|
||||
Generiert am: {_today()}
|
||||
|
||||
{body}
|
||||
|
||||
---
|
||||
|
||||
## CRA-Bezug
|
||||
|
||||
Anhang I, Anforderung 23: maschinenlesbares SBOM (CycloneDX oder SPDX)
|
||||
fuer jedes Produkt mit digitalen Elementen. Pflicht bei jedem Release zu
|
||||
aktualisieren.
|
||||
|
||||
## Naechste Schritte
|
||||
|
||||
1. SBOM bei jedem Release-Update neu hochladen
|
||||
2. osv.dev-Scan pruefen (Phase 3.5)
|
||||
3. CVEs in `affected_components` der `/vuln`-Seite tracken
|
||||
"""
|
||||
coverage = {
|
||||
"doc_type": "doc_sbom_report",
|
||||
"annex_anchor": "CRA Anhang I, Req. 23",
|
||||
"fields_required": 4,
|
||||
"fields_filled": fields_filled,
|
||||
}
|
||||
return title, content, coverage
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Registry — for the /documents/generate endpoint
|
||||
# =============================================================================
|
||||
|
||||
DOC_GENERATORS = {
|
||||
"doc_eu_conformity": doc_eu_conformity,
|
||||
"doc_technical": doc_technical,
|
||||
"doc_cvd_policy": doc_cvd_policy,
|
||||
"doc_update_policy": doc_update_policy,
|
||||
"doc_sbom_report": doc_sbom_report,
|
||||
}
|
||||
|
||||
DOC_TYPE_LABELS = {
|
||||
"doc_eu_conformity": "EU-Konformitaetserklaerung (Annex VII)",
|
||||
"doc_technical": "Technische Dokumentation (Annex V)",
|
||||
"doc_cvd_policy": "CVD Policy",
|
||||
"doc_update_policy": "Update- und Patch-Policy",
|
||||
"doc_sbom_report": "SBOM-Bericht",
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
-- Migration 122: CRA Generated Documents
|
||||
-- Tracks all auto-generated CRA documents (DoC, Technical Doc, CVD Policy, etc.)
|
||||
-- with versioning so customers can audit-trail changes over time.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS compliance_cra_documents (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
cra_project_id UUID NOT NULL,
|
||||
tenant_id VARCHAR(255) NOT NULL,
|
||||
|
||||
-- Document classification
|
||||
doc_type VARCHAR(50) NOT NULL,
|
||||
-- doc_eu_conformity -- EU DoC (Annex VII)
|
||||
-- doc_technical -- Technische Doku (Annex V)
|
||||
-- doc_cvd_policy -- Coordinated Vulnerability Disclosure Policy
|
||||
-- doc_update_policy -- Update / Patch Policy
|
||||
-- doc_sbom_report -- SBOM-Zusammenfassung
|
||||
|
||||
-- Content (Markdown, can be converted to PDF later)
|
||||
title VARCHAR(500) NOT NULL,
|
||||
content_md TEXT NOT NULL,
|
||||
version INTEGER NOT NULL DEFAULT 1,
|
||||
|
||||
-- Compliance metadata
|
||||
requirements_coverage JSONB DEFAULT '{}'::jsonb, -- e.g. {covered: ["CRA-AI-23", ...], total: 40}
|
||||
generation_context JSONB DEFAULT '{}'::jsonb, -- snapshot of project state at generation
|
||||
|
||||
-- Signature/Approval (Phase 5 minimum: just status)
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft | reviewed | approved | superseded
|
||||
signed_by VARCHAR(255),
|
||||
signed_at TIMESTAMPTZ,
|
||||
|
||||
generated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
superseded_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_cra_docs_project ON compliance_cra_documents(cra_project_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_cra_docs_tenant ON compliance_cra_documents(tenant_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_cra_docs_type ON compliance_cra_documents(cra_project_id, doc_type, generated_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_cra_docs_status ON compliance_cra_documents(cra_project_id, status);
|
||||
Reference in New Issue
Block a user