secrets.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. """Deployable, fail-closed connector secret reference resolution."""
  2. from __future__ import annotations
  3. import os
  4. import re
  5. from collections.abc import Mapping
  6. from app.core.connectors.errors import ConnectorConfigurationError
  7. ENV_REFERENCE = re.compile(r"^env:(DATAOPS_CONNECTOR_[A-Z0-9_]{1,200})$")
  8. class EnvironmentSecretResolver:
  9. """Resolve only the dedicated DATAOPS_CONNECTOR_* environment namespace."""
  10. def __init__(self, environ: Mapping[str, str] | None = None):
  11. self.environ = os.environ if environ is None else environ
  12. def __call__(self, reference: str) -> str:
  13. value = str(reference or "")
  14. match = ENV_REFERENCE.fullmatch(value)
  15. if match:
  16. secret = self.environ.get(match.group(1))
  17. if not isinstance(secret, str) or not secret.strip():
  18. raise ConnectorConfigurationError(
  19. "connector environment secret is unavailable"
  20. )
  21. return secret
  22. if value.startswith(("vault:", "secret:")):
  23. raise ConnectorConfigurationError(
  24. "connector secret backend is not configured"
  25. )
  26. raise ConnectorConfigurationError(
  27. "connector environment secret reference is not allowed"
  28. )
  29. __all__ = ["EnvironmentSecretResolver", "ENV_REFERENCE"]