Все статьи
GitHubGitHub AppsOAuthwebhook design

GitHub Apps против OAuth Apps: вебхуки рядом

В первый раз, строя интеграцию с GitHub, вы потратите час, пытаясь понять, нужна вам GitHub App или OAuth App. Документация подаёт их как равнозначные варианты. Это не так. Одной истории с вебхуками чаще всего достаточно, чтобы выбор сделался сам.

Очень короткое резюме

  • GitHub App: устанавливается на аккаунты или репозитории, имеет тонко настраиваемые права, получает вебхуки по ресурсам, где установлена, аутентифицируется как она сама с короткоживущими токенами.
  • OAuth App: пользователи её авторизуют, она действует от их имени с их правами, получает вебхуки только если настроит их как любой сторонний инструмент, аутентифицируется как пользователь с долгоживущими токенами.

Если вы строите что-то, что работает без активного пользователя — CI-бот, автоматизацию код-ревью, что-то по расписанию, — вам нужна GitHub App. Если строите инструмент, выполняющий действия от имени залогиненного пользователя (например, UI поиска по коду), правильная форма — OAuth App.

Как они получают вебхуки

GitHub Apps

Вы настраиваете один URL вебхука при создании приложения. Когда пользователь устанавливает приложение на аккаунт или репозиторий, GitHub начинает слать события этого охвата на ваш URL. Среди событий — installation (жизненный цикл установки/удаления), installation_repositories (добавленные или удалённые репозитории) и те типы событий, на которые подписано ваше приложение (push, pull_request и т. д.).

Каждое событие содержит заголовок X-GitHub-Hook-Installation-Target-Type («integration») и installation ID, по которому можно выпустить токен для этой конкретной установки. Подпись — HMAC SHA-256 в X-Hub-Signature-256 — та же форма, что у вебхуков репозитория.

OAuth Apps

У OAuth Apps нет встроенной подписки на вебхуки. Чтобы получать вебхуки, авторизовавшие приложение пользователи должны создать вебхуки репозитория или организации, указывающие на URL приложения. Это значит, что охват вебхуков приложения привязан к тому, где его пользователи настроили подписки, а не к тому, где «установлено» само приложение.

Некоторые команды строят OAuth Apps, которые после авторизации автоматически создают вебхуки через API GitHub. Это работает, но теперь вы управляете жизненным циклом вебхуков по каждому пользователю наряду с собственной логикой приложения.

Аутентификация — вот где настоящее расхождение

GitHub Apps аутентифицируются через запросы, подписанные JWT, чтобы выпускать короткоживущие installation-токены (1 час) на каждую установку. JWT подписывается приватным ключом, который вы генерируете при создании приложения. Ваш код:

// 1. Подписать JWT приватным ключом приложения (срок 10 минут)
const jwt = createAppJwt(APP_ID, PRIVATE_KEY);

// 2. Обменять JWT на installation-токен (действует 1 час)
const token = await fetchInstallationToken(jwt, INSTALLATION_ID);

// 3. Делать вызовы API с этим токеном
const res = await fetch('https://api.github.com/repos/x/y/issues', {
  headers: { Authorization: `token ${token}` },
});

Installation-токены ограничены установкой и истекают автоматически — поэтому утечка имеет ограниченный радиус поражения.

OAuth Apps аутентифицируются пользовательскими access-токенами, полученными через стандартный OAuth-флоу. По умолчанию эти токены долгоживущие и действуют как пользователь — утечка одного означает, что атакующий может всё, что мог бы этот пользователь. Документация GitHub подталкивает к GitHub Apps для новых интеграций отчасти по этой причине.

Права: ограниченные против широких

GitHub Apps позволяют запросить гранулярные права: читать issues, писать checks, читать pull requests, без доступа к остальному. Каждое право независимо. Пользователь видит точный список и может отказать.

OAuth Apps используют более старую систему на основе scopes: repo, read:user и т. д. Scopes грубее. Scope repo даёт доступ на чтение и запись ко всем репозиториям, которые видит пользователь, — версии «только чтение по конкретным репозиториям» нет.

Для бота код-ревью, которому нужно лишь читать код и писать check runs, GitHub App с двумя конкретными правами гораздо менее навязчива, чем OAuth App, просящая полный доступ repo.

Локальное тестирование обоих

Механика подписи вебхука одинакова — про настройку см. локальное тестирование вебхуков GitHub. Разница в том, как вы регистрируете URL.

  • GitHub App: укажите URL вебхука на странице настроек приложения. Установите приложение на тестовый репозиторий. Запустите события. Готово.
  • OAuth App: у самого приложения вебхуков нет. Добавьте вебхук репозитория (вручную на странице настроек репозитория или программно через API), указывающий на ваш URL туннеля.

Для OAuth Apps нужно также протестировать сам OAuth-колбэк-флоу — см. как тестировать OAuth-колбэки локально.

Миграция между ними мучительна

Если начали с OAuth App и позже поняли, что нужна GitHub App, мигрировать нельзя. Пользователям придётся заново авторизовать новое приложение, вам — заново выпускать сохранённые токены, а все вебхуки репозитория, настроенные через OAuth App, будут срабатывать, пока их не удалят. Потратьте десять минут в начале на выбор правильного типа.

Когда что выбирать

Выбирайте GitHub App, когда:

  • Ваша интеграция работает по своему расписанию или в ответ на события, без залогиненного пользователя.
  • Вам нужны ограниченные права на конкретные репозитории или организации.
  • Вам нужны вебхуки, привязанные к охвату установки, а не настраиваемые по репозиториям.
  • Вы строите что-то, что со временем попадёт в GitHub Marketplace.

Выбирайте OAuth App, когда:

  • Ваш инструмент — UI, в который пользователи входят и действуют в своём аккаунте GitHub.
  • Нужно действовать точно как пользователь, включая его шаблоны доступа.
  • Вебхуки не нужны, или вы настроите их вручную по репозиториям.

О деталях проверки подписи см. руководство по проверке подписей. Запишитесь в лист ожидания PortPreview ради туннеля, который справляется с таймингом вебхуков GitHub и захватом для повтора.

Часто задаваемые вопросы

Что мне строить — GitHub App или OAuth App?
GitHub App — для интеграций, которые работают автономно, нуждаются в ограниченных правах или хотят вебхуки, привязанные к охвату установки. OAuth App — для инструментов, действующих от имени залогиненного пользователя. Если интеграция работает без активного пользователя (бот, автоматизация, задача по расписанию), это почти всегда GitHub App.
Чем вебхуки GitHub App отличаются от вебхуков репозитория?
У GitHub Apps есть один настроенный URL вебхука, получающий события из каждого охвата установки, плюс события жизненного цикла установки. Вебхуки репозитория настраиваются по репозиториям и не включают события установки. Механизм подписи (HMAC SHA-256, X-Hub-Signature-256) одинаков.
Можно ли превратить OAuth App в GitHub App?
Не напрямую. Вы создадите новую GitHub App, попросите пользователей её установить, заново выпустите сохранённые учётные данные и почистите вебхуки репозитория, настроенные OAuth App. Встроенной миграции нет. Тщательно выбирайте тип до того, как пользователи начнут авторизацию.