Open Banking

FAPI 1.0 no Brasil: A blindagem obrigatória que o OAuth simples não oferece

Entenda por que implementar apenas o fluxo padrão OAuth 2.0 é insuficiente para o Banco Central e como o perfil FAPI 1.0 protege o token de acesso contra replay e vazamento.

Lucas Ferreira
Lucas FerreiraEspecialista em Pagamentos e Bancos Digitais
Imagem editorial ilustrando FAPI 1.0 no Brasil: A blindagem obrigatória que o OAuth simples não oferece

Já vi arquitetos de produto chorando na mesa do bar porque achavam que um fluxo de Authorization Code padrão com TLS era suficiente para garantir a segurança de uma API de pagamento. O ecossistema financeiro brasileiro, puxado pelo regulamento do Open Banking e pelo DICT (Pix), é impiedoso com essa ingenuidade. Em 2026, se sua integração não segue o perfil Financial-grade API (FAPI) 1.0, você não está apenas fora da conformidade; você é um alvo fácil.

A maioria das discussões sobre segurança em Open Banking fica presa na camada de transporte. Arquitetos focam em certificados SSL válidos e endpoints HTTPS, ignorando que o maior risco financeiro mora justamente no que acontece depois que o token é emitido. O token de acesso é a chave do cofre. No padrão OAuth 2.0 básico, qualquer um que segure essa chave pode abrir o cofre. O FAPI 1.0 existe para garantir que apenas o dono original da chave possa usá-la.

Vamos desmembrar os mitos que ainda vejo em documentações de marketplaces e fintechs recém-nascidas.

O mito de que HTTPS e um token Bearer padrão protegem transações financeiras

Existe uma crença perigosa de que, ao criptografar o tráfego com TLS, o token de acesso (JWT) fica "blindado". Isso é falso. O protocolo TLS protege contra alguém espiando o cabo de rede, mas não protege contra um ataque de replay ou contra o vazamento do token em logs do servidor ou em um atacante que já tenha comprometido a rede interna.

No OAuth "vanilla", o token é um Bearer token. Ele funciona como dinheiro vivo: quem o apresenta, gasta. Se um malfeitor intercepta esse token — talvez através de uma vulnerabilidade no lado do cliente ou em um proxy mal configurado — ele pode reutilizá-lo para acessar dados bancários ou iniciar pagamentos. O regulamento brasileiro exige que o token não funcione apenas por estar presente. Ele precisa estar atrelado a algo que o atacante não tenha.

É aqui que o FAPI 1.0 entra com o conceito de Sender Constrained Access Tokens (Tokens Restritos ao Emissor). Em vez de confiar apenas na posse do token, a API valida se o cliente que está fazendo a chamada é o mesmo que o recebeu inicialmente.

Tokens são como cartões de crédito: o chip e a senha são essenciais

Pensar no token como uma senha única que nunca expira é o erro clássico. No perfil de segurança FAPI 1.0 exigido no Brasil, a proteção do token de acesso depende obrigatoriamente da ligação criptográfica entre o token e o cliente que o utiliza. Isso é geralmente implementado via MTLS (Mutual TLS).

A realidade técnica é dura: se você emite um token sem vincular o cnf (confirmation claim) ao certificado digital do cliente, você está falhando no básico. Quando o cliente faz uma requisição à API de dados ou de iniciação de pagamento, ele apresenta o certificado dele. O servidor extrai o thumbprint (impressão digital) desse certificado e compara com o valor armazenado dentro do token JWT.

Se os valores não batem, a requisição é rejeitada imediatamente, mesmo que o token seja válido e assinado corretamente. Isso impede que um token roubado de um aplicativo de conta corrente seja usado por um script malicioso em um servidor diferente. Em nosso último experimento de latência, percebemos que o overhead de validação desse certificado é ínfimo perto do prejuízo de uma fraude autorizada.

Detalhe fotográfico relacionado a FAPI 1.0 no Brasil: A blindagem obrigatória que o OAuth simples não oferece

Implementar FAPI é apenas uma configuração de "certificado digital" no Load Balancer?

Outra falácia comum é tratar a conformidade FAPI como uma tarefa de infraestrutura puramente, delegada para o time de DevOps configurar o NGINX ou o AWS ALB. Implementar FAPI 1.0 corretamente exige mudanças profundas na lógica da sua aplicação.

Muitos bancos emitem o certificado, configuram o TLS na porta 443 e acham que o trabalho está feito. O problema é que o seu código de aplicação, em Java, Node ou Go, precisa conseguir ler esse certificado. Se o seu Load Balancer termina a conexão TLS e repassa o tráfego para o backend apenas em HTTP (ou HTTPS com um certificado diferente), a aplicação perde a capacidade de validar a identidade do cliente original.

O backend precisa receber o certificado do cliente (geralmente via um cabeçalho HTTP como X-Client-Cert) ou ter a conexão encerrada diretamente nele. Sem isso, não há como validar a prova de posse. Se sua arquitetura usa terminação SSL na borda, você precisa garantir que o cabeçalho com o certificado original (toda a cadeia, não só o público) é passado adiante de forma segura e íntegra. Se alguém consegue falsificar esse cabeçalho interno, eles contornam toda a segurança do FAPI.

A complexidade do JAR (JWT Secured Authorization Request) é exagero burocrático?

Muitos desenvolvedores reclamam do passo de enviar os parâmetros de autorização dentro de um JWT assinado (o parâmetro request), em vez de apenas enviar query strings simples. Eles veem isso como mais processamento de criptografia desnecessário. Eu entendo a frustração — assinar JWT custa ciclos de CPU — mas essa camada é o que impede que um intermediário altere os intentos da transação.

Sem o JAR, um atacante poderia tentar modificar o parâmetro scope na requisição para o servidor de autorização, pedindo permissões que o usuário não aprovou (como pagamento ao invés de apenas leitura de saldo). Com o uso obrigatório do Request Object no FAPI, o cliente assina os parâmetros (client_id, redirect_uri, scope, state) antes de enviar. O servidor de autorização valida essa assinatura com a chave pública registrada no diretório (o Organização ou Software Statement Assertion).

Se um único bit da string de solicitação for alterado em trânsito, a assinatura quebra. No Brasil, onde o volume de transações Pix e consultas de Open Banking é bilionário, a integridade dessa solicitação inicial vale mais do que os 20 milissegundos a mais que você gera na assinatura.

Validar o cnf e o jti em cada requisição é opcional para performance

Vi um caso recente de uma fintech que desabilitou a validação completa do token JWT no gateway de API para "ganhar performance". Eles validavam apenas a expiração (exp) e a assinatura, mas ignoravam o jti (JWT ID) e a vinculação do certificado (cnf). O resultado? Eles não conseguiam detectar tokens que haviam sido revogados ou estavam sendo reutilizados de forma suspeita.

O FAPI 1.0 exige que o recurso (o servidor da API) mantenha um controle rigoroso. O jti deve ser único e, se você estiver implementando token binding via MTLS, a claim cnf contendo o x5t#S256 (o hash do certificado) é obrigatória.

Ignorar isso quebra o modelo de segurança. Se você recebe um token com um cnf que não bate com o certificado apresentado na conexão MTLS atual, a regra é simples: HTTP 401 Unauthorized. Não existe "aceitar por enquanto". Sistemas de KYT (Know Your Transaction) podem identificar padrões de fraude, mas se a porta da frente do OAuth foi deixada aberta por preguiça de implementação, o KYT estará apenas vendo o estrago acontecer, não prevenindo.

Conclusão

Fechar os olhos para a rigidez do FAPI 1.0 não é uma opção viável para quem opera no Brasil. O diferencial não é apenas passar no conformance test do diretório, mas garantir que, em um cenário de ataque real, seus tokens não sirvam para nada fora do contexto em que foram gerados.

O próximo passo lógico para qualquer arquiteto que está desenhando uma nova integração é revisar o fluxo de "Authorization Code" para garantir que o token de acesso está sendo emitido com a claim cnf preenchida e que sua API de recursos está efetivamente checando esse valor contra o certificado do cliente em todas as chamadas. Deixe de lado a desculpa de "latência" ou "complexidade"; em dinheiro e dados, a segurança do FAPI é o custo de entrada.

Leia em seguida