"""Runtime configuration resolved from environment and repo layout. Nothing here is a secret. Backend auth (BAO_TOKEN / bootstrap token files) is resolved lazily inside the backend adapter, never cached on disk by this module. """ from __future__ import annotations import os from dataclasses import dataclass from pathlib import Path def repo_root() -> Path: """Repo root = nearest ancestor containing pyproject.toml (fallback: cwd).""" here = Path(__file__).resolve() for parent in (here, *here.parents): if (parent / "pyproject.toml").exists(): return parent return Path.cwd() @dataclass(frozen=True) class Config: catalog_dir: Path policy_dir: Path evidence_dir: Path hub_url: str bao_addr: str topic_id: str approval_url: str = "" approval_token_file: Path | None = None @classmethod def load(cls) -> "Config": root = repo_root() token_file = os.environ.get("SECRETS_ENGINE_APPROVAL_TOKEN_FILE", "") return cls( catalog_dir=Path(os.environ.get("SECRETS_ENGINE_CATALOG", root / "catalog")), policy_dir=Path(os.environ.get("SECRETS_ENGINE_POLICIES", root / "policies")), evidence_dir=Path(os.environ.get("SECRETS_ENGINE_EVIDENCE", root / ".evidence")), hub_url=os.environ.get("SECRETS_ENGINE_HUB_URL", "http://127.0.0.1:8000"), bao_addr=os.environ.get("BAO_ADDR", os.environ.get("VAULT_ADDR", "http://127.0.0.1:8200")), topic_id=os.environ.get( "SECRETS_ENGINE_TOPIC_ID", "cee7bedf-2b48-46ef-8601-006474f2ad7a" ), approval_url=os.environ.get("SECRETS_ENGINE_APPROVAL_URL", ""), approval_token_file=Path(token_file) if token_file else None, )