feat(oauth): autodetekcja #21 + self-healing proxy discovery (Authorize bez fixu nginksa) - #16
Merged
Merged
Conversation
Design: bpp-mcp w trybie --http probuje instancje przy starcie i wybiera PASS-THROUGH (issuer->BPP, gdy #21 wdrozony) albo PROXY (bpp-mcp serwuje wlasne metadane RFC 8414 z issuer=self, endpointy->BPP/o/*, gdy 403). Umozliwia dzialajacy przycisk Authorize podczas stopniowego rolloutu #21. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
5 taskow TDD + spike empiryczny jako bramka. Self-review zlapal rozjazd trailing-slash miedzy PRM a dokumentem AS (RFC 8414 §3.3) — issuer normalizowany przez AnyHttpUrl w obu miejscach. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
probe_instance wykrywa czy instancja wystawia .well-known (PASSTHROUGH) czy nie (PROXY, default przy niepewnosci). authorization_server_metadata buduje dokument RFC 8414 z issuer=self (norm. AnyHttpUrl) i endpointami BPP/o/*. _konwencjonalne rozszerzone o revoke_token. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
W trybie --http bpp-mcp probuje instancje przy starcie: PASSTHROUGH gdy .well-known wystawia poprawne metadane (#21 wdrozony), inaczej PROXY — dokladamy custom_route serwujaca metadane AS z issuer=self, endpointy BPP/o/*. Live smoke: proxy wybrany przeciw niezmienionej instancji, issuer w PRM i dokumencie AS zgodne bajt w bajt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
…BLE)
- CORS: dokument AS w trybie PROXY dostaje Access-Control-Allow-Origin: *
(jak PRM od SDK) — bez tego zdalny klient przegladarkowy padal na kroku 2
discovery. Potwierdzone na zywo + test.
- issuer: udokumentowane ograniczenie do golego originu (bez sciezki) —
klient MCP buduje URL discovery inaczej dla issuera ze sciezka; test
przemianowany, by nie sugerowal wsparcia ktorego nie ma.
- effective_issuer_url: rstrip('/') przed removesuffix (trailing slash).
- docstring probe: doprecyzowany (dokladnie 200, nie dowolne 2xx).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL
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.
Cel
Sprawić, by natywny przycisk „Authorize" w kliencie MCP (Claude Code i pokrewne) działał w trybie
--httptakże na instancjach BPP, które nie mają jeszcze wdrożonego fixu nginksa przepuszczającego/.well-known/(bpp-deploy #21). Umożliwia to stopniowy rollout tego fixu bez psucia logowania po drodze.Problem
W trybie HTTP klient robi discovery:
401→ PRM →authorization_servers→GET BPP/.well-known/oauth-authorization-server. Na instancji bez #21 nginx oddaje 403 (regułalocation ~ /\.na pliki ukryte przechwytuje żądanie przed aplikacją), więc „Authorize" pada — mimo że serwer autoryzacji BPP (/o/authorize|token|register) działa w pełni.Rozwiązanie: autodetekcja przy starcie + self-healing proxy
W trybie
--httpbpp-mcprobi jeden probe przy starcie i wybiera tryb na całe życie procesu:issuer→ BPP, zachowanie jak dotąd — klient idzie po metadane wprost do BPP.bpp-mcpsam wystawia/.well-known/oauth-authorization-serverzissuer= własny adres i endpointami →BPP/o/*. „Authorize" działa bez #21.Po wdrożeniu #21 na daną instancję wystarczy restart jej
bpp-mcp— przeskoczy na pass-through.Zgodność ze specem
PROXY nie jest naginaniem RFC 8414: §3.3 wymaga tylko, by
issuer= adres pobrania metadanych (tu: URLbpp-mcp), a endpointy mogą być cross-origin.issuernormalizowany przezAnyHttpUrl— bajt w bajt zgodny z tym, co PRM wystawia zAuthSettings(inaczej trailing-slash by je rozjechał). Token BPP jest opaque (brak claimuiss) — nic do walidacji po stronie tokenu.Weryfikacja
test_probe.py(6),test_metadata_proxy.py(3), integracyjne PROXY/PASS-THROUGH + CORS wtest_http_auth.py(4), config (2).publikacje.up.lublin.pl(403 na discovery): trybproxywybrany poprawnie; dokument ASissuer=http://127.0.0.1:8766/, endpointy.../o/*; PRMauthorization_servers=['http://127.0.0.1:8766/']— zgodne bajt w bajt z dokumentem AS.Review (FABLE) — naniesione
Gałąź przeszła adwersaryjny review subagentem na modelu FABLE (empirycznie zweryfikowany). Znaleziska naniesione w tym PR:
Access-Control-Allow-Origin: *(jak PRM od SDK) — bez tego zdalny klient przeglądarkowy padał na kroku 2 discovery. Potwierdzone na żywo + test.BPP_MCP_ISSUER_URLmusi być gołym originem (klient MCP inaczej buduje URL discovery); jawnie udokumentowane, test przemianowany.removesuffixprzy trailing slash (drobne) i docstring probe (nit): poprawione.Rdzeń (autodetekcja + PROXY dla issuera host:port) FABLE potwierdził jako poprawny, przetestowany i bez regresji — brak blockerów.
Zweryfikowano syntetycznie cały łańcuch protokołu opróc ostatniego kroku: faktyczne kliknięcie „Authorize" w realnym kliencie MCP + logowanie w przeglądarce. To wymaga człowieka i danych do BPP — nie dało się tego wyklikać automatycznie. Analiza speca i live-smoke wskazują na sukces, ale przed mergem warto ten jeden klik wykonać przeciw instancji bez #21 (spike opisany w planie, Task 0).
Dokumenty projektowe
docs/superpowers/specs/2026-07-24-oauth-autodetekcja-proxy-design.mddocs/superpowers/plans/2026-07-24-oauth-autodetekcja-proxy.mdPoza zakresem
Detekcja na żywo/periodyczna (świadomie: stan instancji zmienia się raz, przy deployu), introspekcja tokenu, zmiany w BPP/bpp-deploy.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Wpux2rimQuavKWiaqakxYL