Rhodawk Mythos Agent
mythos: ascend to Mythos-level — multi-agent + probabilistic + advanced tooling + RL + MCP suite + FastAPI
14b1bbe
Raw
History Blame Contribute Delete
1.68 kB
"""
Lightweight API-key + OAuth2 bearer authentication for the Mythos API.
Backed by an env-defined static API key (``MYTHOS_API_KEYS=key1,key2``) plus
optional JWT validation when ``MYTHOS_JWT_PUBKEY`` is set.
"""
from __future__ import annotations
import os
from typing import Any
try: # pragma: no cover
from fastapi import Header, HTTPException, status
except Exception: # noqa: BLE001
Header = HTTPException = status = None # type: ignore
try: # pragma: no cover
import jwt # type: ignore
_JWT = True
except Exception: # noqa: BLE001
_JWT = False
def _allowed_keys() -> set[str]:
return {k.strip() for k in os.getenv("MYTHOS_API_KEYS", "").split(",") if k.strip()}
def require_api_key(authorization: str | None = Header(default=None)) -> dict[str, Any]:
if HTTPException is None: # FastAPI not installed — let the caller handle it.
return {"sub": "anonymous"}
if not authorization or not authorization.lower().startswith("bearer "):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="missing bearer")
token = authorization.split(None, 1)[1].strip()
keys = _allowed_keys()
if keys and token in keys:
return {"sub": "api-key", "token": token[:8] + "..."}
if _JWT and (pubkey := os.getenv("MYTHOS_JWT_PUBKEY")):
try:
return jwt.decode(token, pubkey, algorithms=["RS256"])
except Exception as exc: # noqa: BLE001
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"jwt: {exc}") from exc
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token")