Skip to content

cai-gmbh-dev/RoPA-OSCAL

Repository files navigation

RoPA‑OSCAL (Starter)

Verzeichnis von Verarbeitungstätigkeiten (RoPA, Art. 30 DSGVO) in OSCAL – Profile, Codelisten, XSLT-Views und Validierung (JSON Schema + Schematron).

CI License: EUPL-1.2

Inhalt

  • catalog/ – Codelisten (Rechtsgrundlagen, Rollen, Datenkategorien) als JSON/CSV
  • schemas/oscal-ssp-ropa.json (JSON Schema) & oscal-ssp-ropa.sch (Schematron Business-Regeln)
  • xslt/ – IFG‑Ansicht (v1) sowie optional v2 (strenge Empfänger‑Zuordnung & Sortierung)
  • ssps/ – Beispiel‑SSPs (XML, optional JSON)
  • tools/ – Skripte (z. B. render_ifg.sh)
  • Makefilevalidate-json, validate-schematron

Documentation & Local Validation

📚 Docs

Die ausführliche Level-2-Dokumentation liegt im Ordner docs/:

✅ Positiv-Beispiele

Validierbare Beispiele liegen unter:

ssps/examples/
├─ ssp_ropa_sdm_OK.json
└─ ssp_ropa_sdm_ART9.json

⛔ Negativ-Beispiele

Erwartet fehlschlagende Beispiele (zur CI-Überprüfung) liegen unter:

ssps/negative/
├─ ssp_ropa_sdm_FAIL.json
└─ ssp_ropa_sdm_ART9_FAIL.json

🔎 JSON-Validierung (lokal)

Voraussetzungen: Python 3.11+

python -m venv .venv
. .venv/bin/activate
pip install "jsonschema>=4.19,<5"

Positive Beispiele prüfen:

SCHEMA="schemas/oscal-ssp-ropa_sdm.json"
for f in ssps/examples/*.json; do
  echo "Validating $f"
  python - <<'PY' "$SCHEMA" "$f"
import json, sys
from jsonschema import Draft202012Validator as V
schema = json.load(open(sys.argv[1],'r',encoding='utf-8'))
data   = json.load(open(sys.argv[2],'r',encoding='utf-8'))
v = V(schema); errs = sorted(v.iter_errors(data), key=lambda e: list(e.path))
if errs:
    print("[FAIL]", sys.argv[2])
    for e in errs[:10]:
        loc = "$." + ".".join(map(str, e.path))
        print("-", loc, ":", e.message)
    raise SystemExit(1)
print("[OK]  ", sys.argv[2])
PY
done

Negative Beispiele (müssen fehlschlagen):

SCHEMA="schemas/oscal-ssp-ropa_sdm.json"
for f in ssps/negative/*.json; do
  echo "Expecting FAIL for $f"
  python - <<'PY' "$SCHEMA" "$f"
import json, sys
from jsonschema import Draft202012Validator as V
schema = json.load(open(sys.argv[1],'r',encoding='utf-8'))
data   = json.load(open(sys.argv[2],'r',encoding='utf-8'))
v = V(schema); errs = list(v.iter_errors(data))
if errs:
    print("[EXPECTED-FAIL] violations:", len(errs))
    raise SystemExit(1)
print("[UNEXPECTED-PASS] no violations")
raise SystemExit(0)
PY
rc=$?
if [ $rc -eq 0 ]; then echo "❌ Unexpected PASS"; exit 1; else echo "✅ Failed as expected"; fi
done

🧩 Schematron-Validierung (XSLT-1, lokal)

Voraussetzungen: xsltproc (libxslt)

# Debian/Ubuntu
sudo apt-get update && sudo apt-get install -y xsltproc

Kompilieren & Prüfen (XSLT-1-Pipeline):

INC=schematron/iso_dsdl_include.xsl
EXP=schematron/iso_abstract_expand.xsl
SVRL=schematron/iso_svrl_for_xslt1.xsl
SCH=schemas/oscal-ssp-ropa-xslt-1.sch

# ggf. Tiefe erhöhen, falls nötig: xsltproc --maxdepth 6000 ...
xsltproc "$INC" "$SCH"  > tmp.stage1.sch
xsltproc "$EXP" tmp.stage1.sch > tmp.stage2.sch
xsltproc "$SVRL" tmp.stage2.sch > compiled.sch.xsl

mkdir -p svrl
for f in ssps/**/*.xml; do
  b=$(basename "$f")
  echo "Schematron: $f"
  xsltproc compiled.sch.xsl "$f" > "svrl/${b}.svrl.xml" || true
  if grep -q "<failed-assert" "svrl/${b}.svrl.xml"; then
    echo "❌ Violations in $f"
  else
    echo "✅ OK: $f"
  fi
done

🧪 Tipps & Troubleshooting

  • xsltproc recursion/maxdepth:
    Bei sehr großen SSPs: xsltproc --maxdepth 6000 ... nutzen (siehe Fehlermeldung “potential infinite template recursion”).
  • Regex im JSON-Schema:
    Das Schema nutzt (?i) für Case-Insensitive-Prüfungen. Falls euer Validator keine Inline-Flags unterstützt, bitte melden – wir liefern eine kompatible Variante.
  • Cross-Links (by-components):
    Beziehungen Prozess → Komponente (uses-component) und Control → Komponente (by-components) werden im Schematron geprüft (nicht im JSON-Schema).

Modellierungsrichtlinien (Kurz)

  • Prozesse als component[@type='process'] mit Props: procedure-title, purpose*, legal-basis*, data-subject*, data-category*, retention.*, Flags (dpia.required, third-country-transfer, …).
  • Empfänger als component (software/service) mit processing-role (und ggf. av-contract-id, location, operation*). Optional strikte Prozess‑Verknüpfung via prop name="recipient" (v2‑Mechanik).
  • TOMs als implemented-requirement mit prop name="tom" und statement/by-component.

Für Details siehe catalog/ und schemas/.

Lizenz

Dieses Projekt ist unter der EUPL v1.2 lizenziert. Siehe LICENSE.

SPDX‑Header‑Beispiele:

SPDX-License-Identifier: EUPL-1.2

Made with ❤️ for öffentliche Verwaltungen & Open Source.