594 lines
25 KiB
Python
594 lines
25 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from govoplan_core.core.encryption import (
|
|
CAPABILITY_ENCRYPTION_CONTENT_CIPHER,
|
|
CAPABILITY_ENCRYPTION_CONTENT_CIPHER_PROVIDER_PREFIX,
|
|
CAPABILITY_ENCRYPTION_CONTENT_PROTECTION,
|
|
CAPABILITY_ENCRYPTION_DISABLE_PREFLIGHT,
|
|
CAPABILITY_ENCRYPTION_KEY_MATERIAL_PROVIDER_PREFIX,
|
|
CAPABILITY_ENCRYPTION_KEY_VAULT,
|
|
CAPABILITY_ENCRYPTION_RECOVERY,
|
|
)
|
|
from govoplan_core.core.module_guards import (
|
|
drop_table_retirement_provider,
|
|
persistent_table_uninstall_guard,
|
|
)
|
|
from govoplan_core.core.modules import (
|
|
CapabilityDocumentation,
|
|
DocumentationCondition,
|
|
DocumentationLink,
|
|
DocumentationTopic,
|
|
FrontendModule,
|
|
MigrationSpec,
|
|
ModuleContext,
|
|
ModuleInterfaceProvider,
|
|
ModuleManifest,
|
|
ModuleUninstallGuardResult,
|
|
PermissionDefinition,
|
|
RoleTemplate,
|
|
ViewSurface,
|
|
)
|
|
from govoplan_core.core.provider_governance import declared_module_architecture
|
|
from govoplan_core.db.base import Base
|
|
from govoplan_encryption.backend.db import models
|
|
from govoplan_encryption.backend.dsar_provider import (
|
|
ENCRYPTION_DSAR_CAPABILITY,
|
|
EncryptionDsarProvider,
|
|
)
|
|
from govoplan_encryption.backend.local_provider import (
|
|
LOCAL_PROVIDER_ID,
|
|
LocalAesGcmProvider,
|
|
)
|
|
from govoplan_encryption.backend.service import SqlEncryptionService
|
|
|
|
|
|
MODULE_ID = "encryption"
|
|
MODULE_NAME = "Encryption"
|
|
MODULE_VERSION = "0.1.19"
|
|
|
|
USE_SCOPE = "encryption:vault:use"
|
|
ADMIN_SCOPE = "encryption:vault:admin"
|
|
RECOVERY_SCOPE = "encryption:recovery:approve"
|
|
|
|
OPTIONAL_DEPENDENCIES = (
|
|
"access",
|
|
"audit",
|
|
"policy",
|
|
"notifications",
|
|
"files",
|
|
"postbox",
|
|
"campaigns",
|
|
"workflow_engine",
|
|
"identity_trust",
|
|
)
|
|
|
|
|
|
def _permission(scope: str, label: str, description: str) -> PermissionDefinition:
|
|
module_id, resource, action = scope.split(":", 2)
|
|
return PermissionDefinition(
|
|
scope=scope,
|
|
label=label,
|
|
description=description,
|
|
category="Encryption",
|
|
level="tenant",
|
|
module_id=module_id,
|
|
resource=resource,
|
|
action=action,
|
|
)
|
|
|
|
|
|
def _router(context: ModuleContext):
|
|
from govoplan_encryption.backend.router import create_router
|
|
|
|
return create_router(context.registry)
|
|
|
|
|
|
def _service(context: ModuleContext) -> SqlEncryptionService:
|
|
return SqlEncryptionService(context.registry)
|
|
|
|
|
|
def _local_provider(context: ModuleContext) -> LocalAesGcmProvider:
|
|
return LocalAesGcmProvider(getattr(context.settings, "master_key_b64", None))
|
|
|
|
|
|
def _dsar_provider(_context: ModuleContext) -> EncryptionDsarProvider:
|
|
return EncryptionDsarProvider()
|
|
|
|
|
|
def _disable_guard(
|
|
session: object | None,
|
|
_module_id: str,
|
|
) -> tuple[ModuleUninstallGuardResult, ...]:
|
|
if session is None:
|
|
return (
|
|
ModuleUninstallGuardResult(
|
|
"blocker",
|
|
"encryption_disable_unverified",
|
|
"Encryption cannot be disabled without proving the state of every protection envelope.",
|
|
),
|
|
)
|
|
try:
|
|
report = SqlEncryptionService().assess_disable(session)
|
|
except Exception as exc:
|
|
return (
|
|
ModuleUninstallGuardResult(
|
|
"blocker",
|
|
"encryption_disable_check_failed",
|
|
f"Encryption disable preflight failed: {type(exc).__name__}.",
|
|
),
|
|
)
|
|
if report.allowed:
|
|
return ()
|
|
return (
|
|
ModuleUninstallGuardResult(
|
|
"blocker",
|
|
"encryption_protected_content_present",
|
|
f"Encryption still protects {report.unresolved_count} unresolved envelope(s). Migrate, decrypt, explicitly export, or cryptographically destroy them before disabling the module.",
|
|
),
|
|
)
|
|
|
|
|
|
PERMISSIONS = (
|
|
_permission(
|
|
USE_SCOPE,
|
|
"Use encryption profiles",
|
|
"Register and resolve protected content through configured profiles.",
|
|
),
|
|
_permission(
|
|
ADMIN_SCOPE,
|
|
"Administer encryption",
|
|
"Manage vault metadata, provider operations, rotation, migration, and policy provenance.",
|
|
),
|
|
_permission(
|
|
RECOVERY_SCOPE,
|
|
"Approve key recovery",
|
|
"Participate in a high-assurance recovery ceremony without gaining content ownership.",
|
|
),
|
|
)
|
|
|
|
ROLE_TEMPLATES = (
|
|
RoleTemplate(
|
|
slug="encryption_user",
|
|
name="Encryption user",
|
|
description="Use configured content-protection profiles.",
|
|
permissions=(USE_SCOPE,),
|
|
),
|
|
RoleTemplate(
|
|
slug="encryption_custodian",
|
|
name="Encryption custodian",
|
|
description="Administer encryption and participate in key recovery.",
|
|
permissions=(USE_SCOPE, ADMIN_SCOPE, RECOVERY_SCOPE),
|
|
),
|
|
)
|
|
|
|
manifest = ModuleManifest(
|
|
id=MODULE_ID,
|
|
name=MODULE_NAME,
|
|
version=MODULE_VERSION,
|
|
optional_dependencies=OPTIONAL_DEPENDENCIES,
|
|
provides_interfaces=(
|
|
ModuleInterfaceProvider(
|
|
name=CAPABILITY_ENCRYPTION_KEY_VAULT,
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(
|
|
name=CAPABILITY_ENCRYPTION_CONTENT_PROTECTION,
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(
|
|
name=CAPABILITY_ENCRYPTION_CONTENT_CIPHER,
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(
|
|
name=f"{CAPABILITY_ENCRYPTION_KEY_MATERIAL_PROVIDER_PREFIX}{LOCAL_PROVIDER_ID}",
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(
|
|
name=f"{CAPABILITY_ENCRYPTION_CONTENT_CIPHER_PROVIDER_PREFIX}{LOCAL_PROVIDER_ID}",
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(
|
|
name=CAPABILITY_ENCRYPTION_RECOVERY,
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(
|
|
name=CAPABILITY_ENCRYPTION_DISABLE_PREFLIGHT,
|
|
version="1.0.0",
|
|
),
|
|
ModuleInterfaceProvider(name=ENCRYPTION_DSAR_CAPABILITY, version="0.1.0"),
|
|
),
|
|
permissions=PERMISSIONS,
|
|
role_templates=ROLE_TEMPLATES,
|
|
route_factory=_router,
|
|
frontend=FrontendModule(
|
|
module_id=MODULE_ID,
|
|
package_name="@govoplan/encryption-webui",
|
|
view_surfaces=(
|
|
ViewSurface(
|
|
id="encryption.admin.operations",
|
|
module_id=MODULE_ID,
|
|
kind="section",
|
|
label="Encryption administration",
|
|
order=10,
|
|
),
|
|
ViewSurface(
|
|
id="encryption.admin.vaults",
|
|
module_id=MODULE_ID,
|
|
kind="section",
|
|
label="Key vaults",
|
|
parent_id="encryption.admin.operations",
|
|
order=20,
|
|
),
|
|
ViewSurface(
|
|
id="encryption.admin.migrations",
|
|
module_id=MODULE_ID,
|
|
kind="section",
|
|
label="Protection migrations",
|
|
parent_id="encryption.admin.operations",
|
|
order=30,
|
|
),
|
|
ViewSurface(
|
|
id="encryption.admin.recovery",
|
|
module_id=MODULE_ID,
|
|
kind="section",
|
|
label="Recovery ceremonies",
|
|
parent_id="encryption.admin.operations",
|
|
order=40,
|
|
),
|
|
),
|
|
),
|
|
capability_factories={
|
|
CAPABILITY_ENCRYPTION_KEY_VAULT: _service,
|
|
CAPABILITY_ENCRYPTION_CONTENT_PROTECTION: _service,
|
|
CAPABILITY_ENCRYPTION_CONTENT_CIPHER: _service,
|
|
CAPABILITY_ENCRYPTION_RECOVERY: _service,
|
|
CAPABILITY_ENCRYPTION_DISABLE_PREFLIGHT: _service,
|
|
ENCRYPTION_DSAR_CAPABILITY: _dsar_provider,
|
|
f"{CAPABILITY_ENCRYPTION_KEY_MATERIAL_PROVIDER_PREFIX}{LOCAL_PROVIDER_ID}": _local_provider,
|
|
f"{CAPABILITY_ENCRYPTION_CONTENT_CIPHER_PROVIDER_PREFIX}{LOCAL_PROVIDER_ID}": _local_provider,
|
|
},
|
|
capability_documentation={
|
|
CAPABILITY_ENCRYPTION_KEY_VAULT: CapabilityDocumentation(
|
|
label="Governed encryption key vault",
|
|
summary=(
|
|
"Orchestrates opaque, idempotent provider key references, "
|
|
"lifecycle state, and policy provenance without exposing key material."
|
|
),
|
|
contract_version="1.0.0",
|
|
audience=("administrator", "security_officer", "auditor"),
|
|
),
|
|
CAPABILITY_ENCRYPTION_CONTENT_PROTECTION: CapabilityDocumentation(
|
|
label="Content-protection envelope registry",
|
|
summary=(
|
|
"Registers versioned protection envelopes and fail-closed, "
|
|
"evidence-backed migration state for feature-owned content."
|
|
),
|
|
contract_version="1.0.0",
|
|
),
|
|
CAPABILITY_ENCRYPTION_CONTENT_CIPHER: CapabilityDocumentation(
|
|
label="Server-side content cipher",
|
|
summary=(
|
|
"Protects and opens owner-module content through opaque, "
|
|
"versioned envelopes without exporting key material."
|
|
),
|
|
contract_version="1.0.0",
|
|
audience=("module_developer", "security_officer", "auditor"),
|
|
),
|
|
CAPABILITY_ENCRYPTION_RECOVERY: CapabilityDocumentation(
|
|
label="Encryption recovery ceremony",
|
|
summary=(
|
|
"Requires recent high assurance, distinct custodians, quorum, "
|
|
"expiry, and immutable evidence without changing ownership."
|
|
),
|
|
contract_version="1.0.0",
|
|
),
|
|
CAPABILITY_ENCRYPTION_DISABLE_PREFLIGHT: CapabilityDocumentation(
|
|
label="Encryption disable preflight",
|
|
summary=(
|
|
"Blocks disable or uninstall while any protection envelope "
|
|
"remains unresolved."
|
|
),
|
|
contract_version="1.0.0",
|
|
),
|
|
ENCRYPTION_DSAR_CAPABILITY: CapabilityDocumentation(
|
|
label="Encryption data-subject request provider",
|
|
summary=(
|
|
"Exports minimized cryptographic custody attribution without key "
|
|
"material, ciphertext references, or protected evidence."
|
|
),
|
|
contract_version="0.1.0",
|
|
),
|
|
},
|
|
migration_spec=MigrationSpec(
|
|
module_id=MODULE_ID,
|
|
metadata=Base.metadata,
|
|
script_location=str(Path(__file__).with_name("migrations") / "versions"),
|
|
retirement_supported=True,
|
|
retirement_provider=drop_table_retirement_provider(
|
|
models.RecoveryApproval,
|
|
models.RecoveryCeremony,
|
|
models.ProtectionMigration,
|
|
models.ContentProtectionRecord,
|
|
models.EncryptionLocalProviderOperation,
|
|
models.EncryptionLocalWrappedContentKey,
|
|
models.EncryptionLocalKeyMaterial,
|
|
models.EncryptionKeyOperation,
|
|
models.EncryptionKeyVersion,
|
|
models.EncryptionVault,
|
|
label=MODULE_NAME,
|
|
),
|
|
retirement_notes=(
|
|
"Destructive retirement remains blocked until disable preflight "
|
|
"proves that no unresolved protected envelope remains."
|
|
),
|
|
),
|
|
uninstall_guard_providers=(
|
|
_disable_guard,
|
|
persistent_table_uninstall_guard(
|
|
models.EncryptionVault,
|
|
models.EncryptionKeyVersion,
|
|
models.EncryptionKeyOperation,
|
|
models.ContentProtectionRecord,
|
|
models.ProtectionMigration,
|
|
models.RecoveryCeremony,
|
|
models.RecoveryApproval,
|
|
models.EncryptionLocalKeyMaterial,
|
|
models.EncryptionLocalWrappedContentKey,
|
|
models.EncryptionLocalProviderOperation,
|
|
label=MODULE_NAME,
|
|
),
|
|
),
|
|
documentation=(
|
|
DocumentationTopic(
|
|
id="encryption.data-subject-requests",
|
|
title="Encryption data-subject requests",
|
|
summary=(
|
|
"Export cryptographic custody participation without exposing protected "
|
|
"content or key material."
|
|
),
|
|
body=(
|
|
"Encryption correlates only an exact tenant account identifier and can "
|
|
"narrow an already verified search to a vault, key operation, envelope, "
|
|
"migration, or recovery ceremony. The export reports minimized vault "
|
|
"administration, key-operation requests, protection registrations, "
|
|
"migrations, and recovery participation. It never returns provider or "
|
|
"public key references, wrapped keys, nonces, ciphertext locations, "
|
|
"resource identifiers, digests, request payloads, assurance and policy "
|
|
"references, recovery reasons, idempotency keys, or provenance. Feature "
|
|
"modules remain responsible for exporting the plaintext semantics of "
|
|
"their own protected resources. Cryptographic lifecycle and custody "
|
|
"attribution remains immutable security evidence and is retained rather "
|
|
"than automatically erased."
|
|
),
|
|
layer="configured",
|
|
documentation_types=("admin", "user"),
|
|
audience=("user", "administrator", "security_officer", "auditor"),
|
|
related_modules=("core", "identity_trust", "audit", "policy"),
|
|
order=95,
|
|
metadata={
|
|
"kind": "reference",
|
|
"help_contexts": [
|
|
"encryption.admin.operations",
|
|
"privacy.data-subject-requests",
|
|
],
|
|
"consequence_classes": {
|
|
"export_custody_attribution": (
|
|
"Returns minimized lifecycle activity for the exact account."
|
|
),
|
|
"exclude_cryptographic_secrets": (
|
|
"Never returns key material, ciphertext references, nonces, or protected evidence."
|
|
),
|
|
"retain_cryptographic_evidence": (
|
|
"Preserves immutable custody and recovery accountability."
|
|
),
|
|
},
|
|
},
|
|
translations={
|
|
"de": {
|
|
"title": "Datenschutzanfragen zur Verschlüsselung",
|
|
"summary": (
|
|
"Mitwirkung an kryptografischer Verwahrung ausgeben, ohne geschützte Inhalte oder Schlüsselmaterial offenzulegen."
|
|
),
|
|
"body": (
|
|
"Encryption gleicht ausschließlich eine exakte Mandantenkontokennung ab und kann eine bereits verifizierte "
|
|
"Suche auf einen Tresor, Schlüsselvorgang, Umschlag, eine Migration oder Wiederherstellungszeremonie "
|
|
"einschränken. Die Ausgabe meldet minimierte Tresoradministration, Schlüsselvorgangsanfragen, "
|
|
"Schutzregistrierungen, Migrationen und Wiederherstellungsmitwirkung. Sie enthält niemals Anbieter- oder "
|
|
"öffentliche Schlüsselverweise, umhüllte Schlüssel, Nonces, Chiffratorte, Ressourcenkennungen, Prüfsummen, "
|
|
"Anfrageinhalte, Zusicherungs- und Regelverweise, Wiederherstellungsgründe, Idempotenzschlüssel oder Provenienz. "
|
|
"Fachmodule bleiben für die Ausgabe der Klartextsemantik ihrer geschützten Ressourcen verantwortlich. "
|
|
"Zuordnungen des kryptografischen Lebenszyklus und der Verwahrung bleiben unveränderliche Sicherheitsnachweise "
|
|
"und werden nicht automatisch gelöscht."
|
|
),
|
|
}
|
|
},
|
|
structured_translation_version="1",
|
|
structured_translations={
|
|
"de": {
|
|
"consequence_classes": {
|
|
"export_custody_attribution": "Gibt minimierte Lebenszyklusaktivität für das exakte Konto zurück.",
|
|
"exclude_cryptographic_secrets": "Gibt niemals Schlüsselmaterial, Chiffratverweise, Nonces oder geschützte Nachweise zurück.",
|
|
"retain_cryptographic_evidence": "Bewahrt unveränderliche Verantwortungsnachweise zu Verwahrung und Wiederherstellung.",
|
|
}
|
|
}
|
|
},
|
|
),
|
|
DocumentationTopic(
|
|
id="encryption.boundary",
|
|
title="Encryption and key-custody boundary",
|
|
summary=(
|
|
"Optional vault, content-protection, rotation, recovery, and "
|
|
"disable-assurance capabilities."
|
|
),
|
|
body=(
|
|
"Encryption protects feature-owned content without taking over "
|
|
"its business ownership. Resource ownership recovery never "
|
|
"implicitly grants cryptographic keys. High-risk lifecycle "
|
|
"actions require recent Identity Trust assurance. Disabling is "
|
|
"blocked until each envelope is migrated, decrypted, explicitly "
|
|
"exported, or cryptographically destroyed. The bundled local "
|
|
"AES-GCM provider is server-readable and requires the deployment "
|
|
"master key; it does not imply end-to-end encryption."
|
|
),
|
|
layer="available",
|
|
documentation_types=("admin", "user"),
|
|
audience=(
|
|
"user",
|
|
"administrator",
|
|
"security_officer",
|
|
"product_owner",
|
|
"auditor",
|
|
),
|
|
related_modules=OPTIONAL_DEPENDENCIES,
|
|
order=100,
|
|
links=(
|
|
DocumentationLink(
|
|
label="Encryption boundary and threat model",
|
|
href="govoplan-encryption/docs/ENCRYPTION_BOUNDARY.md",
|
|
kind="repository",
|
|
),
|
|
),
|
|
metadata={"kind": "reference"},
|
|
translations={
|
|
"de": {
|
|
"title": "Abgrenzung von Verschlüsselung und Schlüsselverwahrung",
|
|
"summary": (
|
|
"Optionale Fähigkeiten für Tresore, Inhaltsschutz, Rotation, Wiederherstellung und Deaktivierungsnachweise."
|
|
),
|
|
"body": (
|
|
"Encryption schützt fachmoduleigene Inhalte, ohne deren fachliche Eigentümerschaft zu übernehmen. Die "
|
|
"Wiederherstellung von Ressourceneigentum gewährt niemals stillschweigend kryptografische Schlüssel. "
|
|
"Lebenszyklusaktionen mit hohem Risiko erfordern eine aktuelle Identity-Trust-Zusicherung. Die Deaktivierung "
|
|
"bleibt gesperrt, bis jeder Umschlag migriert, entschlüsselt, ausdrücklich exportiert oder kryptografisch "
|
|
"vernichtet wurde. Der mitgelieferte lokale AES-GCM-Anbieter ist serverseitig lesbar und erfordert den "
|
|
"Deployment-Hauptschlüssel; er begründet keine Ende-zu-Ende-Verschlüsselung."
|
|
),
|
|
}
|
|
},
|
|
),
|
|
DocumentationTopic(
|
|
id="encryption.administration",
|
|
title="Administer encryption operations",
|
|
summary=(
|
|
"Inspect safe vault and envelope metadata, govern key lifecycle, "
|
|
"coordinate migrations, and verify disable readiness."
|
|
),
|
|
body=(
|
|
"Encryption administration exposes bounded tenant metadata but "
|
|
"never provider key references, wrapped keys, ciphertext locations, "
|
|
"or plaintext. Rotation creates a new current version while existing "
|
|
"envelopes remain version-bound. Revocation and destruction cannot "
|
|
"recall material already obtained and can make content unavailable. "
|
|
"Migrations remain two-phase: the owning module performs the durable "
|
|
"content operation and records evidence before success. Disable "
|
|
"preflight blocks until every envelope has a terminal disposition."
|
|
),
|
|
layer="available",
|
|
documentation_types=("admin",),
|
|
audience=("administrator", "security_officer", "auditor"),
|
|
related_modules=OPTIONAL_DEPENDENCIES,
|
|
order=110,
|
|
metadata={"kind": "reference"},
|
|
translations={
|
|
"de": {
|
|
"title": "Verschlüsselungsvorgänge administrieren",
|
|
"summary": (
|
|
"Sichere Tresor- und Umschlagmetadaten prüfen, den Schlüssellebenszyklus steuern, Migrationen koordinieren und Deaktivierungsbereitschaft nachweisen."
|
|
),
|
|
"body": (
|
|
"Die Encryption-Administration zeigt begrenzte Mandantenmetadaten, aber niemals Anbieterschlüsselverweise, "
|
|
"umhüllte Schlüssel, Chiffratorte oder Klartext. Rotation erzeugt eine neue aktuelle Version, während "
|
|
"bestehende Umschläge an ihre Version gebunden bleiben. Widerruf und Vernichtung können bereits erlangtes "
|
|
"Material nicht zurückrufen und Inhalte unzugänglich machen. Migrationen bleiben zweiphasig: Das "
|
|
"Eigentümermodul führt den dauerhaften Inhaltsvorgang aus und hält vor Erfolg Nachweise fest. Die "
|
|
"Deaktivierungsvorprüfung sperrt, bis jeder Umschlag einen endgültigen Verbleib hat."
|
|
),
|
|
}
|
|
},
|
|
),
|
|
DocumentationTopic(
|
|
id="encryption.recovery",
|
|
title="Run an encryption recovery ceremony",
|
|
summary=(
|
|
"Request and decide time-bounded recovery with high assurance and "
|
|
"a distinct-custodian quorum."
|
|
),
|
|
body=(
|
|
"A recovery requester supplies policy and recent high-assurance "
|
|
"evidence and cannot approve the same ceremony. Each custodian can "
|
|
"decide once; a rejection terminates the request and approvals must "
|
|
"reach the vault quorum before expiry. Approval authorizes a later "
|
|
"provider operation. It does not release key material, transfer "
|
|
"resource ownership, or prove that recovery execution succeeded."
|
|
),
|
|
layer="available",
|
|
documentation_types=("admin", "user"),
|
|
audience=("administrator", "security_officer", "auditor"),
|
|
conditions=(
|
|
DocumentationCondition(required_scopes=(RECOVERY_SCOPE,)),
|
|
),
|
|
related_modules=("identity_trust", "access", "audit", "policy"),
|
|
order=120,
|
|
metadata={"kind": "workflow"},
|
|
translations={
|
|
"de": {
|
|
"title": "Wiederherstellungszeremonie für Verschlüsselung durchführen",
|
|
"summary": (
|
|
"Zeitlich begrenzte Wiederherstellung mit hoher Zusicherung und Quorum unterschiedlicher Verwahrender beantragen und entscheiden."
|
|
),
|
|
"body": (
|
|
"Die antragstellende Person legt Regel und aktuellen Nachweis hoher Zusicherung vor und darf dieselbe "
|
|
"Zeremonie nicht genehmigen. Jede verwahrende Person kann genau einmal entscheiden; eine Ablehnung beendet "
|
|
"den Antrag und Genehmigungen müssen das Tresorquorum vor Ablauf erreichen. Die Genehmigung autorisiert einen "
|
|
"späteren Anbietervorgang. Sie gibt kein Schlüsselmaterial frei, überträgt kein Ressourceneigentum und beweist "
|
|
"nicht, dass die Wiederherstellung erfolgreich ausgeführt wurde."
|
|
),
|
|
}
|
|
},
|
|
),
|
|
),
|
|
architecture=declared_module_architecture(
|
|
layer="institutional_foundation",
|
|
kind="foundation",
|
|
maturity="vertical_slice",
|
|
documentation_ref="docs/ENCRYPTION_BOUNDARY.md",
|
|
test_ref="tests/test_encryption.py",
|
|
known_limits=(
|
|
"The bundled local AES-256-GCM provider is a server-side reference provider backed by shared SQL state and MASTER_KEY_B64; it is not an HSM/KMS, client E2EE protocol, or independent certification.",
|
|
"A true E2EE claim remains prohibited until a selected client/provider profile passes its threat model, interoperability fixtures, backup/restore tests, and independent review.",
|
|
),
|
|
owned_concepts=(
|
|
"key vault",
|
|
"content-protection envelope",
|
|
"cryptographic recovery ceremony",
|
|
),
|
|
non_owned_concepts=(
|
|
"domain content",
|
|
"resource ownership",
|
|
"account authentication",
|
|
"provider key material",
|
|
),
|
|
migration_docs=("docs/ENCRYPTION_BOUNDARY.md",),
|
|
recovery_docs=("docs/ENCRYPTION_BOUNDARY.md",),
|
|
security_docs=("docs/ENCRYPTION_BOUNDARY.md",),
|
|
operations_docs=("README.md",),
|
|
),
|
|
)
|
|
|
|
|
|
def get_manifest() -> ModuleManifest:
|
|
return manifest
|
|
|
|
|
|
__all__ = [
|
|
"ADMIN_SCOPE",
|
|
"MODULE_ID",
|
|
"MODULE_VERSION",
|
|
"RECOVERY_SCOPE",
|
|
"USE_SCOPE",
|
|
"get_manifest",
|
|
"manifest",
|
|
]
|