Todos os artigos
GitHubGitHub AppsOAuthwebhook design

GitHub Apps vs OAuth Apps: webhooks lado a lado

Na primeira vez que você constrói uma integração com o GitHub, vai passar uma hora tentando descobrir se quer uma GitHub App ou uma OAuth App. A documentação as trata como opções equivalentes. Não são. Só a história dos webhooks já costuma decidir por você.

O resumo bem curto

  • GitHub App: instalada em contas ou repositórios, tem permissões granulares, recebe webhooks dos recursos onde está instalada, autentica-se como ela mesma com tokens de curta duração.
  • OAuth App: os usuários a autorizam, ela age em nome deles com as permissões deles, recebe webhooks só se os configurar como qualquer ferramenta de terceiros, autentica-se como o usuário com tokens de longa duração.

Se você constrói algo que opera sem um usuário ativo — um bot de CI, uma automação de revisão de código, qualquer coisa agendada — você quer uma GitHub App. Se você constrói uma ferramenta que faz ações em nome de um usuário logado (como uma UI de busca de código), uma OAuth App é o formato certo.

Como elas recebem webhooks

GitHub Apps

Você configura uma URL de webhook ao criar a app. Quando um usuário instala a app numa conta ou repositório, o GitHub começa a enviar eventos daquele escopo para a sua URL. Os eventos incluem installation (o ciclo de vida de instalação/desinstalação), installation_repositories (repos adicionados ou removidos) e os tipos de evento que a sua app assinou (push, pull_request, etc.).

Cada evento inclui um cabeçalho X-GitHub-Hook-Installation-Target-Type ("integration") e um installation ID que você pode usar para cunhar um token daquela instalação específica. A assinatura é HMAC SHA-256 em X-Hub-Signature-256 — o mesmo formato dos webhooks de repositório.

OAuth Apps

OAuth Apps não têm uma assinatura de webhook embutida. Para receber webhooks, os usuários autorizados da app precisam criar webhooks de repositório ou organização apontando para a URL da app. Isso significa que o alcance de webhook da app está atrelado a onde os seus usuários configuraram assinaturas, não a onde a própria app está "instalada".

Alguns times constroem OAuth Apps que criam webhooks automaticamente via a API do GitHub após a autorização. Funciona, mas agora você gerencia o ciclo de vida do webhook por usuário ao lado da lógica própria da app.

A autenticação é a divergência real

GitHub Apps se autenticam usando requisições assinadas com JWT para cunhar tokens de instalação de curta duração (1 hora) por instalação. O JWT é assinado com uma chave privada que você gera ao criar a app. O seu código:

// 1. Assina um JWT com a chave privada da app (expira em 10 min)
const jwt = createAppJwt(APP_ID, PRIVATE_KEY);

// 2. Troca o JWT por um token de instalação (vale 1 hora)
const token = await fetchInstallationToken(jwt, INSTALLATION_ID);

// 3. Faz chamadas de API com esse token
const res = await fetch('https://api.github.com/repos/x/y/issues', {
  headers: { Authorization: `token ${token}` },
});

Tokens de instalação são limitados à instalação e expiram automaticamente — então um vazamento tem raio de impacto limitado.

OAuth Apps se autenticam com tokens de acesso de usuário obtidos pelo fluxo OAuth padrão. Esses tokens são de longa duração por padrão e agem como o usuário — vazar um significa que um atacante pode fazer tudo o que aquele usuário poderia. A documentação do GitHub te empurra para GitHub Apps em novas integrações em parte por isso.

Permissões: restritas vs amplas

GitHub Apps deixam você pedir permissões granulares: ler issues, escrever checks, ler pull requests, sem acesso a mais nada. Cada permissão é independente. O usuário vê a lista exata e pode recusar.

OAuth Apps usam o sistema mais antigo baseado em scopes: repo, read:user, etc. Os scopes são mais grosseiros. O scope repo concede acesso de leitura e escrita a todos os repositórios que o usuário pode ver — não existe versão de "somente leitura em repos específicos".

Para um bot de revisão de código que só precisa ler código e escrever check runs, uma GitHub App com duas permissões específicas é bem menos invasiva que uma OAuth App pedindo acesso completo de repo.

Testes em local com ambas

A mecânica da assinatura do webhook é idêntica — veja testes de webhooks do GitHub em local para a configuração. A diferença é como você registra a URL.

  • GitHub App: defina a URL do webhook na página de ajustes da sua app. Instale a app num repositório de teste. Dispare eventos. Pronto.
  • OAuth App: a app em si não tem webhooks. Adicione um webhook de repositório (manualmente na página de ajustes do repo, ou de forma programática pela API) apontando para a sua URL de túnel.

Para OAuth Apps, você também precisa testar o próprio fluxo de callback OAuth — veja como testar callbacks OAuth em local.

Migrar entre elas é doloroso

Se você começa com uma OAuth App e depois percebe que precisa de uma GitHub App, não dá para migrar. Os usuários têm que reautorizar a nova app, você tem que reemitir quaisquer tokens armazenados, e quaisquer webhooks de repositório que você configurou via a OAuth App vão continuar disparando até serem apagados. Gaste dez minutos no começo para escolher o tipo certo.

Quando escolher cada uma

Escolha uma GitHub App quando:

  • A sua integração roda no próprio cronograma ou em resposta a eventos, sem um usuário logado.
  • Você quer permissões restritas em repositórios ou organizações específicos.
  • Você quer webhooks atrelados ao escopo de instalação, não configurados por repo.
  • Você constrói algo que vai acabar listado no GitHub Marketplace.

Escolha uma OAuth App quando:

  • A sua ferramenta é uma UI em que os usuários fazem login e fazem coisas na própria conta do GitHub.
  • Você precisa agir exatamente como o usuário, incluindo os padrões de acesso dele.
  • Você não precisa de webhooks, ou vai configurá-los manualmente por repo.

Para os detalhes subjacentes da verificação de assinatura, veja o guia de verificação de assinatura. Entre na lista de espera do PortPreview para um túnel que lida com o timing de webhooks do GitHub e a captura para reenvio.

Perguntas frequentes

Devo construir uma GitHub App ou uma OAuth App?
GitHub App para integrações que rodam de forma autônoma, precisam de permissões restritas ou querem webhooks atrelados ao escopo de instalação. OAuth App para ferramentas que agem em nome de um usuário logado. Se a sua integração roda sem um usuário ativamente presente (um bot, automação, tarefa agendada), é quase sempre uma GitHub App.
Como os webhooks de GitHub App diferem dos webhooks de repositório?
GitHub Apps têm uma URL de webhook configurada que recebe eventos de cada escopo de instalação, mais eventos do ciclo de vida de instalação. Webhooks de repositório são configurados por repo e não incluem eventos de instalação. O mecanismo de assinatura (HMAC SHA-256, X-Hub-Signature-256) é o mesmo.
Posso converter uma OAuth App numa GitHub App?
Não diretamente. Você criaria uma nova GitHub App, pediria aos usuários para instalá-la, reemitiria quaisquer credenciais armazenadas e limparia os webhooks de repositório que a OAuth App configurou. Não há migração embutida. Escolha o tipo com cuidado antes de os usuários começarem a autorizar.