fix(security): require API_SERVER_KEY before dispatching API server work

This commit is contained in:
Dusk1e 2026-05-25 18:19:00 +03:00 committed by Teknium
parent 442a9203c0
commit 1a9ef83147
5 changed files with 24 additions and 30 deletions

View file

@ -24,7 +24,8 @@ Exposes an HTTP server with endpoints:
Any OpenAI-compatible frontend (Open WebUI, LobeChat, LibreChat,
AnythingLLM, NextChat, ChatBox, etc.) can connect to hermes-agent
through this adapter by pointing at http://localhost:8642/v1.
through this adapter by pointing at http://localhost:8642/v1 and
authenticating with API_SERVER_KEY.
Requires:
- aiohttp (already available in the gateway)
@ -844,11 +845,11 @@ class APIServerAdapter(BasePlatformAdapter):
Validate Bearer token from Authorization header.
Returns None if auth is OK, or a 401 web.Response on failure.
If no API key is configured, all requests are allowed (only when API
server is local).
connect() refuses to start the API server without API_SERVER_KEY, so
the no-key branch only exists for tests or unsupported manual wiring.
"""
if not self._api_key:
return None # No key configured — allow all (local-only use)
return None
auth_header = request.headers.get("Authorization", "")
if auth_header.startswith("Bearer "):
@ -4099,11 +4100,13 @@ class APIServerAdapter(BasePlatformAdapter):
if hasattr(sweep_task, "add_done_callback"):
sweep_task.add_done_callback(self._background_tasks.discard)
# Refuse to start network-accessible without authentication
if is_network_accessible(self._host) and not self._api_key:
# Refuse to start without authentication. The API server can
# dispatch terminal-capable agent work, so every deployment needs
# an explicit API_SERVER_KEY regardless of bind address.
if not self._api_key:
logger.error(
"[%s] Refusing to start: binding to %s requires API_SERVER_KEY. "
"Set API_SERVER_KEY or use the default 127.0.0.1.",
"[%s] Refusing to start: API_SERVER_KEY is required for the API server, "
"including loopback-only binds on %s.",
self.name, self._host,
)
return False
@ -4141,14 +4144,6 @@ class APIServerAdapter(BasePlatformAdapter):
await self._site.start()
self._mark_connected()
if not self._api_key:
logger.warning(
"[%s] ⚠️ No API key configured (API_SERVER_KEY / platforms.api_server.key). "
"All requests will be accepted without authentication. "
"Set an API key for production deployments to prevent "
"unauthorized access to sessions, responses, and cron jobs.",
self.name,
)
logger.info(
"[%s] API server listening on http://%s:%d (model: %s)",
self.name, self._host, self._port, self._model_name,