Przy pierwszej integracji z GitHubem spędzisz godzinę, próbując ustalić, czy chcesz GitHub App czy OAuth App. Dokumentacja traktuje je jak równoważne opcje. Nie są. Sama historia webhooków zwykle wystarcza, by podjąć decyzję za ciebie.
Bardzo krótkie podsumowanie
- GitHub App: instalowana na kontach lub repozytoriach, ma drobnoziarniste uprawnienia, odbiera webhooki dla zasobów, na których jest zainstalowana, uwierzytelnia się jako ona sama krótkotrwałymi tokenami.
- OAuth App: użytkownicy ją autoryzują, działa w ich imieniu z ich uprawnieniami, odbiera webhooki tylko jeśli sama je skonfiguruje jak każde narzędzie zewnętrzne, uwierzytelnia się jako użytkownik długotrwałymi tokenami.
Jeśli budujesz coś, co działa bez aktywnego użytkownika — bota CI, automatyzację code review, cokolwiek harmonogramowego — chcesz GitHub App. Jeśli budujesz narzędzie wykonujące akcje w imieniu zalogowanego użytkownika (np. UI do wyszukiwania kodu), właściwym kształtem jest OAuth App.
Jak odbierają webhooki
GitHub Apps
Konfigurujesz jeden URL webhooka przy tworzeniu aplikacji. Gdy użytkownik instaluje aplikację na koncie lub repozytorium, GitHub zaczyna wysyłać zdarzenia tego zasięgu na twój URL. Zdarzenia obejmują installation (cykl życia instalacji/odinstalowania), installation_repositories (dodane lub usunięte repo) oraz typy zdarzeń, które subskrybowała twoja aplikacja (push, pull_request itd.).
Każde zdarzenie zawiera nagłówek X-GitHub-Hook-Installation-Target-Type („integration") i installation ID, którym możesz wybić token dla tej konkretnej instalacji. Podpis to HMAC SHA-256 w X-Hub-Signature-256 — ten sam kształt co webhooki repozytorium.
OAuth Apps
OAuth Apps nie mają wbudowanej subskrypcji webhooków. By odbierać webhooki, autoryzowani użytkownicy aplikacji muszą utworzyć webhooki repozytorium lub organizacji wskazujące na URL aplikacji. Oznacza to, że zasięg webhooków aplikacji jest związany z tym, gdzie jej użytkownicy ustawili subskrypcje, a nie z tym, gdzie sama aplikacja jest „zainstalowana".
Niektóre zespoły budują OAuth Apps automatycznie tworzące webhooki przez API GitHuba po autoryzacji. To działa, ale teraz zarządzasz cyklem życia webhooka per użytkownik obok własnej logiki aplikacji.
Uwierzytelnianie to prawdziwa rozbieżność
GitHub Apps uwierzytelniają się żądaniami podpisanymi JWT, by wybijać krótkotrwałe tokeny instalacji (1 godzina) dla każdej instalacji. JWT podpisywany jest kluczem prywatnym generowanym przy tworzeniu aplikacji. Twój kod:
// 1. Podpisz JWT kluczem prywatnym aplikacji (wygasa po 10 min)
const jwt = createAppJwt(APP_ID, PRIVATE_KEY);
// 2. Wymień JWT na token instalacji (ważny 1 godzinę)
const token = await fetchInstallationToken(jwt, INSTALLATION_ID);
// 3. Wykonuj wywołania API tym tokenem
const res = await fetch('https://api.github.com/repos/x/y/issues', {
headers: { Authorization: `token ${token}` },
});
Tokeny instalacji są ograniczone do instalacji i wygasają automatycznie — więc wyciek ma ograniczony zasięg rażenia.
OAuth Apps uwierzytelniają się tokenami dostępu użytkownika z standardowego flow OAuth. Te tokeny są domyślnie długotrwałe i działają jako użytkownik — wyciek jednego oznacza, że atakujący może wszystko, co mógłby ten użytkownik. Dokumentacja GitHuba popycha ku GitHub Apps dla nowych integracji m.in. z tego powodu.
Uprawnienia: ograniczone vs szerokie
GitHub Apps pozwalają prosić o granularne uprawnienia: czytaj issues, zapisuj checks, czytaj pull requests, bez dostępu do reszty. Każde uprawnienie jest niezależne. Użytkownik widzi dokładną listę i może odmówić.
OAuth Apps używają starszego systemu opartego na scope: repo, read:user itd. Scope są grubsze. Scope repo daje dostęp do odczytu i zapisu wszystkich repozytoriów widocznych dla użytkownika — nie ma wersji „tylko odczyt na konkretnych repo".
Dla bota code review, który tylko czyta kod i zapisuje check runs, GitHub App z dwoma konkretnymi uprawnieniami jest znacznie mniej inwazyjna niż OAuth App prosząca o pełny dostęp repo.
Testowanie lokalne obu
Mechanika podpisu webhooka jest identyczna — konfigurację zobacz w lokalnym testowaniu webhooków GitHub. Różnica jest w tym, jak rejestrujesz URL.
- GitHub App: ustaw URL webhooka na stronie ustawień aplikacji. Zainstaluj aplikację na repozytorium testowym. Wyzwól zdarzenia. Gotowe.
- OAuth App: sama aplikacja nie ma webhooków. Dodaj webhook repozytorium (ręcznie na stronie ustawień repo albo programowo przez API) wskazujący na twój URL tunelu.
Dla OAuth Apps musisz też przetestować sam flow callbacku OAuth — zobacz jak testować callbacki OAuth lokalnie.
Migracja między nimi jest bolesna
Jeśli zaczniesz od OAuth App i później zorientujesz się, że potrzebujesz GitHub App, nie możesz migrować. Użytkownicy muszą ponownie autoryzować nową aplikację, ty musisz ponownie wydać zapisane tokeny, a wszystkie webhooki repozytorium ustawione przez OAuth App będą działać, dopóki ich nie usuniesz. Poświęć dziesięć minut na początku na wybór właściwego typu.
Kiedy co wybrać
Wybierz GitHub App, gdy:
- Twoja integracja działa według własnego harmonogramu lub w reakcji na zdarzenia, bez zalogowanego użytkownika.
- Chcesz ograniczone uprawnienia na konkretnych repozytoriach lub organizacjach.
- Chcesz webhooki związane z zasięgiem instalacji, nie konfigurowane per repo.
- Budujesz coś, co ostatecznie trafi na GitHub Marketplace.
Wybierz OAuth App, gdy:
- Twoje narzędzie to UI, do którego użytkownicy się logują i działają we własnym koncie GitHub.
- Musisz działać dokładnie jak użytkownik, łącznie z jego wzorcami dostępu.
- Nie potrzebujesz webhooków albo ustawisz je ręcznie per repo.
Po szczegóły weryfikacji podpisu zobacz przewodnik po weryfikacji podpisów. Dołącz do listy oczekujących PortPreview po tunel radzący sobie z timingiem webhooków GitHuba i przechwytywaniem do ponawiania.