fix: register CORSMiddleware outermost so OPTIONS preflight bypasses auth gate (#59052) - #59111
Closed
wesleysimplicio wants to merge 3 commits into
Closed
Conversation
Remove 11 stale # noqa comments (E731 on fallback lambdas, F401 on re-exported imports) and 5 stale # type: ignore[import-not-found] comments (SUPERVISOR_REGISTRY imports). The SUPERVISOR_REGISTRY symbol is defined in tools/browser_supervisor.py and listed in __all__; other modules (browser_dialog_tool.py) already import it without suppression. Stale suppressions detected via: ruff check --select RUF100 --fix
Issue NousResearch#59026 - the langfuse SDK can be removed from the active environment, causing tracing to silently stop with no operator warning. Changes: - Add logger.warning() in _get_langfuse() when the SDK import fails - Add a prominent warning section to README.md about the dependency - Add requirements.txt for the langfuse>=2.36,<3.0 dependency
…auth gate (NousResearch#59052) Bug: OPTIONS preflight requests to /api/* return 401 because CORSMiddleware was registered first (line 289) via app.add_middleware, making it the innermost middleware in the Starlette stack. Auth middlewares registered later (auth_middleware, _dashboard_auth_gate, _token_auth_seam via @app.middleware) wrapped around it, running first on incoming requests. An OPTIONS preflight has no session token header, so auth_middleware rejects it before CORSMiddleware ever sees it. Fix: Move app.add_middleware(CORSMiddleware, ...) to after all @app.middleware decorators (after token_auth_seam). In Starlette 1.0.1, add_middleware inserts at index 0 of user_middleware, and build_middleware_stack reverses the list — so the last-registered middleware is outermost (runs first). CORS is now outermost after ServerErrorMiddleware, handling OPTIONS preflight before auth runs. Fixes NousResearch#59052
Collaborator
Duplicate of #59072 — same CORS-middleware-reordering fix in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #59052.
OPTIONS preflight requests to
/api/*return 401 because CORSMiddleware was registeredfirst(viaapp.add_middlewareat line 289), making it theinnermostmiddleware in the Starlette stack. Auth middlewares registered later (auth_middleware,_dashboard_auth_gate,_token_auth_seamvia@app.middleware) wrappedaroundit, running first on incoming requests. An OPTIONS preflight carries no session token header, soauth_middlewarerejects it with 401 before CORSMiddleware ever sees it.Root Cause
In Starlette 1.0.1,
add_middlewareinserts at index 0 ofuser_middleware, andbuild_middleware_stackiterates in reverse — so thelast-registeredmiddleware is outermost (runs first on incoming requests).Current order (before fix):
_token_auth_seam(outermost — registered last via@app.middleware)auth_middleware_dashboard_auth_gate_plugin_api_runtime_gatehost_header_middlewareCORSMiddleware(innermost — registered first viaapp.add_middleware)An OPTIONS preflight to
/api/some-endpointhitsauth_middlewareat step 2, which calls_has_valid_session_token()— the preflight has noX-Hermes-Session-Tokenheader → 401 before CORS ever runs.Fix
Moved
app.add_middleware(CORSMiddleware, ...)to after all@app.middlewaredecorators (after_token_auth_seam). CORSMiddleware is now registered last → outermost:_token_auth_seamauth_middleware_dashboard_auth_gate_plugin_api_runtime_gatehost_header_middlewareCORSMiddleware.preflight_response()returns a 200 with CORS headers for OPTIONS requests and doesNOTcallcall_next— so the request never reaches any auth middleware.Testing
add_middlewareinserts at position 0;build_middleware_stackreverses)curl -X OPTIONS -H 'Origin: http://localhost:5173' http://localhost:9119/api/sessionsshould return 200 with CORS headers, not 401