Eu reviso as conexões OAuth da minha conta Google todo trimestre. Não é paranoia — é higiene básica de segurança. Segundo o Sapo.pt, muitos usuários acumulam dezenas de plataformas conectadas sem perceber, e cada uma dessas conexões é um vetor de ataque silencioso. Para nós, devs, o problema é ainda mais grave porque lidamos com tokens, scopes e refresh tokens que podem sobreviver anos se ninguém revogar.
Por que devs precisam se preocupar mais que usuários comuns
Quando você clica em “Entrar com Google” num SaaS qualquer, está autorizando um fluxo OAuth 2.0 completo. O que muita gente esquece é que essa autorização tem três camadas que merecem atenção:
- Access Token — curta duração (geralmente 1h), usado em cada request à API.
- Refresh Token — longa duração, pode permanecer válido indefinidamente até ser revogado manualmente. Permite gerar novos access tokens sem interação do usuário.
- Scopes — definem exatamente quais dados o app pode acessar (email, perfil, Drive, Calendar, contatos, etc.).
Na minha experiência, o ponto crítico é o refresh token. Enquanto o usuário não revogar a permissão na conta Google, aquele token pode ser reutilizado à vontade. Se o SaaS for comprometido — e SaaS são comprometidos o tempo todo — o atacante herda acesso à sua conta Google com os mesmos scopes que você concedeu originalmente.
E aqui entra um detalhe que pega até dev experiente: scopes sensíveis como https://www.googleapis.com/auth/drive ou https://www.googleapis.com/auth/gmail.readonly continuam válidos mesmo depois que você parou de usar a plataforma há meses. Não existe “expiração por inatividade” automática para refresh tokens na maioria dos fluxos OAuth do Google.
Onde encontrar as conexões da sua conta
O Sapo.pt indica a página oficial de conexões da conta Google. O caminho mais estável, que funciona em qualquer versão da interface, é:
- Acesse myaccount.google.com/connections.
- Você verá duas listas distintas: “Aplicativos e serviços de terceiros” e “Apps que você usa” (apps internos do Google, como Workspace).
- Clique em cada item para inspecionar os scopes concedidos e a data da autorização original.
- Para revogar, selecione o item e clique em “Remover acesso”.
Dica de dev: faça a mesma auditoria em myaccount.google.com/permissions. Em algumas versões da interface, é onde aparecem os apps com acesso a dados sensíveis. As duas páginas existem por motivos históricos e cobrem casos ligeiramente diferentes — vale checar as duas.
Na Prática: auditando conexões via API
Se você é dev e quer automatizar essa auditoria — por exemplo, para monitorar contas da sua equipe ou do seu próprio produto — dá para inspecionar tokens emitidos usando a Google Identity API. Eu rodo um script Node.js mensalmente que me avisa quando aparece um app novo autorizado com scopes amplos.
Aqui vai um exemplo funcional usando a biblioteca oficial googleapis:
import { google } from 'googleapis';
import { OAuth2Client } from 'google-auth-library';
const oauth2Client = new OAuth2Client(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.GOOGLE_REDIRECT_URI
);
// Refresh token do seu usuário admin com scope de auditoria
oauth2Client.setCredentials({
refresh_token: process.env.ADMIN_REFRESH_TOKEN,
});
const oauth2 = google.oauth2({ auth: oauth2Client, version: 'v2' });
// Lista os scopes atualmente concedidos na sessão/token
async function listMyScopes() {
const tokenInfo = await oauth2.tokeninfo({
access_token: oauth2Client.credentials.access_token,
});
console.log('Scopes ativos:', tokenInfo.data.scope);
console.log('Expira em:', tokenInfo.data.expires_in, 'segundos');
return tokenInfo.data;
}
// Verifica se um scope sensível está presente
function hasScope(scopesString, targetScope) {
const scopes = scopesString.split(' ');
return scopes.includes(targetScope);
}
(async () => {
const info = await listMyScopes();
const sensitiveScopes = [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/contacts',
];
sensitiveScopes.forEach((scope) => {
if (hasScope(info.scope, scope)) {
console.warn(`⚠️ ALERTA: este app possui o scope sensível ${scope}`);
}
});
})();
Para um nível mais profundo de auditoria corporativa, existe a Google Workspace Admin SDK com o endpoint users.tokens.list, que retorna todos os tokens OAuth emitidos pelos usuários do domínio. Útil quando sua empresa usa Workspace e você quer mapear quem autorizou o quê — essencial para compliance em LGPD/GDPR.
Passo a passo para limpeza manual
- Abra myaccount.google.com/connections em janela anônima — evita cache enganoso da interface.
- Ordene por data de autorização, se a UI permitir. Conexões com mais de 2 anos sem uso são candidatas imediatas a remoção.
- Para cada item, clique e inspecione os scopes. Se você não reconhece o app ou os scopes são amplos demais para o uso que fazia, remova sem dó.
- Repita o processo em myaccount.google.com/permissions.
- Ative o 2FA se ainda não estiver ativo. Sem isso, qualquer revogação é inútil se alguém já capturou um refresh token em algum momento.
Erros comuns que devs cometem
Ao longo dos anos, vi colegas repetirem os mesmos deslizes em produção. Anote os mais caros:
- Pedir scope demais “por via das dúvidas”. Se você só precisa do email e do perfil, peça apenas
emaileprofile. Scopes amplos comoopenid+email+profile+drive.readonlyno mesmo app fazem o usuário desconfiar e ampliam drasticamente o impacto em caso de breach. - Esquecer de implementar logout que revoga o token. Quando o usuário clica em “sair” no seu app, você deve chamar o endpoint
https://oauth2.googleapis.com/revoke?token=.... Caso contrário, mesmo sem usar mais, o refresh token continua válido no seu backend. - Persistir refresh tokens em localStorage do navegador. Isso vaza em qualquer XSS. Refresh token vai em cookie httpOnly ou, melhor ainda, exclusivamente server-side.
- Não tratar o erro
invalid_grant. Quando um usuário revoga o acesso na conta Google, seu app recebeinvalid_grantna próxima tentativa de refresh. Se você só loga o erro e continua tentando em loop, vai gerar ruído e potencialmente rate-limit. Capture, limpe o token armazenado e redirecione para novo login. - Confundir “Sign in with Google” com OAuth client-side. O fluxo implícito foi depreciado pela Google. Se você está construindo algo novo em 2026, use obrigatoriamente Authorization Code Flow com PKCE.
Sobre esse último ponto: a Google vem endurecendo as políticas de verificação de apps OAuth. Apps não verificados que pedem scopes sensíveis exibem tela de aviso “Não verificado” para o usuário, derrubando conversão de cadastro em até 40%. Planeje o app review desde o design, não deixe para depois do MVP.
Comparação rápida: Sign in with Google vs alternativas
| Provedor | Vantagem principal | Desvantagem para devs |
|---|---|---|
| Google (OAuth 2.0 nativo) | Amplo ecossistema, scopes granulares, totalmente auditável | Verificação burocrática, app review lento |
| Auth0 | Federado, abstrai complexidade multi-provider | Custo escala rápido, lock-in parcial |
| Clerk | DX excelente, moderno, Next.js first | Vendor lock-in forte, opções enterprise caras |
| Supabase Auth | Open source, Postgres nativo | Provider Google exige config manual cuidadosa |
| NextAuth.js | Grátis, várias providers, integrável | Manutenção e segurança por sua conta |
Na minha stack padrão, mantenho Clerk para projetos novos em React/Next.js e NextAuth.js quando preciso de controle total e zero dependência externa. Para produtos B2B integrados a Google Workspace, vou direto na Google Cloud com OAuth do zero — é mais código, mas nenhum vendor tem acesso aos tokens, e isso vale ouro em auditoria.
FAQ — Perguntas que devs realmente fazem
Revogar o acesso na página do Google invalida o refresh token imediatamente?
Sim. No momento em que você clica em “Remover acesso”, o Google revoga o refresh token e qualquer access token ativo derivado dele. Apps bem implementados recebem invalid_grant na próxima tentativa de refresh e devem tratar isso como sinal de logout definitivo.
Posso listar todos os apps conectados via API em vez da interface web?
Para uso pessoal, não existe endpoint público que liste apps OAuth de terceiros na sua conta. Para domínios Workspace, sim, via Admin SDK no Directory API > users.tokens.list. Para auditoria pessoal, a interface web segue sendo a forma oficial.
Scopes granulares como openid email são seguros?
São os mais seguros que existem no ecossistema Google. Só revelam seu ID, email verificado e foto. Não concedem acesso a Drive, Gmail, Calendar ou contatos. Use-os sempre que possível e adicione outros scopes apenas sob demanda justificada.
O que acontece se eu revogar o acesso de um app que eu mesmo desenvolvi?
O app perde acesso imediatamente e o refresh token é invalidado. Para testar esse cenário em dev, simule um revoke via endpoint e garanta que seu fluxo trata o erro com elegância — redirecionando para novo login, nunca exibindo stacktrace para o usuário final.
Vale a pena criar um painel interno para monitorar conexões OAuth dos meus clientes?
Se você tem um SaaS B2B com integração Google, sim. Logs de invalid_grant e tentativas de refresh falhando são sinais de que o cliente revogou o acesso ou rotacionou credenciais. Capture isso e notifique o usuário proativamente antes que ele reclame no suporte.
Considerações finais
O ponto principal, que o Sapo.pt levanta mas não aprofunda, é que conexões OAuth esquecidas são dívida técnica de segurança. Trate a lista de apps conectados como trata suas dependências no package.json: revise periodicamente, remova o que não usa e mantenha visível o que sobra.
E se você está construindo um produto que consome Google APIs, invista tempo na experiência de revogação. Muitas vezes, o usuário vai querer desconectar seu app — se o caminho for claro e o feedback imediato, ele volta. Se for confuso, ele simplesmente abandona a integração e nunca mais abre.
Gostou? Me segue no GitHub e deixa um comentário se tiver dúvida ou quiser aprofundar algum ponto.