Skip to content

fix(serve): --ui auth survives fastapi 0.137 (router match, fail closed); lift cap#444

Draft
soustruh wants to merge 2 commits into
fix/typer-vendored-clickfrom
fix/serve-ui-auth-fastapi-0137
Draft

fix(serve): --ui auth survives fastapi 0.137 (router match, fail closed); lift cap#444
soustruh wants to merge 2 commits into
fix/typer-vendored-clickfrom
fix/serve-ui-auth-fastapi-0137

Conversation

@soustruh

Copy link
Copy Markdown

Why

Follow-up to #443, which capped fastapi<0.137 because 0.137 reopened
GHSA-ffpq-prmh-3gx2. The serve --ui auth predicate scanned app.routes as a flat
list; fastapi 0.137 (fastapi/fastapi#15745)
made include_router nest routers into a lazy tree (_IncludedRouter) instead of
flattening them, so the flat scan missed nested endpoints and served /doctor,
/version, /changelog, /agents unauthenticated. fastapi documents this as
intentional (their release notes warn that code iterating app.routes as a flat list
is affected) -- so the fix is on our side.

What changed

  • server/app.py: the --ui auth predicate asks the router's match protocol whether a
    GET resolves to a real endpoint (skipping the SPA StaticFiles catch-all), instead of
    scanning app.routes. matches() is the same resolution a real request uses, so it
    can't miss a live endpoint however fastapi structures routes. Also fails closed.
  • pyproject.toml: lift the fastapi<0.137 cap (latest, 0.137.2, in the lock).
  • Version 0.63.5.

Verification

test_serve_ui.py (incl. the 7 GHSA regression tests) green on fastapi 0.137.2; full
suite (minus live-cred e2e) green on 0.137; ruff + ty clean.

Stacking

Based on fix/typer-vendored-click (#443), not main. After #443 squash-merges:
git rebase --onto main fix/typer-vendored-click <this-branch> and switch base to main
(expect one intentional conflict on the fastapi pin / lock — the cap-lift itself).

soustruh added 2 commits June 19, 2026 01:06
The --ui auth predicate scanned app.routes as a flat list to decide which
paths need auth. fastapi 0.137 nests included routers into a lazy tree
(_IncludedRouter) instead of flattening, so the flat scan missed nested
endpoints and served /doctor, /version, /changelog, /agents unauthenticated
(GHSA-ffpq-prmh-3gx2). Ask the router's match protocol whether a GET resolves
to a real endpoint instead -- the same resolution a real request uses, so it
cannot miss a live endpoint. Fails closed: any error -> path treated as
protected, never silently public.
…p 0.63.5

GHSA-ffpq-prmh-3gx2 was the reason for the temporary cap in 0.63.4; the
router-match predicate fix lets fastapi go back to the latest release (0.137.2).
@soustruh soustruh force-pushed the fix/serve-ui-auth-fastapi-0137 branch from f29da23 to 3f5b957 Compare June 18, 2026 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant