"""Kept-running manifestation of the lifecycle library. This is the same library the CLI uses, in a process that stays up for one injected stage. It is not a second implementation and not a Deployment. """ from __future__ import annotations import os from collections.abc import Iterable, Mapping from typing import Any from secrets_engine import lifecycle as lifecycle_lib from secrets_engine.catalog import CatalogEntry from secrets_engine.lifecycle import LifecyclePlan from secrets_engine.stage_binding import StageBinding, StartupError LOCAL_ALLOW_ENV = "SECRETS_ENGINE_LOCAL_ALLOW" def local_allow_requested(flag: bool = False) -> bool: """True when a caller asked to be allowed. The answer is not authority.""" env = os.environ.get(LOCAL_ALLOW_ENV, "").strip() in {"1", "true", "yes"} return bool(flag) or env def run_service( binding: StageBinding | None, jobs: Iterable[Mapping[str, Any]], ) -> list[LifecyclePlan]: """Run lifecycle jobs for one stage until the job iterable ends. A job may carry ``foreign_stage_credential`` only as a refusal test. A present value refuses the job. The binding credential is never rendered. """ if binding is None or not binding.credential or not binding.stage: raise StartupError("startup refused: no stage credential is present") plans: list[LifecyclePlan] = [] for job in jobs: foreign = str(job.get("foreign_stage_credential") or "") if foreign: raise StartupError( "startup refused: another stage credential is present" ) entry = job.get("entry") if not isinstance(entry, CatalogEntry): raise StartupError("service job is missing a catalog entry") operation = str(job.get("operation") or "") plans.append(lifecycle_lib.build_lifecycle_plan(entry, operation)) return plans def invoke_protected( cfg: Any, entry: CatalogEntry, action: str, *, allow: bool = False, auth_args: Any = None, ) -> Any: """Gate a protected call the way the CLI does. ``allow`` and ``SECRETS_ENGINE_LOCAL_ALLOW`` are recorded as not authority and then discarded. The call still requires a decision record or the published unreachable-engine stance. """ local_allow_requested(allow) from secrets_engine.cli import _require_lane_approval return _require_lane_approval( cfg, entry, action, None, auth_args=auth_args )