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", ]