#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Central guard for Gemini API egress. Gemini is emergency fallback only in this project. A plain API key must never be enough to spend money: traffic is blocked by default with a hard kill switch, and operators must explicitly unlock emergency fallback before any code path may initialize the SDK or call the REST API. """ from __future__ import annotations import os _TRUE_VALUES = {"1", "true", "yes", "on"} _FALSE_VALUES = {"0", "false", "no", "off"} def _env_flag(name: str, default: str) -> bool: value = os.getenv(name, default).strip().lower() if value in _TRUE_VALUES: return True if value in _FALSE_VALUES: return False return default.strip().lower() in _TRUE_VALUES def is_gemini_hard_disabled() -> bool: """Master kill switch. Default true means zero Gemini API egress.""" return _env_flag("GEMINI_API_HARD_DISABLED", "true") def _context_allowed(context: str | None) -> bool: """Optional allowlist for emergency fallback contexts.""" raw = os.getenv("GEMINI_ALLOWED_CONTEXTS", "").strip() if not raw: return True if not context: return False allowed = {item.strip() for item in raw.split(",") if item.strip()} return context in allowed def is_gemini_fallback_enabled(context: str | None = None) -> bool: """Return whether Gemini fallback traffic is allowed for this process.""" if is_gemini_hard_disabled(): return False if not _env_flag("GEMINI_FALLBACK_ENABLED", "false"): return False return _context_allowed(context) def get_gemini_api_key(context: str | None = None) -> str: """Return the Gemini API key only when fallback traffic is enabled.""" if not is_gemini_fallback_enabled(context): return "" return os.getenv("GEMINI_API_KEY", "") def gemini_disabled_message(context: str | None = None) -> str: """Human-readable reason for telemetry and error paths.""" suffix = f" ({context})" if context else "" if is_gemini_hard_disabled(): return f"Gemini API hard-disabled by GEMINI_API_HARD_DISABLED=true{suffix}" if not _env_flag("GEMINI_FALLBACK_ENABLED", "false"): return f"Gemini fallback disabled by GEMINI_FALLBACK_ENABLED=false{suffix}" if not _context_allowed(context): return f"Gemini fallback context not allowed by GEMINI_ALLOWED_CONTEXTS{suffix}" return f"Gemini fallback disabled{suffix}"