Poslední týdny jsem dělal na integraci Supabase do Keboola Connection. Vznikl z toho kompletní driver s OAuth 2.0, automatickým discovery schémat a napojením na Supabase Marketplace. A cestou jsem narazil na pár bugů, ze kterých jsem málem šedivěl.
Supabase + Keboola
Supabase je open-source alternativa k Firebase postavená nad PostgreSQL -- autentizace, real-time, storage a hlavně plnohodnotná PostgreSQL databáze. Keboola je platforma pro datové pipeline a ETL procesy nad různými datovými zdroji.
Cíl byl jednoduchý: uživatel připojí svůj Supabase projekt jako externí datový zdroj v Keboola a data se automaticky začnou stahovat do pipeline.
Z CLI na webový controller
Původně jsem chtěl CLI příkaz na registraci OAuth credentials. Jenže testovat OAuth flow z terminálu je utrpení -- kopírujete URL tam a zpátky, ručně řešíte přesměrování, žádná vizuální zpětná vazba.
Takže jsem brzo otočil: místo CLI jsem postavil webový test harness na /supabase/connect. Jednoduchý formulář, zadáte client_id a client_secret, vygeneruje redirect URL, pošle vás na Supabase a obslouží callback. Tohle rozhodnutí se ukázalo jako klíčové -- iterativní debugging, který následoval, by z terminálu prostě nešel.
Stateless OAuth hlavolam
První pořádná výzva přišla ze Symfony. Routy s #[AsPublicAction] běží na stateless firewallu -- žádná session. Jenže OAuth flow typicky potřebuje uložit PKCE verifier mezi autorizací a callbackem. Symfony vyhodilo: "Session was used while the request was declared stateless."
No a co s tím? Zakódovat všechno -- client credentials, PKCE verifier, redirect URI -- přímo do OAuth state parametru, podepsaného HMAC-SHA256 přes kernel.secret. Callback stav dekóduje, ověří podpis a vytáhne PKCE verifier. Žádná session, žádná databáze, HMAC brání manipulaci a state parametr z principu chrání proti CSRF. Elegantní.
Záludnosti OAuth API
Pak přišly dvě menší překážky:
Záhada approval_prompt. League OAuth2 knihovna přidává approval_prompt do autorizačních požadavků automaticky (konvence Google OAuth). Supabase to odmítlo: "Unrecognized key(s) in object: 'approval_prompt'." Stačilo přepsat getAuthorizationParameters() a parametr odfiltrovat.
Projektové vs. účtové OAuth aplikace. Vytvořil jsem OAuth aplikaci na úrovni projektu (/project/{ref}/auth/oauth-apps) a dostával "Unrecognized client_id." Supabase má totiž dva odlišné scopy -- projektové aplikace a integrační aplikace na úrovni účtu (/account/integrations). Pro marketplace integraci přes projekty potřebujete to druhé. Tohle v dokumentaci snadno přehlédnete.
PKCE Double-Handling Bug
Tohle byl nejtěžší bug celého projektu. Po vyřešení stateless flow a API záludností pořád selhávala výměna kódu za tokeny: "Invalid or expired OAuth authorization."
Zkoušel jsem systematicky:
- Detailní error logging -- stejná chyba
- HTTP Basic Auth pro token endpoint -- pořád nic
Accept: application/jsonheader -- pořád nic- Kompletně vlastní
exchangeCodeForTokens()obcházející knihovnu -- pořád nic
Autorizace fungovala. Callback dostal kód. Ale výměna za tokeny konzistentně vracela tu samou kryptickou chybu. Šílel jsem z toho.
Průlom: League OAuth2 knihovna má vestavěnou PKCE podporu. Můj kód PKCE taky řešil manuálně kvůli stateless flow. Dvě korektní PKCE implementace běžely současně -- knihovna poslala jeden code_verifier, můj kód jiný. Supabase vidělo nesoulad a výměnu odmítlo.
Fix? Jeden řádek:
protected $pkceMethod = null; // Vypnout vestavěné PKCE knihovny
Klasický integrační bug -- dva systémy, každý sám o sobě správný, v kombinaci nefungují. Debugging zabral hodiny, protože každý dílek zvlášť vypadal v pohodě.
Dva režimy připojení
Driver podporuje dva způsoby přístupu k datům:
Přímé PostgreSQL připojení -- klasika přes connection pooler (port 6543). Plný přístup k SQL, vhodné pro větší objemy dat.
REST API (PostgREST) -- přes Supabase REST endpoint s service_role klíčem. Jednodušší setup bez sdílení databázového hesla.
Obě varianty podporují šifrované ukládání credentials s oddělenými klíči pro hesla, API klíče a OAuth tokeny.
Automatické schema discovery
Po úspěšném OAuth propojení se na pozadí spustí SupabaseProjectSetupJob:
- Přes protobuf zavolá
ListSchemasCommandna Supabase driver - Objeví dostupná schémata
- Pro každé vytvoří externí bucket v Keboola
- Nastaví auto-refresh každých 6 hodin
Protobuf komunikace je architektonicky fajn -- příkazy se definují ve sdíleném storage-driver-common monorepu a implementují v storage-driver-postgres driveru. Čisté hranice, žádné přímé provázání.
Uživatel po připojení okamžitě vidí svá data bez jakékoli ruční konfigurace.
Supabase Management API
Součástí je klient pro Supabase Management API:
- Detaily projektu (region, konfigurace)
- API klíče (
anon,service_role) - Konfigurace connection pooleru
- Seznam projektů a organizací
Tahle data se využívají při automatickém nastavení credentials po OAuth flow.
Celý user flow
Jak to vypadá end-to-end:
- Uživatel klikne "Připojit Supabase" a autorizuje přes OAuth
- Callback uloží tokeny, přesměruje na setup stránku
- Uživatel vybere svůj Supabase projekt, volitelně zadá PostgreSQL DSN
- Keboola vytvoří organizaci a projekt se Supabase backendem
- Background job objeví tabulky, zaregistruje buckety, nastaví auto-refresh
- Uživatel přistane na dashboardu s daty, která už tečou
Rozsah
Celý driver vznikl za týden v asi 60 hodinách intenzivní práce s Claude Code. Výsledek je kolem 25 000 změn -- třídy, controllery, migrace, testy, CLI příkazy, dokumentace. Od nuly ke kompletní integraci.
Vývoj probíhal vysoce iterativně: definovat co je potřeba, implementovat, hned otestovat v prohlížeči, debugovat z reálných chybovek. Rychlé feedback smyčky umožnily vyřešit i PKCE double-handling v řádu hodin místo dnů.
AI agent výrazně zrychlil opakující se vzory (controllery, DTO, testy), generování boilerplate a navigaci v rozsáhlém Keboola codebase. Klíčová architektonická rozhodnutí a bezpečnostní model ale samozřejmě vyžadovaly lidský úsudek.
Co jsem se naučil
- Stateless OAuth jde udělat -- zakódovat vše do HMAC-podepsaného state parametru, žádná session
- Knihovny si hlídej -- PKCE double-handling mě naučil vždy zkontrolovat, co knihovna dělá automaticky za mě
- OAuth API se liší provider od providera --
approval_prompt, auth metody, scopy aplikací, nic není standard - PKCE je nutnost pro flow, kde nelze plně zabezpečit client secret
- Webový test harness poráží CLI testování OAuth flow o řád
- AI agenti mění rychlost vývoje -- 25 000 změn za týden by bez nich nešlo
Integrace je momentálně v pull requestu a prochází code review. Těším se, až to poběží v produkci.