from __future__ import annotations from datetime import datetime from typing import Any, Literal from pydantic import BaseModel, Field class DeviceKeyRegisterPayload(BaseModel): identity_id: str = Field(min_length=1, max_length=255) account_id: str = Field(min_length=1, max_length=255) device_id: str = Field(min_length=1, max_length=255) key_id: str = Field(min_length=1, max_length=255) algorithm: str = Field(min_length=1, max_length=120) public_jwk: dict[str, Any] purpose: Literal["encryption", "signing", "encryption_and_signing"] = "encryption" assurance_level: str = Field(default="software", min_length=1, max_length=80) attestation_ref: str | None = Field(default=None, max_length=1000) expires_at: datetime | None = None idempotency_key: str = Field(min_length=1, max_length=255) class DeviceKeyRevokePayload(BaseModel): expected_epoch: int = Field(ge=1) reason: str = Field(min_length=1, max_length=4000) class DeviceKeyResponse(BaseModel): tenant_id: str identity_id: str account_id: str device_id: str key_id: str algorithm: str public_jwk: dict[str, Any] purpose: str assurance_level: str status: str epoch: int registered_at: datetime attestation_ref: str | None = None expires_at: datetime | None = None revoked_at: datetime | None = None revocation_reason: str | None = None provenance: dict[str, Any] = Field(default_factory=dict) class DeviceKeyListResponse(BaseModel): keys: list[DeviceKeyResponse] class AssuranceEvidenceResponse(BaseModel): id: str tenant_id: str account_id: str device_key_id: str | None = None evidence_ref: str assurance_level: str provider_id: str verified_at: datetime expires_at: datetime active: bool provenance: dict[str, Any] = Field(default_factory=dict) class AssuranceEvidenceListResponse(BaseModel): evidence: list[AssuranceEvidenceResponse] class EpochListResponse(BaseModel): epochs: list[EpochResponse] class EpochRotatePayload(BaseModel): subject_kind: Literal[ "identity", "account", "function", "postbox", "external_recipient" ] subject_id: str = Field(min_length=1, max_length=255) reason: str = Field(min_length=1, max_length=4000) access_decision_ref: str = Field(min_length=1, max_length=1000) idempotency_key: str = Field(min_length=1, max_length=255) history_policy: str = Field(default="all_retained", min_length=1, max_length=80) previous_epoch: int | None = Field(default=None, ge=1) class EpochResponse(BaseModel): tenant_id: str subject_kind: str subject_id: str epoch: int state: str history_policy: str effective_at: datetime previous_epoch: int | None = None reason: str | None = None access_decision_ref: str | None = None provenance: dict[str, Any] = Field(default_factory=dict) class KeyAccessPayload(BaseModel): account_id: str = Field(min_length=1, max_length=255) device_key_id: str = Field(min_length=1, max_length=255) subject_kind: Literal[ "identity", "account", "function", "postbox", "external_recipient" ] subject_id: str = Field(min_length=1, max_length=255) key_epoch: int = Field(ge=1) access_decision_ref: str = Field(min_length=1, max_length=1000) purpose: str = Field(min_length=1, max_length=255) requested_at: datetime function_assignment_id: str | None = Field(default=None, max_length=255) delegation_id: str | None = Field(default=None, max_length=255) resource_ref: str | None = Field(default=None, max_length=1000) class KeyAccessResponse(BaseModel): allowed: bool decision_ref: str reason: str device_key: DeviceKeyResponse | None = None epoch: EpochResponse | None = None audit_event_ref: str | None = None requirements: list[str] = Field(default_factory=list) provenance: dict[str, Any] = Field(default_factory=dict) class KeyAccessDecisionItem(BaseModel): id: str decision_ref: str account_id: str device_key_id: str subject_kind: str subject_id: str key_epoch: int access_decision_ref: str purpose: str allowed: bool reason: str resource_ref: str | None = None function_assignment_id: str | None = None delegation_id: str | None = None provenance: dict[str, Any] = Field(default_factory=dict) created_at: datetime class KeyAccessDecisionListResponse(BaseModel): decisions: list[KeyAccessDecisionItem] class ReferenceOptionsResponse(BaseModel): options: list[dict[str, Any]] = Field(default_factory=list) provider_available: bool = False class AssuranceEvidencePayload(BaseModel): account_id: str = Field(min_length=1, max_length=255) evidence_ref: str = Field(min_length=1, max_length=1000) assurance_level: str = Field(min_length=1, max_length=80) provider_id: str = Field(min_length=1, max_length=120) verified_at: datetime expires_at: datetime device_key_id: str | None = Field(default=None, max_length=255) provenance: dict[str, Any] = Field(default_factory=dict) class AssuranceCheckPayload(BaseModel): account_id: str = Field(min_length=1, max_length=255) purpose: str = Field(min_length=1, max_length=255) minimum_level: str = Field(min_length=1, max_length=80) evidence_ref: str = Field(min_length=1, max_length=1000) evaluated_at: datetime maximum_age_seconds: int = Field(default=300, ge=1, le=86400) device_key_id: str | None = Field(default=None, max_length=255) class AssuranceResponse(BaseModel): allowed: bool reason: str assurance_level: str | None = None evidence_ref: str | None = None verified_at: datetime | None = None expires_at: datetime | None = None provenance: dict[str, Any] = Field(default_factory=dict)