"""Sanctioned MCP daemon guards for imports and credential access (#558). Direct ``import gitea_mcp_server`` / ``import gitea_auth`` from a shell, plus raw keychain dumps, bypass preflight purity and role gates. Mutation helpers and keychain fallbacks therefore require an explicit sanctioned runtime. Sanctioned contexts (any one): - ``GITEA_MCP_SANCTIONED_DAEMON=1`` (set by the official MCP entrypoint) - pytest (``PYTEST_CURRENT_TEST`` present) - explicit operator opt-in ``GITEA_ALLOW_DIRECT_MCP_IMPORT=1`` (tests/tools only) Credential keychain fill additionally allows: - ``GITEA_ALLOW_KEYCHAIN_CLI=1`` for operator-only non-MCP scripts that must use git-credential (never the default for LLM shells). """ from __future__ import annotations import os from typing import Any SANCTIONED_DAEMON_ENV = "GITEA_MCP_SANCTIONED_DAEMON" ALLOW_DIRECT_IMPORT_ENV = "GITEA_ALLOW_DIRECT_MCP_IMPORT" ALLOW_KEYCHAIN_CLI_ENV = "GITEA_ALLOW_KEYCHAIN_CLI" class UnsanctionedRuntimeError(RuntimeError): """Raised when mutation/credential code runs outside a sanctioned MCP daemon.""" def is_pytest_runtime() -> bool: return bool((os.environ.get("PYTEST_CURRENT_TEST") or "").strip()) def is_sanctioned_mcp_daemon() -> bool: if (os.environ.get(SANCTIONED_DAEMON_ENV) or "").strip() in {"1", "true", "yes"}: return True if (os.environ.get(ALLOW_DIRECT_IMPORT_ENV) or "").strip() in {"1", "true", "yes"}: return True if is_pytest_runtime(): return True return False def mark_sanctioned_daemon() -> None: """Call from the official MCP server entrypoint before serving tools.""" os.environ[SANCTIONED_DAEMON_ENV] = "1" def assert_sanctioned_mutation_runtime(context: str = "mutation") -> None: """Fail closed when server mutation code is used outside the MCP daemon.""" if is_sanctioned_mcp_daemon(): return raise UnsanctionedRuntimeError( f"Unsanctioned runtime blocked {context} (#558). " "Do not import gitea_mcp_server / call mutation helpers from a raw " "shell or ad-hoc script. Use the official MCP daemon entrypoint " f"(sets {SANCTIONED_DAEMON_ENV}=1), or run under pytest. " f"Operator-only override: {ALLOW_DIRECT_IMPORT_ENV}=1 (not for LLM sessions)." ) def assert_keychain_access_allowed() -> None: """Fail closed for git-credential keychain fill outside sanctioned contexts.""" if is_sanctioned_mcp_daemon(): return if (os.environ.get(ALLOW_KEYCHAIN_CLI_ENV) or "").strip() in {"1", "true", "yes"}: return raise UnsanctionedRuntimeError( "Unsanctioned keychain/credential fill blocked (#558). " "Token extraction via git-credential is only allowed inside the " f"official MCP daemon ({SANCTIONED_DAEMON_ENV}=1), pytest, or with " f"explicit operator opt-in {ALLOW_KEYCHAIN_CLI_ENV}=1." ) def runtime_status() -> dict[str, Any]: return { "sanctioned_daemon": is_sanctioned_mcp_daemon(), "pytest": is_pytest_runtime(), "sanctioned_env": SANCTIONED_DAEMON_ENV, "allow_direct_import_env": ALLOW_DIRECT_IMPORT_ENV, "allow_keychain_cli_env": ALLOW_KEYCHAIN_CLI_ENV, }