Files
govoplan-encryption/src/govoplan_encryption/backend/db/models.py
T

454 lines
19 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Any
import uuid
from sqlalchemy import (
DateTime,
Index,
Integer,
JSON,
LargeBinary,
String,
Text,
UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column
from govoplan_core.db.base import Base, TimestampMixin
def new_uuid() -> str:
return str(uuid.uuid4())
class EncryptionVault(Base, TimestampMixin):
__tablename__ = "encryption_vaults"
__table_args__ = (
UniqueConstraint("tenant_id", "vault_id", name="uq_encryption_vault"),
UniqueConstraint(
"tenant_id",
"create_idempotency_key",
name="uq_encryption_vault_create_idempotency",
),
Index(
"ix_encryption_vault_scope",
"tenant_id",
"scope_type",
"scope_id",
"state",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
vault_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
name: Mapped[str] = mapped_column(String(255), nullable=False)
provider_id: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
purpose: Mapped[str] = mapped_column(String(255), nullable=False)
profile_kind: Mapped[str] = mapped_column(String(40), nullable=False)
scope_type: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
scope_id: Mapped[str | None] = mapped_column(String(255), nullable=True, index=True)
policy_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
recovery_quorum: Mapped[int] = mapped_column(Integer, nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
revision: Mapped[int] = mapped_column(Integer, default=1, nullable=False)
current_key_version: Mapped[int | None] = mapped_column(Integer, nullable=True)
create_idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
create_request_digest: Mapped[str] = mapped_column(String(64), nullable=False)
provenance: Mapped[dict[str, Any]] = mapped_column(
JSON, default=dict, nullable=False
)
created_by: Mapped[str] = mapped_column(String(255), nullable=False)
updated_by: Mapped[str] = mapped_column(String(255), nullable=False)
class EncryptionKeyVersion(Base, TimestampMixin):
__tablename__ = "encryption_key_versions"
__table_args__ = (
UniqueConstraint(
"tenant_id",
"vault_id",
"version",
name="uq_encryption_key_version",
),
UniqueConstraint(
"tenant_id",
"provider_id",
"provider_key_ref",
name="uq_encryption_provider_key_ref",
),
Index(
"ix_encryption_key_vault_state",
"tenant_id",
"vault_id",
"state",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
vault_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
version: Mapped[int] = mapped_column(Integer, nullable=False)
provider_id: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
provider_key_ref: Mapped[str | None] = mapped_column(String(1000), nullable=True)
algorithm_suite: Mapped[str] = mapped_column(String(120), nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
public_key_ref: Mapped[str | None] = mapped_column(String(1000), nullable=True)
imported: Mapped[bool] = mapped_column(default=False, nullable=False)
exportable: Mapped[bool] = mapped_column(default=False, nullable=False)
provider_version: Mapped[str | None] = mapped_column(String(120), nullable=True)
provider_provenance: Mapped[dict[str, Any]] = mapped_column(
JSON, default=dict, nullable=False
)
activated_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
revoked_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
destruction_scheduled_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
destroyed_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class EncryptionKeyOperation(Base, TimestampMixin):
__tablename__ = "encryption_key_operations"
__table_args__ = (
UniqueConstraint(
"tenant_id", "idempotency_key", name="uq_encryption_key_operation_idem"
),
Index(
"ix_encryption_key_operation_state",
"tenant_id",
"state",
"updated_at",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
vault_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
key_version: Mapped[int] = mapped_column(Integer, nullable=False)
operation: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
provider_id: Mapped[str] = mapped_column(String(120), nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_digest: Mapped[str] = mapped_column(String(64), nullable=False)
request_payload: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
error_code: Mapped[str | None] = mapped_column(String(255), nullable=True)
policy_decision_ref: Mapped[str | None] = mapped_column(String(1000), nullable=True)
assurance_evidence_ref: Mapped[str | None] = mapped_column(
String(1000), nullable=True
)
requested_by: Mapped[str] = mapped_column(String(255), nullable=False)
completed_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class EncryptionLocalKeyMaterial(Base, TimestampMixin):
"""Provider-owned wrapped data-encryption key material.
The configured deployment master key never enters this table. The raw data
key exists only inside the provider while a cryptographic operation runs.
"""
__tablename__ = "encryption_local_key_material"
__table_args__ = (
UniqueConstraint(
"provider_key_ref",
name="uq_encryption_local_provider_key_ref",
),
UniqueConstraint(
"tenant_id",
"vault_id",
"key_version",
name="uq_encryption_local_vault_key_version",
),
UniqueConstraint(
"tenant_id",
"provision_idempotency_key",
name="uq_encryption_local_provision_idempotency",
),
Index(
"ix_encryption_local_key_state",
"tenant_id",
"state",
"updated_at",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
vault_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
key_version: Mapped[int] = mapped_column(Integer, nullable=False)
provider_key_ref: Mapped[str] = mapped_column(
String(255), nullable=False, index=True
)
algorithm_suite: Mapped[str] = mapped_column(String(120), nullable=False)
purpose: Mapped[str] = mapped_column(String(255), nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
wrapped_key: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
wrap_nonce: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
wrap_context_sha256: Mapped[str] = mapped_column(String(64), nullable=False)
provision_idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
provision_request_sha256: Mapped[str] = mapped_column(String(64), nullable=False)
revoked_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
destruction_scheduled_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
destroyed_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class EncryptionLocalWrappedContentKey(Base, TimestampMixin):
__tablename__ = "encryption_local_wrapped_content_keys"
__table_args__ = (
UniqueConstraint(
"wrapped_key_ref",
name="uq_encryption_local_wrapped_key_ref",
),
UniqueConstraint(
"tenant_id",
"idempotency_key",
name="uq_encryption_local_content_idempotency",
),
Index(
"ix_encryption_local_content_state",
"tenant_id",
"state",
"updated_at",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
wrapped_key_ref: Mapped[str] = mapped_column(
String(255), nullable=False, index=True
)
provider_key_ref: Mapped[str] = mapped_column(
String(255), nullable=False, index=True
)
algorithm_suite: Mapped[str] = mapped_column(String(120), nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
wrapped_content_key: Mapped[bytes | None] = mapped_column(
LargeBinary, nullable=True
)
wrap_nonce: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
content_nonce: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
authenticated_context_sha256: Mapped[str] = mapped_column(
String(64), nullable=False
)
plaintext_commitment: Mapped[str] = mapped_column(String(64), nullable=False)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_sha256: Mapped[str] = mapped_column(String(64), nullable=False)
source_wrapped_key_ref: Mapped[str | None] = mapped_column(
String(255), nullable=True
)
destroyed_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class EncryptionLocalProviderOperation(Base, TimestampMixin):
__tablename__ = "encryption_local_provider_operations"
__table_args__ = (
UniqueConstraint(
"tenant_id",
"idempotency_key",
name="uq_encryption_local_provider_operation_idem",
),
Index(
"ix_encryption_local_provider_operation_state",
"tenant_id",
"state",
"updated_at",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
operation: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
target_ref: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
outcome_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_sha256: Mapped[str] = mapped_column(String(64), nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
completed_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class ContentProtectionRecord(Base, TimestampMixin):
__tablename__ = "encryption_content_protections"
__table_args__ = (
UniqueConstraint(
"tenant_id", "envelope_id", name="uq_encryption_content_envelope"
),
UniqueConstraint(
"tenant_id",
"idempotency_key",
name="uq_encryption_content_idempotency",
),
Index(
"ix_encryption_content_owner",
"tenant_id",
"owner_module",
"resource_type",
"resource_id",
),
Index("ix_encryption_content_state", "tenant_id", "state", "updated_at"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
envelope_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
owner_module: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
resource_type: Mapped[str] = mapped_column(String(120), nullable=False)
resource_id: Mapped[str] = mapped_column(String(255), nullable=False)
profile_kind: Mapped[str] = mapped_column(String(40), nullable=False)
profile_id: Mapped[str] = mapped_column(String(255), nullable=False)
provider_id: Mapped[str] = mapped_column(String(120), nullable=False)
vault_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
key_version: Mapped[int] = mapped_column(Integer, nullable=False)
algorithm_suite: Mapped[str] = mapped_column(String(120), nullable=False)
ciphertext_ref: Mapped[str] = mapped_column(String(2000), nullable=False)
ciphertext_digest: Mapped[str] = mapped_column(String(255), nullable=False)
authenticated_context_digest: Mapped[str] = mapped_column(
String(255), nullable=False
)
wrapped_key_refs: Mapped[list[str]] = mapped_column(
JSON, default=list, nullable=False
)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
source_envelope_id: Mapped[str | None] = mapped_column(String(255), nullable=True)
migration_id: Mapped[str | None] = mapped_column(String(36), nullable=True)
envelope_metadata: Mapped[dict[str, Any]] = mapped_column(
JSON, default=dict, nullable=False
)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_digest: Mapped[str] = mapped_column(String(64), nullable=False)
policy_decision_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
registered_by: Mapped[str] = mapped_column(String(255), nullable=False)
class ProtectionMigration(Base, TimestampMixin):
__tablename__ = "encryption_protection_migrations"
__table_args__ = (
UniqueConstraint(
"tenant_id",
"idempotency_key",
name="uq_encryption_migration_idempotency",
),
Index("ix_encryption_migration_state", "tenant_id", "state", "updated_at"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
source_envelope_id: Mapped[str] = mapped_column(
String(255), nullable=False, index=True
)
target_envelope_id: Mapped[str | None] = mapped_column(String(255), nullable=True)
target_provider_id: Mapped[str] = mapped_column(String(120), nullable=False)
target_vault_id: Mapped[str] = mapped_column(String(255), nullable=False)
target_key_version: Mapped[int] = mapped_column(Integer, nullable=False)
target_algorithm_suite: Mapped[str] = mapped_column(String(120), nullable=False)
mode: Mapped[str] = mapped_column(String(40), nullable=False)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
policy_decision_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
assurance_evidence_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_digest: Mapped[str] = mapped_column(String(64), nullable=False)
evidence_refs: Mapped[list[str]] = mapped_column(JSON, default=list, nullable=False)
error_code: Mapped[str | None] = mapped_column(String(255), nullable=True)
provenance: Mapped[dict[str, Any]] = mapped_column(
JSON, default=dict, nullable=False
)
requested_by: Mapped[str] = mapped_column(String(255), nullable=False)
completed_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class RecoveryCeremony(Base, TimestampMixin):
__tablename__ = "encryption_recovery_ceremonies"
__table_args__ = (
UniqueConstraint(
"tenant_id",
"idempotency_key",
name="uq_encryption_recovery_idempotency",
),
Index("ix_encryption_recovery_state", "tenant_id", "state", "expires_at"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
vault_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
state: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
requested_scope: Mapped[str] = mapped_column(String(255), nullable=False)
reason: Mapped[str] = mapped_column(Text, nullable=False)
quorum: Mapped[int] = mapped_column(Integer, nullable=False)
revision: Mapped[int] = mapped_column(Integer, default=1, nullable=False)
policy_decision_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
requester_assurance_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
requester_account_id: Mapped[str] = mapped_column(String(255), nullable=False)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_digest: Mapped[str] = mapped_column(String(64), nullable=False)
expires_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, index=True
)
execution_ref: Mapped[str | None] = mapped_column(String(1000), nullable=True)
provenance: Mapped[dict[str, Any]] = mapped_column(
JSON, default=dict, nullable=False
)
class RecoveryApproval(Base, TimestampMixin):
__tablename__ = "encryption_recovery_approvals"
__table_args__ = (
UniqueConstraint(
"tenant_id",
"recovery_id",
"approver_account_id",
name="uq_encryption_recovery_approver",
),
UniqueConstraint(
"tenant_id",
"idempotency_key",
name="uq_encryption_recovery_approval_idem",
),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
recovery_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
approver_account_id: Mapped[str] = mapped_column(String(255), nullable=False)
decision: Mapped[str] = mapped_column(String(20), nullable=False)
reason: Mapped[str] = mapped_column(Text, nullable=False)
assurance_evidence_ref: Mapped[str] = mapped_column(String(1000), nullable=False)
idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False)
request_digest: Mapped[str] = mapped_column(String(64), nullable=False)
__all__ = [
"ContentProtectionRecord",
"EncryptionKeyOperation",
"EncryptionKeyVersion",
"EncryptionLocalKeyMaterial",
"EncryptionLocalProviderOperation",
"EncryptionLocalWrappedContentKey",
"EncryptionVault",
"ProtectionMigration",
"RecoveryApproval",
"RecoveryCeremony",
"new_uuid",
]