"""Tenant and Cell scoped secret reference model. This module never stores secret values. It stores ownership and retrieval scope metadata for integration with a real secret broker. """ from __future__ import annotations from dataclasses import dataclass from typing import Literal from .tenant_context import ValidationError, require_ident @dataclass(frozen=True) class SecretRef: secret_id: str tenant_id: str cell_id: str kind: Literal["channel", "model", "tool", "runtime"] version: str broker_path: str def __post_init__(self) -> None: for name in ("secret_id", "cell_id", "version"): require_ident(name, getattr(self, name)) require_ident("tenant_id", self.tenant_id, tenant=True) if self.kind not in {"channel", "model", "tool", "runtime"}: raise ValidationError("invalid secret kind") if not self.broker_path.startswith("secret://"): raise ValidationError("secret broker path required") def can_be_used_by(self, *, tenant_id: str, cell_id: str) -> bool: return self.tenant_id == tenant_id and self.cell_id == cell_id