Introdução
Abra o DevTools do seu navegador agora mesmo, vá até a aba Application e procure por tokens no localStorage, sessionStorage ou nos cookies. Se a sua aplicação é uma SPA — Angular, React, Vue — há uma boa chance de que um JWT esteja lá, totalmente legível, esperando que alguém com um mínimo de conhecimento técnico o copie e use. Um API Gateway pode validar esse token a cada request, rejeitar chamadas sem autenticação e aplicar rate limiting severo contra abusos. Mas ele não pode impedir que um script malicioso, injetado via XSS, roube o token antes mesmo que o request chegue ao gateway.
Esse é o paradoxo que quero explorar neste artigo. Em arquiteturas de microservices com SPAs no frontend, o API Gateway é uma peça essencial — centraliza autenticação, observabilidade e políticas de segurança em um único ponto. Porém ele não é bala de prata. A segurança real de tokens no browser depende de decisões arquiteturais que vão muito além de configurar um plugin de JWT no Kong ou no Azure APIM.
Este é o terceiro artigo da série Segurança para Devs. No primeiro artigo, cobri os fundamentos de JWT, OAuth2, OpenID Connect e os tipos de Client ID no Azure Entra ID. No segundo artigo, implementei o padrão BFF com ASP.NET Core 8, Angular 16+ e cookies HttpOnly. Agora vou fechar o ciclo respondendo perguntas que ficaram em aberto: o que é um API Gateway, quais são os projetos open source mais robustos, como ele se integra com BFF, e — a questão central — qual é a abordagem mais robusta segundo a OWASP para proteger tokens em SPAs.
Ao final deste artigo, você vai entender quando usar (e quando não usar) API Gateway, por que JWT é vulnerável em qualquer forma de armazenamento no browser — incluindo variáveis em memória — e por que a recomendação da OWASP é que o token simplesmente não exista no browser.
O Que é um API Gateway
Um API Gateway é o ponto único de entrada para todas as APIs de uma arquitetura de microservices. Diferente de um reverse proxy — que simplesmente encaminha requests para servidores backend — e de um load balancer — que distribui carga entre instâncias — o API Gateway entende as suas APIs. Ele sabe quem está chamando, qual endpoint está sendo acessado, se o token é válido, se o rate limit foi excedido, e pode transformar tanto o request quanto o response antes de chegar ao serviço final.
Na prática, o API Gateway funciona como um porteiro inteligente. Ele não apenas abre a porta — ele verifica identidade, aplica regras, registra quem entrou e pode até modificar a mensagem antes de entregá-la ao destinatário.
A confusão entre API Gateway, reverse proxy e load balancer é comum porque alguns produtos fazem mais de uma coisa. O NGINX, por exemplo, nasceu como web server e reverse proxy, mas com módulos extras pode funcionar como API Gateway. Para deixar claro onde cada um atua, veja a tabela abaixo:
| Aspecto | Reverse Proxy | Load Balancer | API Gateway |
|---|---|---|---|
| Foco principal | Encaminhar requests | Distribuir carga | Gestão completa de APIs |
| Autenticação | Básica (IP, headers) | Não | JWT, OAuth2, API keys, mTLS |
| Rate limiting | Básico | Não | Avançado (por cliente, por API, quotas) |
| Transformação | Cabeçalhos | Não | Request/response body e headers |
| Observabilidade | Logs básicos | Métricas de saúde | Métricas, logs, tracing distribuído |
| Exemplos | NGINX, HAProxy | Azure LB, AWS ELB | Kong, APISIX, Azure APIM |
As responsabilidades típicas de um API Gateway incluem: routing inteligente, rate limiting e throttling, autenticação e autorização, transformação de request/response, observabilidade centralizada (métricas, logs e tracing distribuído), caching de respostas e API versioning. Todas essas preocupações transversais (cross-cutting concerns) ficam centralizadas em um único ponto em vez de serem reimplementadas em cada microservice.
ℹ️ Informação: Um reverse proxy encaminha requests. Um API Gateway entende suas APIs — quem está chamando, com qual token, sob qual política, e pode transformar a comunicação em ambas as direções.
Principais Players e Projetos Open Source
O ecossistema de API Gateways é extenso. Existem projetos open source robustos, soluções cloud-managed e gateways enterprise com licenciamento comercial. Vou focar nos projetos mais relevantes para quem desenvolve e opera microservices hoje.
Open Source
Kong é provavelmente o API Gateway open source mais conhecido. Construído sobre NGINX/OpenResty, usa Lua para plugins e oferece DB-less mode para configuração declarativa. O Kong Ingress Controller torna-o Kubernetes-native, e a comunidade é enorme — com centenas de plugins disponíveis no Kong Hub. É a escolha segura quando se busca maturidade e ecossistema.
Apache APISIX é o concorrente direto do Kong em performance. Usa etcd como backend (em vez de PostgreSQL), suporta plugins em Lua, Java, Go e Python, e vem com dashboard nativo. Incubado pela Apache Foundation, tem crescido rápido em adoção, especialmente em ambientes que exigem alta throughput com baixa latência.
Tyk é escrito em Go e se diferencia pelo suporte nativo a GraphQL, developer portal integrado e analytics built-in. Tem uma versão community (open source) e uma versão enterprise com features adicionais. É uma boa escolha quando o time já trabalha com GraphQL e quer um gateway que entenda esse protocolo nativamente.
KrakenD é stateless por design — não depende de banco de dados, toda a configuração é declarativa em JSON ou YAML. Escrito em Go, entrega performance extremamente alta e é ideal para cenários onde a simplicidade operacional é prioridade. Se você não quer gerenciar um PostgreSQL ou etcd só para o gateway, KrakenD resolve.
Traefik nasceu no ecossistema de containers e brilha no auto-discovery de serviços via Docker labels ou Kubernetes annotations. Gerenciamento de certificados Let’s Encrypt é automático, e a cadeia de middlewares é configurável de forma declarativa. Para quem já usa Docker Compose ou Kubernetes, Traefik é o gateway que “se configura sozinho”.
NGINX vai além de reverse proxy quando combinado com módulos Plus ou com o NGINX Gateway Fabric para Kubernetes. Embora não seja um API Gateway “de nascença”, a maturidade e estabilidade do projeto fazem dele uma escolha confiável para equipes que já dominam sua configuração.
Cloud e Enterprise
No universo cloud, os principais são: Azure API Management (APIM) — com developer portal, policies em XML/C# e integração com Azure Entra ID; AWS API Gateway — REST e WebSocket com integração Lambda e API keys nativo; Google Cloud Apigee — analytics avançado e monetização de APIs; e Cloudflare API Shield — proteção edge-based com mTLS nativo e DDoS integrado.
Comparativo Rápido
| Gateway | Linguagem | Licença | K8s-native | Destaque |
|---|---|---|---|---|
| Kong | Lua/C | Apache 2.0 | Sim | Maior ecossistema de plugins |
| APISIX | Lua | Apache 2.0 | Sim | Performance raw mais alta |
| Tyk | Go | MPL 2.0 | Sim | GraphQL nativo |
| KrakenD | Go | Apache 2.0 | Sim | Stateless, declarativo |
| Traefik | Go | MIT | Sim | Auto-discovery de serviços |
| NGINX | C | BSD | Sim (Fabric) | Maturidade, estabilidade |
💡 Dica: Se o critério é performance pura, APISIX e KrakenD lideram. Se é ecossistema e maturidade, Kong e NGINX dominam. Se é facilidade operacional com containers, Traefik é difícil de bater.
Quando Usar e Quando NÃO Usar API Gateway
API Gateway é uma peça de infraestrutura poderosa, mas que adiciona complexidade operacional. Usá-lo sem necessidade real é over-engineering. Não usá-lo quando necessário é expor sua arquitetura a riscos e retrabalho.
Quando usar
- Microservices com múltiplos consumers — web, mobile, IoT, parceiros externos acessando as mesmas APIs. O gateway centraliza autenticação e políticas sem que cada serviço reimplemente.
- Cross-cutting concerns centralizados — autenticação, rate limiting, logging, caching. Sem gateway, cada microservice precisa de sua própria implementação, gerando inconsistência e duplicação.
- Multi-tenancy e rate limiting por cliente — quando diferentes clientes ou planos de assinatura têm limites distintos de consumo. O gateway aplica essas políticas sem que os serviços precisem conhecê-las.
- API versioning e deprecation control — migrar de v1 para v2 sem quebrar clientes. O gateway roteia baseado na versão, enquanto ambas as implementações coexistem.
- Transformação de protocolos — frontend fala REST, backend fala gRPC. O gateway faz a tradução, evitando que o frontend precise entender protocolos internos.
- Compliance e auditoria — requisitos como PCI-DSS e LGPD exigem logs centralizados de quem acessou o quê e quando. O gateway é o ponto natural para essa captura.
Quando NÃO usar
- Monolito simples com único frontend — adicionar API Gateway para um monolito que serve um único SPA é complexidade desnecessária. Um NGINX como reverse proxy é suficiente.
- 2-3 APIs internas sem exposição externa — se tudo está na mesma rede interna e há poucos serviços, a comunicação direta é mais simples. YAGNI (You Aren’t Gonna Need It).
- Equipe pequena sem capacidade operacional — um API Gateway é mais uma peça de infraestrutura para monitorar, atualizar e debugar. Se a equipe mal consegue manter o que já existe, adicionar um gateway piora a situação.
O Anti-Pattern: Gateway Gordo
Um erro comum é usar o API Gateway como orquestrador de lógica de negócio. O gateway deve fazer routing e aplicar policies — nunca orquestração de fluxo. Se o gateway decide “chamar API A, depois API B, depois API C com o resultado combinado”, isso é responsabilidade de um BFF ou de um padrão de saga, não do gateway.
⚠️ Atenção: API Gateway gordo é um monolito disfarçado. Se tem lógica de negócio no gateway, algo está errado. Ele deve ser uma camada fina de políticas e roteamento, não um orquestrador de workflow.
API Gateway e a Segurança em Arquiteturas SPA
Esta é a seção central deste artigo. Aqui vou explicar o que o API Gateway pode (e o que não pode) fazer pela segurança de uma SPA, e por que o JWT é vulnerável independente de onde esteja armazenado no browser.
O Problema Fundamental
SPAs são Public Clients — rodam inteiramente no browser do usuário, sem capacidade de guardar segredos. Não existe secret client seguro no frontend. O código JavaScript é acessível via DevTools, o network tab mostra cada request, e qualquer armazenamento no browser é acessível via JavaScript. Esse é o contexto no qual o JWT precisa operar, e é aí que a maioria das arquiteturas falha.
Se você ainda não está familiarizado com os fundamentos de JWT, OAuth2 e tipos de client, recomendo ler o primeiro artigo da série antes de continuar.
O Que o API Gateway PODE Fazer
O API Gateway é muito eficiente em validar tokens e aplicar políticas de forma centralizada:
- JWT validation centralizada — verifica signature, issuer, audience e expiration em um único ponto, em vez de cada microservice reimplementar a validação. Um token rejeitado no gateway nunca chega aos serviços internos.
- Rate limiting contra brute force e abuso — limitar chamadas por IP, por token ou por cliente reduz a superfície de ataque para ataques automatizados.
- IP allowlisting e blocklisting — restringir acesso a endpoints críticos por faixa de IP ou bloquear IPs suspeitos em tempo real.
- Transformação de request/response — remover claims sensíveis antes de devolver a resposta ao client, ou adicionar headers de segurança que o serviço backend não conhece.
- mTLS entre gateway e backend — garantir que somente o gateway acessa os microservices. Mesmo que um atacante descubra um endpoint interno, sem o certificado do gateway não consegue chamar diretamente.
- CORS enforcement centralizado — definir quais origens podem chamar quais APIs, em vez de cada microservice configurar CORS independentemente (e potencialmente errar).
Exemplo de configuração no Kong com plugins de JWT, rate limiting e CORS:
| |
Essa configuração valida tokens JWT automaticamente, limita cada consumidor a 100 requests por minuto e restringe CORS apenas à origem legítima da SPA. Tudo centralizado, sem que os microservices precisem saber.
O Que o API Gateway NÃO Resolve — Token Vulnerável em QUALQUER Armazenamento no Browser
Aqui é onde a maioria dos artigos sobre API Gateway para. Eles mostram a configuração de JWT validation, declaram vitória e seguem em frente. Mas o problema real não é validar o token — é que o token existe no browser em primeiro lugar.
Vou percorrer cada método de armazenamento para demonstrar que nenhum é seguro quando um XSS é explorado:
localStorage e sessionStorage — o método mais comum e mais vulnerável. O token persiste (localStorage) ou vive até o fechamento da aba (sessionStorage), e qualquer JavaScript na página pode lê-lo com window.localStorage.getItem('token'). Um script malicioso injetado via XSS faz exatamente isso.
Cookie sem HttpOnly — desenvolvedores que migram de localStorage para cookies sem configurar a flag HttpOnly não ganham nada. O cookie continua acessível via document.cookie, tão legível via JavaScript quanto localStorage.
Variáveis em memória — closures, module scope, Redux store, NgRx store, variável global. Este é o ponto que muitos desenvolvedores erram ao acreditar que “se não persistir, está seguro”. O raciocínio é: “o token existe apenas em memória JavaScript, não está em nenhum storage persistente, logo XSS não consegue acessá-lo”. Está errado. O XSS injeta um script que roda no mesmo contexto de execução JavaScript da aplicação. Isso significa que o atacante pode:
Ler diretamente variáveis e stores do framework — se o token está em um Redux store, o script acessa
window.__REDUX_STORE__ou qualquer referência global. Se está em uma variável exportada de um módulo, importações dinâmicas ou referências de escopo podem alcançá-la.Fazer monkey-patch de
fetcheXMLHttpRequestpara interceptar o headerAuthorization: Bearer ...em trânsito — mesmo que o token esteja numa closure inacessível, no momento em que a aplicação envia um request com o token no header, o atacante captura:
| |
- Hookear interceptors do framework — Angular
HttpInterceptor, Axios interceptors, ou qualquer middleware que adiciona o token aos requests. O atacante substitui o interceptor original por um que copia o token antes de adicioná-lo ao header.
Web Worker — mesmo isolando o token em um Web Worker, ele precisa devolver o token (ou enviá-lo como parte de um request) ao main thread via postMessage(). Nesse momento, o script malicioso que está ouvindo eventos de message no main thread intercepta o token.
⚠️ Atenção: Se um atacante consegue XSS, ele controla o runtime JavaScript inteiro. Não importa ONDE o token está na memória do browser — se o JavaScript da aplicação consegue acessá-lo para enviar requests, o script malicioso também consegue. A superfície de ataque não é o “local de armazenamento”, é o contexto de execução compartilhado do JavaScript.
O veredicto: se o token existe no browser em qualquer forma acessível ao JavaScript — seja localStorage, cookie sem HttpOnly, closure, Redux store, Web Worker com postMessage — um XSS significa game over. O API Gateway valida tokens no lado do servidor, mas não tem como resolver um problema que acontece inteiramente no browser, antes do request chegar à rede. A recomendação é clara: o token não deve existir no browser. É exatamente isso que o padrão BFF com HttpOnly cookies resolve.

API Gateway + BFF: Faz Sentido?
Sim, faz — mas depende do tamanho e da complexidade da sua arquitetura. API Gateway e BFF resolvem problemas diferentes e, quando combinados, criam uma arquitetura de segurança robusta onde cada peça tem uma responsabilidade clara.
A Arquitetura Combinada
O fluxo completo fica assim:
| |
Nessa arquitetura, o BFF gerencia toda a autenticação do usuário — sessão, cookies HttpOnly, token refresh. O token nunca chega ao browser. O BFF obtém o token do Identity Provider, armazena no servidor e envia apenas um cookie de sessão HttpOnly para o browser. Cada request da SPA inclui esse cookie automaticamente, e o BFF injeta o token real antes de encaminhar ao API Gateway.
O API Gateway recebe o request já autenticado (com o token real no header) e aplica suas políticas: validação de JWT, rate limiting, mTLS para os backends, versionamento de APIs e observabilidade centralizada. Ele não sabe nem se importa que o request veio de um BFF — ele apenas valida e roteia.
Separação de Responsabilidades
| Responsabilidade | BFF | API Gateway |
|---|---|---|
| Autenticação do usuário | ✅ | ❌ |
| Sessão e cookies HttpOnly | ✅ | ❌ |
| Token refresh | ✅ | ❌ |
| JWT validation | ❌ | ✅ |
| Rate limiting | Básico | ✅ Avançado |
| mTLS para backends | ❌ | ✅ |
| API versioning | ❌ | ✅ |
| CORS | Parcial | ✅ |
| Observabilidade | Parcial | ✅ Centralizado |
O BFF é confidential client — possui client_secret, roda no servidor, e pode autenticar de forma segura com o Identity Provider. O API Gateway é o policy enforcement point — valida tokens, aplica rate limiting e garante que apenas requests autorizados cheguem aos microservices.
Para detalhes de implementação do BFF com ASP.NET Core 8, YARP e Angular 16+, veja o artigo anterior da série.
Quando Faz Sentido e Quando é Overkill
A combinação BFF + API Gateway faz sentido quando:
- Equipes grandes operam dezenas de microservices com múltiplos frontends (web, mobile, IoT)
- Múltiplos consumers acessam as mesmas APIs — cada consumer pode ter seu próprio BFF, mas todos passam pelo mesmo gateway
- Requisitos enterprise como multi-tenancy, API monetização, ou compliance PCI-DSS exigem governança centralizada
Já quando a equipe é pequena, os serviços são poucos e há um único frontend, o BFF sozinho com NGINX como reverse proxy é suficiente. Adicionar um API Gateway nesse cenário é complexidade operacional sem benefício proporcional.
💡 Dica: Se sua equipe opera 3 APIs internas e um único frontend, BFF + NGINX é suficiente. API Gateway brilha quando há escala, múltiplos consumers, ou requisitos enterprise. Não adicione complexidade sem necessidade real.
OWASP: A Abordagem Mais Robusta para JWT em SPAs
A OWASP e o IETF mantêm o draft OAuth 2.0 for Browser-Based Applications, que é a referência mais atual para autenticação em SPAs. Esse documento deixa claro: nenhum armazenamento no browser é seguro contra XSS.
Por Que NENHUM Armazenamento no Browser é Seguro
Reforçando o que demonstrei na Seção 5 com um resumo consolidado:
| Método de Armazenamento | Vulnerável a XSS? | Como o Atacante Acessa |
|---|---|---|
localStorage | ✅ Sim | window.localStorage.getItem('token') |
sessionStorage | ✅ Sim | Mesmo acesso via JS, apenas escopo de aba |
Cookie sem HttpOnly | ✅ Sim | document.cookie |
| Variável JS em memória | ✅ Sim | Mesmo contexto de execução — monkey-patch de fetch/XHR intercepta o header Authorization |
| Web Worker | ✅ Sim* | Token precisa voltar ao main thread via postMessage() |
O denominador comum é simples: qualquer coisa acessível ao JavaScript da aplicação é acessível a um script injetado via XSS. O browser não diferencia “seu código legítimo” de “script malicioso injetado” — ambos rodam no mesmo sandbox, com os mesmos privilégios, no mesmo contexto de execução.
Hierarquia de Abordagens — Da Menos Para Mais Segura
- ❌
localStorage+ Access Token direto — XSS lê diretamente. É o cenário mais vulnerável e mais comum. - ❌
sessionStorage+ PKCE — mesmo problema do localStorage, apenas com escopo reduzido à aba do browser. Se o atacante tem XSS, ele está na mesma aba. - ❌ Variável em memória / closure — monkey-patch de
fetchouXMLHttpRequestintercepta o token em trânsito, como demonstrado anteriormente. A falsa sensação de segurança é o maior risco aqui. - ⚠️ Service Worker como Token Mediator — o token fica isolado no Service Worker context, inacessível ao main thread JavaScript. O Service Worker intercepta requests da SPA e injeta o token automaticamente. É uma abordagem melhor, mas com limitações significativas: o Service Worker pode ser desregistrado pelo browser, não funciona em modo incógnito em alguns browsers, e a complexidade de implementação é alta. Poucos frameworks suportam nativamente.
- ✅✅ BFF Pattern com HttpOnly cookies — o token nunca chega ao browser. O BFF, como confidential client no servidor, obtém e armazena o token. Apenas um cookie de sessão HttpOnly (inacessível ao JavaScript) trafega entre browser e servidor. XSS não tem o que roubar.
Token Mediator Pattern
O Token Mediator é a recomendação alternativa da OWASP para quando o BFF não é viável. A ideia é usar um Service Worker que intercepta todos os requests da SPA. Quando a SPA faz um fetch(), o Service Worker captura o request, adiciona o token ao header Authorization e encaminha ao servidor. O token fica armazenado apenas no contexto do Service Worker, que é separado do main thread JavaScript.
Na teoria, isso impede que XSS no main thread acesse o token. Na prática, existem limitações que fazem do Token Mediator uma alternativa inferior ao BFF: o browser pode desregistrar Service Workers sob pressão de memória, nem todos os browsers mantêm Service Workers ativos em modo incógnito, e a complexidade de implementar refresh token dentro de um Service Worker (que não tem acesso a DOM ou localStorage) é significativa.
Mitigações no Browser — Defesa em Profundidade
Mesmo com BFF, é fundamental aplicar camadas de defesa no browser para reduzir a probabilidade de XSS em primeiro lugar:
- Content Security Policy (CSP) rigoroso — configure
script-src 'self'semunsafe-inlinee semunsafe-eval. Isso bloqueia a execução de scripts inline injetados via XSS, reduzindo drasticamente a superfície de injeção. - Subresource Integrity (SRI) para scripts externos — garante que scripts carregados de CDNs não foram comprometidos. Se o hash não bate, o browser bloqueia a execução.
- Trusted Types API — previne DOM-based XSS impedindo o uso de
innerHTML,eval()e outras sinks perigosas sem validação explícita. É suportada pelo Chrome e Edge. - DPoP (Demonstration of Proof-of-Possession) — torna o token roubado inútil sem a chave privada correspondente. Detalhado na próxima seção.
- Short-lived access tokens (1-5 minutos) — reduz a janela de ataque. Mesmo que o token seja roubado, expira rapidamente.
⚠️ Atenção: Essas medidas são camadas de defesa (defense in depth), não soluções definitivas. Se XSS ocorre, o atacante pode operar em tempo real — mesmo com token de 1 minuto, ele age nos 60 segundos disponíveis. Automação torna isso trivial.
Veredicto OWASP
A abordagem mais robusta segundo a OWASP é BFF + HttpOnly cookies + CSP rigoroso. O token não deve existir no browser em nenhuma forma acessível ao JavaScript. O Token Mediator com Service Worker é uma alternativa válida quando BFF não é viável, mas com trade-offs significativos. Variáveis em memória, closures e stores não são alternativas seguras — são apenas uma falsa sensação de proteção que pode ser mais perigosa do que localStorage, porque os desenvolvedores baixam a guarda.
DPoP: Tokens à Prova de Roubo
O DPoP — Demonstration of Proof-of-Possession (RFC 9449) — é um mecanismo que vincula um token de acesso a um par de chaves criptográficas específico. Mesmo que o token seja interceptado, ele é inútil sem a chave privada correspondente.
Como Funciona
O fluxo é direto: o browser gera um par de chaves assimétrico usando a Web Crypto API (CryptoKey). Ao solicitar um token ao Authorization Server, o browser envia um proof JWT assinado com a chave privada. O Authorization Server vincula o access token à chave pública do browser. Em cada request subsequente, o browser envia o access token junto com um novo proof JWT assinado com a mesma chave privada. O API Gateway (ou o resource server) valida tanto o token quanto o proof.
O resultado: se um atacante rouba o access token via XSS, ele não possui a chave privada (que é um CryptoKey não-exportável armazenado no browser). Sem a chave privada, o atacante não consegue gerar proofs válidos, e o servidor rejeita o token.
Quando Usar
DPoP brilha quando o BFF não é viável — por exemplo, em mobile apps, SPAs sem backend dedicado, ou aplicações de terceiros que não controlam a infraestrutura de servidor. Nesses cenários, DPoP é a melhor proteção disponível contra token replay e roubo, pois adiciona uma camada de proof-of-possession que o Bearer token simples não tem.
Kong e Azure APIM suportam políticas customizadas para validar DPoP proofs, permitindo que o API Gateway rejeite tokens sem proof válido.
Limitações
DPoP não é perfeito. A complexidade de implementação é maior que Bearer tokens simples, e nem todos os Identity Providers suportam DPoP ainda. A chave privada, embora seja um CryptoKey não-exportável, ainda está na memória do browser — um ataque XSS sofisticado poderia, em teoria, usar a chave para gerar proofs (sem extraí-la), realizando requests autenticados em tempo real. Porém, isso é significativamente mais difícil do que simplesmente copiar um Bearer token.
💡 Dica: DPoP não substitui BFF, mas é a melhor proteção disponível quando BFF não é uma opção. Se você pode usar BFF, use BFF. Se não pode, DPoP é o próximo nível de proteção — muito superior a Bearer tokens simples.
Dicas e Boas Práticas
Aqui está uma síntese das lições mais importantes deste artigo, consolidadas como referência rápida:
Não use API Gateway como orquestrador — o gateway é uma camada fina de políticas e roteamento. Se tem lógica de negócio como “chamar API A, depois API B, combinar resultados”, isso pertence ao BFF ou a um serviço de orquestração dedicado. Gateway gordo vira monolito disfarçado.
Centralize autenticação no gateway, não nos microservices — cada microservice que reimplementa validação de JWT é uma oportunidade de inconsistência e falha de segurança. O gateway valida uma vez, os serviços confiam no gateway (validando via mTLS que o request veio dele).
Tokens no browser = risco aceito — se sua SPA armazena JWT em localStorage, sessionStorage, cookies sem HttpOnly ou variáveis em memória, aceite explicitamente o risco de XSS. Documente essa decisão arquitetural. Se o risco não é aceitável, migre para BFF com HttpOnly cookies.
CSP é sua primeira linha de defesa — um Content Security Policy rigoroso (
script-src 'self', semunsafe-inline) bloqueia a maioria dos vetores de XSS antes que eles possam executar. Implemente CSP antes de qualquer outra mitigação.Não adicione complexidade sem necessidade — BFF sozinho com NGINX como reverse proxy é suficiente para a maioria das equipes pequenas e médias. API Gateway adiciona valor quando há escala, múltiplos consumers, ou requisitos enterprise de governança. Avalie honestamente se sua arquitetura precisa de cada peça.
Short-lived tokens reduzem, não eliminam, o risco — tokens com expiração de 1-5 minutos limitam a janela de ataque, mas com automação um atacante age em segundos. Combine short-lived tokens com DPoP (se sem BFF) ou HttpOnly cookies (com BFF) para proteção efetiva.
mTLS entre gateway e backends não é opcional — sem mTLS, um atacante que descobre endpoints internos pode chamar microservices diretamente, bypassando todas as políticas do gateway. mTLS garante que somente o gateway é aceito como caller.
Conclusão
O API Gateway é uma peça fundamental em qualquer arquitetura de microservices séria. Ele centraliza preocupações transversais — autenticação, rate limiting, observabilidade, versionamento de APIs — que, sem um gateway, seriam reimplementadas de forma inconsistente em cada serviço. Os projetos open source como Kong, APISIX, Tyk, KrakenD e Traefik oferecem opções maduras para cada perfil de equipe e cenário operacional.
Mas segurança de tokens em uma SPA é um problema do browser, não da rede. O API Gateway valida tokens no servidor, e isso é importante — mas não resolve o fato de que um XSS comprometeu o runtime JavaScript no browser antes do request chegar ao gateway. O token em localStorage é acessível. O token em sessionStorage é acessível. O token numa closure ou Redux store é acessível via monkey-patch do fetch. O token num Web Worker precisa transitar pelo postMessage. Em todos os casos, XSS significa game over.
A recomendação da OWASP é clara: o token não deve existir no browser em nenhuma forma acessível ao JavaScript. BFF com HttpOnly cookies é a abordagem mais robusta — o BFF autentica como confidential client, armazena tokens no servidor, e envia apenas cookies de sessão HttpOnly para o browser. Para cenários onde BFF não é viável, DPoP (RFC 9449) adiciona proof-of-possession que torna tokens roubados inúteis sem a chave privada.
API Gateway valida tokens. BFF protege tokens. Combinados, são invencíveis.
Se quiser colocar os conceitos em prática, o segundo artigo da série tem uma implementação completa com ASP.NET Core 8, Angular 16+ e Keycloak. E para os fundamentos de JWT, OAuth2 e OpenID Connect que sustentam tudo isso, volte ao primeiro artigo.
Leia Também
- Autenticação e Autorização: JWT, OAuth2 e OpenID Connect — fundamentos de JWT, OAuth2, PKCE e tipos de Client ID no Azure Entra ID
- BFF Backend For Frontend: Segurança em SPAs — implementação completa do padrão BFF com ASP.NET Core 8, Angular 16+ e HttpOnly cookies
- Keycloak: Autenticação Grátis e Poderosa com Container e C# — Identity Provider open source para testar OAuth2/OIDC completo
- Design de API REST: Verbos HTTP e Parameter Binding — boas práticas para APIs que ficarão atrás do gateway
- Arquitetura de Software: GoF, Padrões e Cloud — fundamentos de arquitetura para microservices
Referências
- OAuth 2.0 for Browser-Based Applications (IETF) — recomendação oficial da IETF/OWASP para autenticação em SPAs, incluindo BFF e Token Mediator.
- RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP) — especificação oficial de proof-of-possession para tokens OAuth 2.0.
- OWASP Top 10 — referência para as vulnerabilidades de segurança web mais críticas, incluindo XSS (A03:2021 Injection).
- Kong Gateway Documentation — documentação oficial do Kong, incluindo plugins de JWT, rate limiting, mTLS e CORS.
- Apache APISIX Documentation — documentação oficial do APISIX, incluindo arquitetura e sistema de plugins.
- KrakenD Documentation — documentação oficial do KrakenD, incluindo configuração declarativa e pipelines stateless.
- Tyk Gateway Documentation — documentação oficial do Tyk, incluindo suporte a GraphQL e analytics.
- Traefik Documentation — documentação oficial do Traefik, incluindo auto-discovery, middlewares e Let’s Encrypt automático.
- Azure API Management — documentação oficial do Azure APIM, incluindo policies, developer portal e integração com Entra ID.

Ao comentar, você concorda com nossa Política de Privacidade, Termos de Uso e Política de Exclusão de Dados.