chore(diagnostics): switch bearer token logging to file-based diag log
Replace stdlib logger calls for inbound bearer token capture and forward decisions with a `_diag_write` helper that appends to `/tmp/pallas-bearer.log`. This ensures diagnostic output is reliably captured regardless of logger configuration, while swallowing any write errors to avoid impacting request handling.
This commit is contained in:
@@ -29,39 +29,45 @@ _AUTH_HEADER_KEYS = {"authorization", "x-hf-authorization"}
|
|||||||
_original_prepare = _mcm._prepare_headers_and_auth
|
_original_prepare = _mcm._prepare_headers_and_auth
|
||||||
|
|
||||||
|
|
||||||
|
def _diag_write(line: str) -> None:
|
||||||
|
"""Append a diagnostic line to /tmp/pallas-bearer.log, never raises."""
|
||||||
|
try:
|
||||||
|
from datetime import datetime
|
||||||
|
with open("/tmp/pallas-bearer.log", "a") as f:
|
||||||
|
f.write(f"{datetime.now().isoformat()} {line}\n")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _prepare_headers_and_auth_with_forward(server_config, **kwargs):
|
def _prepare_headers_and_auth_with_forward(server_config, **kwargs):
|
||||||
headers, oauth_auth, user_auth_keys = _original_prepare(server_config, **kwargs)
|
headers, oauth_auth, user_auth_keys = _original_prepare(server_config, **kwargs)
|
||||||
|
|
||||||
server_name = getattr(server_config, "name", None)
|
server_name = getattr(server_config, "name", None)
|
||||||
forward_flag = getattr(server_config, "forward_inbound_auth", False)
|
forward_flag = getattr(server_config, "forward_inbound_auth", False)
|
||||||
|
|
||||||
logger.info(
|
_diag_write(f"FORWARD check server={server_name} flag={forward_flag}")
|
||||||
"forward_check server=%s forward_flag=%s",
|
|
||||||
server_name, forward_flag,
|
|
||||||
)
|
|
||||||
|
|
||||||
if not forward_flag:
|
if not forward_flag:
|
||||||
return headers, oauth_auth, user_auth_keys
|
return headers, oauth_auth, user_auth_keys
|
||||||
|
|
||||||
if user_auth_keys:
|
if user_auth_keys:
|
||||||
logger.info("forward_skipped_user_auth server=%s", server_name)
|
_diag_write(f"FORWARD skipped_user_auth server={server_name}")
|
||||||
return headers, oauth_auth, user_auth_keys
|
return headers, oauth_auth, user_auth_keys
|
||||||
|
|
||||||
if oauth_auth is not None:
|
if oauth_auth is not None:
|
||||||
logger.info("forward_skipped_oauth server=%s", server_name)
|
_diag_write(f"FORWARD skipped_oauth server={server_name}")
|
||||||
return headers, oauth_auth, user_auth_keys
|
return headers, oauth_auth, user_auth_keys
|
||||||
|
|
||||||
inbound = request_bearer_token.get()
|
inbound = request_bearer_token.get()
|
||||||
if not inbound:
|
if not inbound:
|
||||||
logger.info("forward_no_inbound server=%s", server_name)
|
_diag_write(f"FORWARD no_inbound server={server_name}")
|
||||||
return headers, oauth_auth, user_auth_keys
|
return headers, oauth_auth, user_auth_keys
|
||||||
|
|
||||||
headers = dict(headers)
|
headers = dict(headers)
|
||||||
headers["Authorization"] = f"Bearer {inbound}"
|
headers["Authorization"] = f"Bearer {inbound}"
|
||||||
user_auth_keys = set(user_auth_keys) | {"Authorization"}
|
user_auth_keys = set(user_auth_keys) | {"Authorization"}
|
||||||
logger.info(
|
_diag_write(
|
||||||
"forward_inbound_auth server=%s token_len=%d prefix=%s",
|
f"FORWARD applied server={server_name} token_len={len(inbound)} prefix={inbound[:8]}"
|
||||||
server_name, len(inbound), inbound[:8],
|
|
||||||
)
|
)
|
||||||
return headers, oauth_auth, user_auth_keys
|
return headers, oauth_auth, user_auth_keys
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,16 @@ from starlette.responses import JSONResponse, Response
|
|||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _diag_write(line: str) -> None:
|
||||||
|
"""Append a diagnostic line to /tmp/pallas-bearer.log, never raises."""
|
||||||
|
try:
|
||||||
|
from datetime import datetime
|
||||||
|
with open("/tmp/pallas-bearer.log", "a") as f:
|
||||||
|
f.write(f"{datetime.now().isoformat()} {line}\n")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _get_request_bearer_token() -> str | None:
|
def _get_request_bearer_token() -> str | None:
|
||||||
"""Return the raw bearer token from the current MCP request's Authorization header.
|
"""Return the raw bearer token from the current MCP request's Authorization header.
|
||||||
|
|
||||||
@@ -46,8 +56,6 @@ def _get_request_bearer_token() -> str | None:
|
|||||||
the request scope, so get_access_token() always returns None here. The token
|
the request scope, so get_access_token() always returns None here. The token
|
||||||
is an opaque string forwarded to opted-in downstream servers by _fastagent_patch.
|
is an opaque string forwarded to opted-in downstream servers by _fastagent_patch.
|
||||||
"""
|
"""
|
||||||
import logging as _stdlib_logging
|
|
||||||
_diag = _stdlib_logging.getLogger("pallas.bearer")
|
|
||||||
try:
|
try:
|
||||||
from fastmcp.server.dependencies import get_http_request
|
from fastmcp.server.dependencies import get_http_request
|
||||||
|
|
||||||
@@ -55,14 +63,13 @@ def _get_request_bearer_token() -> str | None:
|
|||||||
auth = request.headers.get("authorization", "")
|
auth = request.headers.get("authorization", "")
|
||||||
if auth.lower().startswith("bearer "):
|
if auth.lower().startswith("bearer "):
|
||||||
token = auth[7:]
|
token = auth[7:]
|
||||||
_diag.info(
|
_diag_write(
|
||||||
"pallas_inbound_bearer_captured token_len=%d prefix=%s",
|
f"BEARER captured len={len(token)} prefix={token[:8]}"
|
||||||
len(token), token[:8],
|
|
||||||
)
|
)
|
||||||
return token
|
return token
|
||||||
_diag.info("pallas_inbound_bearer_absent has_auth_header=%s", bool(auth))
|
_diag_write(f"BEARER absent has_auth={bool(auth)}")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
_diag.warning("pallas_inbound_bearer_error error=%s", exc)
|
_diag_write(f"BEARER error={exc}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user