Source code for mlflow.entities.gateway_secrets

import json
from dataclasses import dataclass
from typing import Any

from mlflow.entities._mlflow_object import _MlflowObject
from mlflow.protos.service_pb2 import GatewaySecretInfo as ProtoGatewaySecretInfo


[docs]@dataclass(frozen=True) class GatewaySecretInfo(_MlflowObject): """ Metadata about an encrypted secret for authenticating with LLM providers. This entity contains metadata, masked value, and auth configuration of a secret, but NOT the decrypted secret value itself. The actual secret is stored encrypted using envelope encryption (DEK encrypted by KEK). NB: secret_id and secret_name are IMMUTABLE after creation. They are used as AAD (Additional Authenticated Data) during AES-GCM encryption. If either is modified in the database, decryption will fail. To "rename" a secret, create a new one with the desired name and delete the old one. See mlflow/utils/crypto.py:_create_aad(). This dataclass is frozen (immutable) because: 1. It represents a read-only view of database state 2. secret_id and secret_name must never be modified (used in encryption AAD) 3. Database triggers also enforce immutability of these fields Args: secret_id: Unique identifier for this secret. IMMUTABLE - used in AAD for encryption. secret_name: User-friendly name for the secret. IMMUTABLE - used in AAD for encryption. masked_value: Masked version of the secret for display (e.g., "sk-...xyz123"). created_at: Timestamp (milliseconds) when the secret was created. last_updated_at: Timestamp (milliseconds) when the secret was last updated. provider: LLM provider this secret is for (e.g., "openai", "anthropic"). auth_config: Provider-specific configuration (e.g., region, project_id). This is non-sensitive metadata useful for UI disambiguation. created_by: User ID who created the secret. last_updated_by: User ID who last updated the secret. """ secret_id: str secret_name: str masked_value: str created_at: int last_updated_at: int provider: str | None = None auth_config: dict[str, Any] | None = None created_by: str | None = None last_updated_by: str | None = None
[docs] def to_proto(self): proto = ProtoGatewaySecretInfo() proto.secret_id = self.secret_id proto.secret_name = self.secret_name proto.masked_value = self.masked_value proto.created_at = self.created_at proto.last_updated_at = self.last_updated_at if self.provider is not None: proto.provider = self.provider if self.auth_config is not None: proto.auth_config_json = json.dumps(self.auth_config) if self.created_by is not None: proto.created_by = self.created_by if self.last_updated_by is not None: proto.last_updated_by = self.last_updated_by return proto
[docs] @classmethod def from_proto(cls, proto): auth_config = None if proto.auth_config_json: auth_config = json.loads(proto.auth_config_json) return cls( secret_id=proto.secret_id, secret_name=proto.secret_name, masked_value=proto.masked_value, created_at=proto.created_at, last_updated_at=proto.last_updated_at, provider=proto.provider or None, auth_config=auth_config, created_by=proto.created_by or None, last_updated_by=proto.last_updated_by or None, )