mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
fix(agent_session_endpoints): require LITELLM_AGENT_JWT_SECRET, no master-key fallback
The daemon JWT secret must be a SEPARATE credential from the proxy master key. The previous fallback to LITELLM_MASTER_KEY conflated two distinct auth surfaces — a captured daemon JWT could be used to mint regular API keys with master-key authority. Replace _get_signing_secret with a strict check that raises AgentJWTSecretNotConfiguredError if the dedicated env var is unset. Add is_agent_jwt_secret_configured() so proxy_server.py can refuse to mount the routers when the secret is missing. Greptile P1 SECURITY (review #PRR_kwDOKALCgc78uM7F).
This commit is contained in:
parent
f6e5951556
commit
5037026d75
1 changed files with 29 additions and 8 deletions
|
|
@ -26,20 +26,41 @@ class AgentDaemonTokenError(Exception):
|
|||
"""Raised when a daemon token is invalid (used internally by validators)."""
|
||||
|
||||
|
||||
class AgentJWTSecretNotConfiguredError(RuntimeError):
|
||||
"""Raised when ``LITELLM_AGENT_JWT_SECRET`` is unset.
|
||||
|
||||
The daemon JWT secret MUST be a separate credential from the proxy
|
||||
master key. Falling back to ``LITELLM_MASTER_KEY`` would conflate two
|
||||
distinct auth surfaces — a captured daemon JWT could then be used to
|
||||
mint regular API keys with master-key authority.
|
||||
"""
|
||||
|
||||
|
||||
def is_agent_jwt_secret_configured() -> bool:
|
||||
"""Return True iff a non-empty ``LITELLM_AGENT_JWT_SECRET`` is present.
|
||||
|
||||
Used at startup by ``proxy_server.py`` to decide whether to mount the
|
||||
agent_session_endpoints routers. Mounting the routers when this is
|
||||
False would silently expose an unsigned auth surface — refuse instead.
|
||||
"""
|
||||
return bool(os.environ.get(AGENT_JWT_SECRET_ENV))
|
||||
|
||||
|
||||
def _get_signing_secret() -> str:
|
||||
"""Resolve the JWT signing secret.
|
||||
|
||||
Falls back to ``LITELLM_MASTER_KEY`` for local dev so a fresh proxy
|
||||
boot doesn't blow up; production deploys MUST set
|
||||
``LITELLM_AGENT_JWT_SECRET``.
|
||||
The daemon JWT secret is a SEPARATE credential from the proxy master
|
||||
key. There is no fallback — if ``LITELLM_AGENT_JWT_SECRET`` is unset,
|
||||
we refuse to mint or validate any token. Mounting the agent_session
|
||||
routers without this env var is itself a startup error (see
|
||||
``proxy_server.py``).
|
||||
"""
|
||||
secret = os.environ.get(AGENT_JWT_SECRET_ENV)
|
||||
if not secret:
|
||||
secret = os.environ.get("LITELLM_MASTER_KEY")
|
||||
if not secret:
|
||||
raise RuntimeError(
|
||||
f"Neither {AGENT_JWT_SECRET_ENV} nor LITELLM_MASTER_KEY is set; "
|
||||
"cannot mint or validate daemon JWTs."
|
||||
raise AgentJWTSecretNotConfiguredError(
|
||||
f"{AGENT_JWT_SECRET_ENV} is not set; cannot mint or validate "
|
||||
"daemon JWTs. This env var must be a dedicated random secret, "
|
||||
"distinct from LITELLM_MASTER_KEY."
|
||||
)
|
||||
return secret
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue