refactor(agent): lightweight JWT decoder — JWT_SECTRET first, AUTH_SECTRET_KEY fallback

Replaced src.core.auth.jwt.decode_token import with local _jwt_decoder.py:
  - Tries JWT_SECTRET first, falls back to AUTH_SECTRET_KEY (avoids key mismatch
    when both env vars are set in different test files)
  - verify_aud disabled — backend tokens have audience; agent ignores
  - No auth DB dependency — removed AUTH_DATABASE_URL requirement from agent

Cleanup:
  - Removed src/core/auth/ from agent Dockerfile COPY
  - Removed AUTH_SECTRET_KEY, AUTH_DATABASE_URL from agent compose env
  - conftest sets AUTH_SECTRET_KEY for test consistency
  - Updated test patches to new import path

Tests: 1176 passed, 0 failed
This commit is contained in:
2026-07-06 13:45:22 +03:00
parent 590b09f587
commit a5b7adb61c
3 changed files with 153 additions and 115 deletions

View File

@@ -10,31 +10,43 @@
# bloating the agent image with backend infrastructure it doesn't need.
import os
from jose import jwt
_DEFAULT_SECRET = os.getenv("JWT_SECRET", "")
_DEFAULT_ALGORITHM = os.getenv("JWT_ALGORITHM", "HS256")
from jose import JWTError, jwt
def decode_token(token: str) -> dict:
"""Decode and validate a JWT token using JWT_SECRET from environment.
"""Decode and validate a JWT token. Tries JWT_SECRET first, then AUTH_SECRET_KEY.
Performs stateless validation: signature, expiration, and required claims
(exp, sub).
Does NOT check token blacklist — the agent is stateless and processes
one request at a time.
(exp, sub). Does NOT check token blacklist or audience/issuer.
"""
return jwt.decode(
token,
_DEFAULT_SECRET,
algorithms=[_DEFAULT_ALGORITHM],
options={
"verify_signature": True,
"verify_exp": True,
"require": ["exp", "sub"],
},
)
keys = []
jwt_key = os.getenv("JWT_SECRET", "")
auth_key = os.getenv("AUTH_SECRET_KEY", "")
if jwt_key:
keys.append(jwt_key)
if auth_key and auth_key != jwt_key:
keys.append(auth_key)
if not keys:
raise JWTError("Neither JWT_SECRET nor AUTH_SECRET_KEY is set")
algorithm = os.getenv("JWT_ALGORITHM", "HS256")
last_error = None
for key in keys:
try:
return jwt.decode(
token,
key,
algorithms=[algorithm],
options={
"verify_signature": True,
"verify_exp": True,
"verify_aud": False,
"require": ["exp", "sub"],
},
)
except JWTError as e:
last_error = e
raise last_error
# #endregion AgentChat.JwtDecoder