Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1401,15 +1401,16 @@ async def initialize_services():
await TelemetryClient.send_event(
Category.SERVICE_INITIALIZATION, MessageId.ORB_SVC_INIT_START
)
# Generate JWT keys if they don't exist and a JWT signing key isn't specified
if not os.getenv("JWT_SIGNING_KEY"):
generate_jwt_keys()

from config.settings import IBM_AUTH_ENABLED

if IBM_AUTH_ENABLED:
logger.info("IBM auth mode enabled — JWT validation delegated to Traefik")

# Generate JWT keys if they don't exist, a JWT signing key isn't specified,
# and IBM auth is not enabled (IBM mode delegates all auth to Traefik)
if not os.getenv("JWT_SIGNING_KEY") and not IBM_AUTH_ENABLED:
generate_jwt_keys()

# Initialize clients (now async to generate Langflow API key)
try:
await clients.initialize()
Expand Down
27 changes: 22 additions & 5 deletions src/session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import os
from utils.logging_config import get_logger
from config.settings import IBM_AUTH_ENABLED

logger = get_logger(__name__)
@dataclass
Expand Down Expand Up @@ -106,9 +107,16 @@ def _configure_jwt_signing(self):
self.public_key_pem = None # No JWKS for symmetric
self.algorithm = "HS256"
else:
# Fall back to file-based RSA keys
self._load_rsa_keys()
self.algorithm = "RS256"
if IBM_AUTH_ENABLED:
# IBM Auth Mode: Traefik handles auth (no local JWT signing required)
self.private_key = None
self.public_key = None
self.public_key_pem = None
self.algorithm = None
else:
# Fall back to file-based RSA keys
self._load_rsa_keys()
self.algorithm = "RS256"
logger.info(f"Initialized JWT signing with {self.algorithm}")


Expand Down Expand Up @@ -215,11 +223,17 @@ def create_jwt_token(self, user: User) -> str:
if token and (token.startswith("Bearer ") or token.startswith("Basic ")):
return token
if not token:
if self.private_key is None:
logger.error("create_jwt_token called but JWT signing is disabled (IBM auth mode)")
return None
token = jwt.encode(token_payload, self.private_key, algorithm=self.algorithm)
return f"Bearer {token}"

def verify_token(self, token: str) -> Optional[Dict[str, Any]]:
"""Verify JWT token and return user info"""
if IBM_AUTH_ENABLED:
# IBM Auth Mode: Token verification handled externally by Traefik
return None
try:
raw = token.removeprefix("Bearer ")
payload = jwt.decode(
Expand Down Expand Up @@ -258,7 +272,7 @@ def get_user_opensearch_client(self, user_or_id: Union[User, str], jwt_token: st
# Get the effective JWT token (handles anonymous JWT creation)
jwt_token = self.get_effective_jwt_token(user_id, jwt_token)

from config.settings import IBM_AUTH_ENABLED, clients
from config.settings import clients

# In IBM mode credentials may rotate per-request — always create a fresh client
if IBM_AUTH_ENABLED:
Expand All @@ -274,7 +288,7 @@ def get_user_opensearch_client(self, user_or_id: Union[User, str], jwt_token: st

def get_effective_jwt_token(self, user_id: str, jwt_token: str) -> str:
"""Get the effective JWT token, creating anonymous JWT if needed in no-auth mode"""
from config.settings import IBM_AUTH_ENABLED, is_no_auth_mode
from config.settings import is_no_auth_mode

# IBM JWT is used as-is — never override with an anonymous OpenRAG JWT
if IBM_AUTH_ENABLED and jwt_token:
Expand All @@ -285,6 +299,9 @@ def get_effective_jwt_token(self, user_id: str, jwt_token: str) -> str:

# No token — create one
if is_no_auth_mode() or user_id in (None, AnonymousUser().user_id):
# IBM Auth Mode: No anonymous JWT concept (disable signing)
if self.private_key is None:
return None
# anonymous JWT (cached)
if not hasattr(self, "_anonymous_jwt"):
self._anonymous_jwt = self._create_anonymous_jwt()
Expand Down
Loading