From 80dabde81d50731422d8f9b7b62a1fb483a30446 Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Sun, 23 Aug 2026 01:54:20 +0200 Subject: [PATCH] docs(identity-trust): add complete German trust guidance --- pyproject.toml | 4 +- .../backend/manifest.py | 136 +++++++++++++++++- tests/test_documentation.py | 31 ++++ webui/package.json | 2 +- 4 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 tests/test_documentation.py diff --git a/pyproject.toml b/pyproject.toml index 819ec0e..dfb9b48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta" [project] name = "govoplan-identity-trust" -version = "0.1.18" +version = "0.1.19" description = "Public device-key, assurance, and key-epoch trust services for GovOPlaN." readme = "README.md" requires-python = ">=3.12" license = "AGPL-3.0-or-later" authors = [{ name = "GovOPlaN" }] -dependencies = ["govoplan-core>=0.1.18"] +dependencies = ["govoplan-core>=0.1.37"] [tool.setuptools.packages.find] where = ["src"] diff --git a/src/govoplan_identity_trust/backend/manifest.py b/src/govoplan_identity_trust/backend/manifest.py index ace2af8..d37dc46 100644 --- a/src/govoplan_identity_trust/backend/manifest.py +++ b/src/govoplan_identity_trust/backend/manifest.py @@ -12,6 +12,7 @@ from govoplan_core.core.module_guards import ( ) from govoplan_core.core.modules import ( CapabilityDocumentation, + DocumentationCondition, DocumentationLink, DocumentationTopic, FrontendModule, @@ -35,7 +36,7 @@ from govoplan_identity_trust.backend.service import SqlIdentityTrustService MODULE_ID = "identity_trust" MODULE_NAME = "Identity Trust" -MODULE_VERSION = "0.1.18" +MODULE_VERSION = "0.1.19" DEVICE_READ_SCOPE = "identity_trust:device:read" DEVICE_WRITE_SCOPE = "identity_trust:device:write" KEY_ACCESS_SCOPE = "identity_trust:key_access:approve" @@ -246,6 +247,7 @@ manifest = ModuleManifest( audience=("user", "administrator", "security_officer", "auditor"), related_modules=("core", "access", "encryption", "postbox"), metadata={ + "kind": "reference", "help_contexts": [ "identity_trust.settings.devices", "identity_trust.admin.trust", @@ -263,6 +265,42 @@ manifest = ModuleManifest( ), }, }, + translations={ + "de": { + "title": "Datenschutzanfragen zu Identity Trust", + "summary": ( + "Mandantenbezogene Gerätevertrauens-, Assurance-, Epochen- und " + "Schlüsselzugriffsnachweise ohne private oder operative Schlüsselmaterialien exportieren." + ), + "body": ( + "Identity Trust gleicht im aktiven Mandanten exakte Konto- und Identitätskennungen ab " + "und kann Ergebnisse auf ein bestimmtes Gerät oder einen bestimmten Schlüssel eingrenzen. " + "Das Auskunftspaket enthält begrenzte Registrierungsfelder öffentlicher Schlüssel, den " + "Assurance-Status, passende Schlüsselepochen und Schlüsselzugriffsentscheidungen. Private " + "JWK-Parameter, Anforderungsprüfsummen, Idempotenzschlüssel und beliebige " + "Provenienzinhalte werden niemals exportiert. Der Widerruf eines Geräteschlüssels erfordert " + "eine manuelle Prüfung der Wiederherstellung, aktiver verschlüsselter Ressourcen und der " + "aktuellen Epoche. Assurance-, Epochen- und Zugriffsentscheidungsdatensätze bleiben " + "unveränderliche Sicherheitsnachweise." + ), + } + }, + structured_translation_version="1", + structured_translations={ + "de": { + "consequence_classes": { + "export_trust_state": ( + "Gibt ausschließlich begrenzte öffentliche Vertrauens- und Assurance-Nachweise zurück." + ), + "review_device_revocation": ( + "Erfordert eine Prüfung der Wiederherstellung und der Auswirkungen auf verschlüsselte Ressourcen." + ), + "retain_security_evidence": ( + "Bewahrt die Historie von Epochen, Assurance und Zugriffsentscheidungen auf." + ), + } + } + }, ), DocumentationTopic( id="identity-trust.device-keys", @@ -274,6 +312,102 @@ manifest = ModuleManifest( layer="available", documentation_types=("admin", "user"), audience=("user", "administrator", "security_officer", "auditor"), + conditions=( + DocumentationCondition( + any_scopes=(DEVICE_READ_SCOPE, ASSURANCE_READ_SCOPE) + ), + ), + related_modules=("access", "audit", "policy", "encryption", "postbox"), + metadata={ + "kind": "workflow", + "help_contexts": [ + "identity_trust.settings.devices", + "identity_trust.admin.trust", + ], + "purpose": ( + "Review public device-key trust and rotate or revoke trust evidence without handling private keys." + ), + "prerequisites": [ + "The actor has device or assurance read access; consequential actions require their dedicated scopes.", + "Access has already authorized the account and protected resource independently.", + ], + "steps": [ + "Review registered public device keys and their assurance provenance in Settings.", + "Inspect the current key epoch and any recorded key-access decisions before changing trust state.", + "Assess recovery and encrypted-resource impact before revoking a device key.", + "Security officers may rotate a subject epoch or record assurance only with the corresponding authority.", + "Reload stale evidence before retrying a revision-bound revoke or rotation action.", + ], + "limitations": [ + "Identity Trust stores public trust metadata only and provides neither private-key custody nor content encryption.", + "Trust metadata is not device certification or proof that plaintext was never obtained.", + ], + "operational_consequences": { + "revoke_device": "Blocks future trust decisions for the device but cannot erase plaintext already obtained.", + "rotate_epoch": "Changes the epoch accepted by future key-access decisions and requires impact review.", + "record_assurance": "Appends immutable provenance evidence; it does not replace Access authorization.", + }, + "verification": [ + "The displayed key contains public parameters only and names its current status and revision.", + "Every consequential action records the actor, revision, reason, and resulting trust state.", + "Access authorization and Identity Trust decisions remain separately auditable.", + ], + }, + translations={ + "de": { + "title": "Geräteschlüssel und Schlüsselepochen", + "summary": ( + "Anmeldeberechtigung von öffentlichen Geräteschlüsseln und dem Vertrauen für " + "kryptografische Zugriffe trennen." + ), + "body": ( + "Identity Trust speichert ausschließlich öffentliche Schlüssel. Benutzer können ihre " + "Geräteschlüssel in den Einstellungen prüfen und widerrufen sowie die Herkunft von " + "Assurance-Nachweisen einsehen. Sicherheitsverantwortliche können ein berechtigtes Konto " + "auswählen, Nachweise zu widerrufenen oder kompromittierten Geräten prüfen, " + "Schlüsselepochen einer betroffenen Person rotieren und Schlüsselzugriffsentscheidungen " + "in der Administration nachvollziehen. Access entscheidet zuerst, ob ein Konto eine " + "geschützte Ressource erreichen darf; Identity Trust prüft anschließend das aktuelle Gerät " + "und die Schlüsselepoche und zeichnet eine nachvollziehbare Entscheidung auf. Historische " + "Freigaben für Funktionen und Postbox sind ausdrückliche Epochenrichtlinien. Ein Widerruf " + "kann bereits erhaltenen Klartext nicht löschen. Jeder Widerruf und jede Rotation ist an " + "eine Revision gebunden; veraltete Aktionen müssen neu geladen werden." + ), + } + }, + structured_translation_version="1", + structured_translations={ + "de": { + "purpose": ( + "Das Vertrauen in öffentliche Geräteschlüssel prüfen und Vertrauensnachweise rotieren oder widerrufen, ohne private Schlüssel zu verarbeiten." + ), + "prerequisites": [ + "Die handelnde Person darf Geräte oder Assurance lesen; folgenreiche Aktionen erfordern ihre jeweils eigenen Berechtigungen.", + "Access hat das Konto und die geschützte Ressource bereits unabhängig autorisiert.", + ], + "steps": [ + "Registrierte öffentliche Geräteschlüssel und die Herkunft ihrer Assurance-Nachweise in den Einstellungen prüfen.", + "Vor einer Änderung des Vertrauensstatus die aktuelle Schlüsselepoche und aufgezeichnete Schlüsselzugriffsentscheidungen prüfen.", + "Vor dem Widerruf eines Geräteschlüssels Wiederherstellung und Auswirkungen auf verschlüsselte Ressourcen bewerten.", + "Sicherheitsverantwortliche dürfen eine Epoche rotieren oder Assurance nur mit der jeweiligen Berechtigung aufzeichnen.", + "Veraltete Nachweise neu laden, bevor eine revisionsgebundene Widerrufs- oder Rotationsaktion wiederholt wird.", + ], + "limitations": [ + "Identity Trust speichert nur öffentliche Vertrauensmetadaten und bietet weder private Schlüsselverwahrung noch Inhaltsverschlüsselung.", + "Vertrauensmetadaten sind keine Gerätezertifizierung und kein Nachweis dafür, dass niemals Klartext erhalten wurde.", + ], + "operational_consequences": { + "revoke_device": "Blockiert künftige Vertrauensentscheidungen für das Gerät, kann aber bereits erhaltenen Klartext nicht löschen.", + "rotate_epoch": "Ändert die für künftige Schlüsselzugriffsentscheidungen akzeptierte Epoche und erfordert eine Folgenprüfung.", + "record_assurance": "Fügt unveränderliche Herkunftsnachweise an und ersetzt nicht die Autorisierung durch Access.", + }, + "verification": [ + "Der angezeigte Schlüssel enthält nur öffentliche Parameter und nennt aktuellen Status und Revision.", + "Jede folgenreiche Aktion zeichnet Akteur, Revision, Begründung und resultierenden Vertrauensstatus auf.", + "Access-Autorisierung und Identity-Trust-Entscheidung bleiben getrennt nachvollziehbar.", + ], + } + }, links=( DocumentationLink( label="Device-key trust and recovery boundary", diff --git a/tests/test_documentation.py b/tests/test_documentation.py new file mode 100644 index 0000000..8a41c71 --- /dev/null +++ b/tests/test_documentation.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +import unittest + +from govoplan_core.core.modules import ( + documentation_structured_translation_issues, + user_workflow_scope_condition_issues, +) +from govoplan_identity_trust.backend.manifest import manifest + + +class IdentityTrustDocumentationTests(unittest.TestCase): + def test_public_topics_have_complete_german_reference_content(self) -> None: + self.assertEqual(2, len(manifest.documentation)) + for topic in manifest.documentation: + translation = topic.translations.get("de", {}) + self.assertTrue( + all(translation.get(key) for key in ("title", "summary", "body")) + ) + self.assertEqual((), documentation_structured_translation_issues(topic)) + + def test_documentation_has_scope_conditioned_workflow_and_reference(self) -> None: + kinds = {topic.metadata.get("kind") for topic in manifest.documentation} + self.assertIn("workflow", kinds) + self.assertIn("reference", kinds) + for topic in manifest.documentation: + self.assertEqual((), user_workflow_scope_condition_issues(topic)) + + +if __name__ == "__main__": + unittest.main() diff --git a/webui/package.json b/webui/package.json index e2e2ae9..e0fa171 100644 --- a/webui/package.json +++ b/webui/package.json @@ -1,6 +1,6 @@ { "name": "@govoplan/identity-trust-webui", - "version": "0.1.18", + "version": "0.1.19", "private": true, "type": "module", "main": "src/index.ts",