Files
govoplan-audit/src/govoplan_audit/backend/manifest.py
T
zemion f2d7b9b29a
Module Package Release / publish-packages (push) Successful in 11s
docs: complete German structured documentation
2026-08-24 01:15:31 +02:00

337 lines
17 KiB
Python

from __future__ import annotations
from govoplan_core.core.modules import with_documentation_structured_translations
from govoplan_audit.backend.german_structured_documentation import GERMAN_STRUCTURED_TRANSLATIONS
from pathlib import Path
from govoplan_audit.backend.db import models as audit_models # noqa: F401 - populate Audit ORM metadata
from govoplan_audit.backend.dsar_provider import (
AUDIT_DSAR_CAPABILITY,
AuditDsarProvider,
)
from govoplan_core.core.access import (
CAPABILITY_AUDIT_RECORDER,
CAPABILITY_AUDIT_RETENTION,
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
)
from govoplan_core.core.module_guards import (
drop_table_retirement_provider,
persistent_table_uninstall_guard,
)
from govoplan_core.core.modules import (
CapabilityDocumentation,
DocumentationCondition,
DocumentationTopic,
FrontendModule,
MigrationSpec,
ModuleContext,
ModuleInterfaceProvider,
ModuleManifest,
)
from govoplan_core.core.provider_governance import declared_module_architecture
from govoplan_core.core.events import CAPABILITY_PLATFORM_EVENT_OUTBOX
from govoplan_core.core.views import ViewSurface
from govoplan_core.db.base import Base
from govoplan_audit.backend.permissions import AUDIT_PERMISSIONS, AUDIT_ROLE_TEMPLATES
def _route_factory(context: ModuleContext):
del context
from govoplan_audit.backend.api.v1.routes import router
return router
def _audit_recorder(context: ModuleContext):
del context
from govoplan_audit.backend.recording import SqlAuditRecorder
return SqlAuditRecorder()
def _audit_retention(context: ModuleContext):
del context
from govoplan_audit.backend.retention import SqlAuditRetentionProvider
return SqlAuditRetentionProvider()
def _event_outbox(context: ModuleContext):
from govoplan_audit.backend.outbox import SqlAuditOutbox
return SqlAuditOutbox(
max_attempts=getattr(
context.settings,
"platform_event_outbox_max_attempts",
8,
)
)
def _dsar_provider(_context: ModuleContext) -> AuditDsarProvider:
return AuditDsarProvider()
manifest = ModuleManifest(
id="audit",
name="Audit",
version="0.1.20",
permissions=AUDIT_PERMISSIONS,
role_templates=AUDIT_ROLE_TEMPLATES,
required_capabilities=(
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
),
provides_interfaces=(
ModuleInterfaceProvider(name=AUDIT_DSAR_CAPABILITY, version="0.1.0"),
),
route_factory=_route_factory,
documentation=(
DocumentationTopic(
id="audit.data-subject-requests",
title="Audit data-subject requests",
summary=(
"Include minimized subject-linked accountability evidence in "
"access packages while preserving immutable retention."
),
body=(
"Audit correlates exact account, membership, identity, or user "
"identifiers only within the active tenant. It contributes actor "
"audit records, structured platform-event actor envelopes, manual "
"replay attribution, and evidence-bundle request attribution. The "
"projection preserves action, object, event, trace, source, policy, "
"status, timing, and verification references needed to explain the "
"subject's involvement. Arbitrary audit details, event payloads, "
"institutional context, delivery keys and errors, replay reasons, "
"request payloads, generated bundle payloads, and credentials are "
"excluded. Optional exact record references narrow results but never "
"replace actor corroboration. System and cross-tenant evidence is not "
"included in tenant requests. All Audit erasure actions are retain-only "
"and non-executable because the records are immutable accountability "
"evidence governed by retention and legal hold."
),
layer="configured",
documentation_types=("admin", "user"),
audience=("data_subject", "auditor", "security_officer", "operator"),
related_modules=("core", "access", "policy", "ops"),
translations={
"de": {
"title": "Datenschutzanfragen für Audit",
"summary": "Minimierte, betroffenenbezogene Rechenschaftsnachweise in Auskunftspakete aufnehmen und dabei die unveränderliche Aufbewahrung wahren.",
"body": (
"Audit korreliert genaue Konto-, Mitgliedschafts-, Identitäts- oder Benutzerkennungen ausschließlich im aktiven Mandanten. "
"Beigetragen werden Akteursdaten aus Audit-Einträgen, strukturierte Akteursumschläge von Plattformereignissen, Zuordnungen manueller Wiederholungen und Anforderungszuordnungen von Nachweispaketen. "
"Die Projektion erhält Handlung, Objekt, Ereignis, Trace, Quelle, Richtlinie, Status, Zeitangaben und Prüfverweise, die zur Erklärung der Beteiligung der betroffenen Person erforderlich sind. "
"Beliebige Audit-Details, Ereignisnutzdaten, institutioneller Kontext, Zustellschlüssel und -fehler, Wiederholungsgründe, Anfragenutzdaten, erzeugte Paketnutzdaten und Zugangsdaten bleiben ausgeschlossen. "
"Optionale genaue Datensatzverweise grenzen Ergebnisse ein, ersetzen aber niemals die Bestätigung der Akteurszuordnung. Systemweite und mandantenübergreifende Nachweise werden nicht in Mandantenanfragen aufgenommen. "
"Alle Löschaktionen von Audit sind reine Aufbewahrungsentscheidungen und nicht ausführbar, weil die Datensätze unveränderliche Rechenschaftsnachweise unter Aufbewahrung und rechtlicher Sperre sind."
),
}
},
metadata={
"help_contexts": [
"audit.admin.tenant",
"audit.event-details",
"audit.evidence.export",
"privacy.data-subject-requests",
],
"consequence_classes": {
"export_actor_evidence": (
"Returns minimized actor attribution and stable references, "
"never arbitrary evidence payloads."
),
"retain_audit_evidence": (
"Keeps immutable evidence under configured retention and "
"legal-hold policy."
),
},
},
),
DocumentationTopic(
id="audit.read-authorized-evidence",
title="Read authorized audit evidence",
summary="Audit history explains who performed a governed action, when it happened, and which resource and trace context were involved.",
body="Audit views are permission- and tenant-scoped. Entries are evidence, not editable business records. Sensitive payloads may be redacted while stable resource, actor, outcome, request, run, and trace references remain available for investigation.",
documentation_types=("user",),
audience=("auditor", "tenant_admin", "operator"),
translations={
"de": {
"title": "Berechtigte Audit-Nachweise lesen",
"summary": "Der Audit-Verlauf erklärt, wer eine gesteuerte Handlung wann ausgeführt hat und welche Ressourcen- und Trace-Zusammenhänge beteiligt waren.",
"body": (
"Audit-Ansichten sind nach Berechtigung und Mandant begrenzt. Einträge sind Nachweise und keine bearbeitbaren Fachdaten. "
"Sensible Nutzdaten können geschwärzt sein, während stabile Verweise auf Ressource, Akteur, Ergebnis, Anfrage, Lauf und Trace für Untersuchungen verfügbar bleiben."
),
}
},
metadata={
"kind": "reference",
"help_contexts": [
"audit.admin.system",
"audit.admin.tenant",
"audit.event-details",
],
"surfaces": ["audit.admin.system", "audit.admin.tenant"],
},
),
DocumentationTopic(
id="audit.recording-retention-and-outbox",
title="Operate audit recording and event delivery",
summary="Audit owns durable audit records, retention operations, and the transactional platform-event outbox.",
body="Modules record bounded audit facts through the Audit capability. Governed platform events are committed to the outbox with retry and delivery metadata so a failed consumer does not erase the originating transaction. Worker dispatch is partitioned by tenant entitlement; an unavailable consumer retains its durable delivery and records an operator-required outcome instead of acknowledging the event. Retention and destructive retirement must preserve the configured evidence and recovery guarantees.",
documentation_types=("admin",),
audience=("auditor", "security_officer", "operator"),
related_modules=("policy", "ops"),
translations={
"de": {
"title": "Audit-Aufzeichnung, Aufbewahrung und Ereigniszustellung betreiben",
"summary": "Audit verwaltet dauerhafte Audit-Datensätze, Aufbewahrungsvorgänge und die transaktionale Plattformereignis-Outbox.",
"body": (
"Module zeichnen begrenzte Audit-Fakten über die Audit-Fähigkeit auf. Gesteuerte Plattformereignisse werden zusammen mit Wiederholungs- und Zustellmetadaten in die Outbox übernommen, sodass ein ausgefallener Verbraucher die ursprüngliche Transaktion nicht auslöscht. "
"Die Worker-Zustellung wird nach Mandantenberechtigung getrennt; ein nicht verfügbarer Verbraucher behält seine dauerhafte Zustellung und erfasst ein Ergebnis, das einen betrieblichen Eingriff verlangt, statt das Ereignis zu bestätigen. "
"Aufbewahrung und destruktive Ausmusterung müssen die konfigurierten Nachweis- und Wiederherstellungsgarantien erhalten."
),
}
},
metadata={
"kind": "reference",
"help_contexts": [
"audit.recording",
"audit.retention",
"audit.event-outbox",
],
},
),
DocumentationTopic(
id="audit.evidence-bundles",
title="Export and independently verify audit evidence",
summary="Authorized auditors can export bounded, redacted evidence bundles with canonical hashes and optional trusted signatures.",
body="Tenant exports require audit:evidence:export and remain tenant-scoped; system or all-scope exports require audit:system_evidence:export. Each bundle contains versioned audit-record DTOs, trace and policy/source provenance, external module evidence references, redaction declarations, and canonical hashes, but never raw messages, recipient lists, secrets, credentials, or file contents. Generation and download are audited. Use govoplan-audit-verify with optional trusted Ed25519 public keys and external evidence files to distinguish valid, incomplete, unverifiable, unsupported, and tampered evidence without database access. Modules contribute external references through serialized Core EvidenceReference-compatible facts or the export request; they do not import Audit internals.",
documentation_types=("user", "admin"),
audience=("auditor", "security_officer", "operator"),
conditions=(
DocumentationCondition(required_scopes=("audit:evidence:export",)),
DocumentationCondition(
required_scopes=("audit:system_evidence:export",)
),
),
related_modules=("policy", "files"),
translations={
"de": {
"title": "Audit-Nachweise exportieren und unabhängig prüfen",
"summary": "Berechtigte Prüfer können begrenzte, geschwärzte Nachweispakete mit kanonischen Hashes und optionalen vertrauenswürdigen Signaturen exportieren.",
"body": (
"Mandantenexporte erfordern audit:evidence:export und bleiben mandantenbezogen; systemweite oder unbeschränkte Exporte erfordern audit:system_evidence:export. "
"Jedes Paket enthält versionierte Audit-Datensatz-DTOs, Trace- sowie Richtlinien- und Quellenherkunft, externe Nachweisverweise anderer Module, Schwärzungserklärungen und kanonische Hashes, jedoch niemals vollständige Nachrichten, Empfängerlisten, Geheimnisse, Zugangsdaten oder Dateiinhalte. "
"Erzeugung und Download werden auditiert. Verwenden Sie govoplan-audit-verify mit optionalen vertrauenswürdigen öffentlichen Ed25519-Schlüsseln und externen Nachweisdateien, um gültige, unvollständige, nicht prüfbare, nicht unterstützte und manipulierte Nachweise ohne Datenbankzugriff zu unterscheiden. "
"Module liefern externe Verweise als serialisierte, mit Core EvidenceReference kompatible Fakten oder über die Exportanfrage; sie importieren keine Audit-Interna."
),
}
},
metadata={
"kind": "workflow",
"help_contexts": [
"audit.evidence.export",
"audit.evidence.verify",
"audit.evidence.signing",
],
"verification": [
"Confirm the requested record scope is complete and bounded before export.",
"Verify canonical hashes offline and supply trusted keys or referenced evidence when required.",
"Treat missing external evidence, unverifiable references, and hash mismatches as distinct outcomes.",
],
},
),
),
frontend=FrontendModule(
module_id="audit",
package_name="@govoplan/audit-webui",
view_surfaces=(
ViewSurface(
id="audit.admin.system",
module_id="audit",
kind="section",
label="System audit",
order=90,
),
ViewSurface(
id="audit.admin.tenant",
module_id="audit",
kind="section",
label="Tenant audit",
order=100,
),
),
),
migration_spec=MigrationSpec(
module_id="audit",
metadata=Base.metadata,
script_location=str(Path(__file__).with_name("migrations") / "versions"),
retirement_supported=True,
retirement_provider=drop_table_retirement_provider(
audit_models.AuditEvidenceBundle,
audit_models.AuditLog,
audit_models.AuditOutboxDelivery,
audit_models.AuditOutboxEvent,
label="Audit",
),
retirement_notes="Destructive retirement drops audit-owned database tables after the installer captures a database snapshot.",
),
uninstall_guard_providers=(
persistent_table_uninstall_guard(
audit_models.AuditEvidenceBundle,
audit_models.AuditLog,
audit_models.AuditOutboxDelivery,
audit_models.AuditOutboxEvent,
label="Audit",
),
),
capability_factories={
CAPABILITY_AUDIT_RECORDER: _audit_recorder,
CAPABILITY_AUDIT_RETENTION: _audit_retention,
CAPABILITY_PLATFORM_EVENT_OUTBOX: _event_outbox,
AUDIT_DSAR_CAPABILITY: _dsar_provider,
},
capability_documentation={
AUDIT_DSAR_CAPABILITY: CapabilityDocumentation(
label="Audit data-subject request provider",
summary=(
"Exports minimized tenant actor evidence with retain-only "
"erasure outcomes."
),
contract_version="0.1.0",
),
},
architecture=declared_module_architecture(
layer="governance_accountability",
kind="governance",
maturity="vertical_slice",
documentation_ref="docs/AUDIT_TRACE_CONTEXT.md",
test_ref="tests/test_audit_module_contract.py",
known_limits=(
"Cross-deployment long-term archive transfer remains deployment-specific.",
),
owned_concepts=(
"audit record",
"audit retention",
"audit evidence bundle",
"transactional event outbox",
),
non_owned_concepts=("domain record", "policy decision", "external effect"),
recovery_docs=("README.md",),
security_docs=("docs/AUDIT_TRACE_CONTEXT.md", "docs/EVIDENCE_BUNDLES.md"),
operations_docs=("README.md", "docs/EVIDENCE_BUNDLES.md"),
),
)
manifest = with_documentation_structured_translations(
manifest, locale="de", translations=GERMAN_STRUCTURED_TRANSLATIONS
)
def get_manifest() -> ModuleManifest:
return manifest