mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-10 17:02:20 +02:00
security: fail closed on bearer endpoint credentials
This commit is contained in:
@@ -683,7 +683,7 @@ def _validate_bearer_session_model(sess, owner: str | None = None) -> Optional[s
|
||||
Direct API-key sessions intentionally have no ``ModelEndpoint`` row and
|
||||
retain their documented compatibility behavior. Registered endpoint
|
||||
sessions, including provider-auth-backed rows, must use the visible
|
||||
server-owned inventory and never trigger a provider lookup here.
|
||||
server-owned inventory and never trigger a live provider lookup here.
|
||||
"""
|
||||
# Lightweight in-memory test doubles from older route tests do not carry
|
||||
# durable provenance fields. They cannot represent a persisted bearer
|
||||
@@ -737,9 +737,9 @@ def _validate_bearer_session_model(sess, owner: str | None = None) -> Optional[s
|
||||
validated = _validate_bearer_model_selection(ep, requested)
|
||||
|
||||
# A session may outlive an endpoint-key rotation. For bearer calls,
|
||||
# use the current static key for this exact endpoint and never trust a
|
||||
# stale persisted Authorization header. Provider-auth rows remain
|
||||
# request-local and are intentionally empty in cache-only mode.
|
||||
# use the current exact-endpoint credentials and never trust a stale
|
||||
# persisted Authorization header. Provider-auth credentials are
|
||||
# owner-scoped, request-local, and cache-only in this boundary.
|
||||
try:
|
||||
from src.endpoint_resolver import build_headers, resolve_endpoint_runtime
|
||||
|
||||
@@ -752,6 +752,9 @@ def _validate_bearer_session_model(sess, owner: str | None = None) -> Optional[s
|
||||
except Exception as exc:
|
||||
logger.warning("Could not refresh bearer session endpoint auth: %s", exc)
|
||||
sess.headers = {}
|
||||
if getattr(ep, "provider_auth_id", None):
|
||||
raise HTTPException(401, "Registered provider credentials are unavailable") from exc
|
||||
raise HTTPException(400, "Registered endpoint credentials are unavailable") from exc
|
||||
|
||||
sess.model = validated
|
||||
return validated
|
||||
|
||||
@@ -997,6 +997,14 @@ def setup_session_routes(
|
||||
rag: str = Form(None)
|
||||
):
|
||||
require_chat_scope(request)
|
||||
# This legacy alias uses the server-owned OPENAI_API_KEY rather than a
|
||||
# caller-selected, owner-visible ModelEndpoint. A bearer must not turn
|
||||
# that credential into an owner-attributed session whose provenance
|
||||
# cannot be represented as either a registered endpoint or a direct
|
||||
# caller-supplied key. Registered bearer chat remains available through
|
||||
# POST /api/session with endpoint_id.
|
||||
if is_bearer_principal(request):
|
||||
raise HTTPException(403, "Bearer callers must choose a registered model endpoint")
|
||||
if not OPENAI_API_KEY:
|
||||
raise HTTPException(400, "Server missing OPENAI_API_KEY")
|
||||
sid = str(uuid.uuid4())
|
||||
|
||||
Reference in New Issue
Block a user