34 lines
1.1 KiB
Python
34 lines
1.1 KiB
Python
"""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
|