Reautenticação facial
Reautenticação facial
O módulo face_reauth reconfirma, numa ação sensível (um saque, uma troca de chave Pix, um login em aparelho novo), que quem age agora é a mesma pessoa que você já aprovou no onboarding. O titular faz a prova de vida e uma selfie, e o módulo compara essa selfie com a matrícula biométrica daquela conta, sem pedir documento e sem refazer o onboarding. É step-up sob evento, disparado pelo seu backend quando ele decide que a ação merece biometria, e nunca uma checagem contínua rodando em segundo plano.
create de flow o recusa até a abertura. A criação de sessão de reautenticação também ainda não está publicada. O que está descrito abaixo é o contrato de resposta que o backend já emite, para você planejar a integração, não uma porta que dá para chamar hoje.A matrícula é a referência, e ela é sua. Ela nasce de graça num onboarding aprovado: você marca o flow de onboarding para matricular, esse flow precisa ter face e liveness, e a matrícula é criada quando a verificação aprova pelo caminho automático, fora do sandbox e com o desafio de gestos cumprido. Aprovação manual na fila de revisão não matricula, e o sandbox também não: matrícula biométrica nasce de prova, nunca de decisão de operador. Existe uma matrícula ativa por conta (o seu reference_id), dentro da sua organização e do seu ambiente: não há base compartilhada entre clientes, e a comparação nunca acontece contra o índice de detecção de múltiplas contas, que serve a outra pergunta. Você paga a autenticação, nunca a matrícula.
O flow de reautenticação é curto de propósito: liveness mais face_reauth, sem documento. A prova de vida é exigida pelo catálogo, e o motivo é direto: sem ela, a foto impressa do titular bateria contra a matrícula e a reautenticação entregaria a conta. Pelo mesmo raciocínio, face_reauth não convive com face nem com doclink no mesmo flow: os dois comparam contra outra referência, e num flow sem documento o face nunca teria a foto do documento para comparar. Flow com reautenticação também desliga a renovação de sessão pelo widget: quem decide quando exigir biometria é o seu backend, não o navegador do titular.
// face_reauth no check_details: é a mesma pessoa da matrícula
{ "module": "face_reauth", "passed": true, "outcome": "approved", "score": 92,
"data": { "match": true, // a resposta: true | false | null (indeterminado)
"similarity": 0.83, // cosseno 0..1 contra a matrícula
"similarity_band": "high", // high | gray | low
"enrolled_at": "2026-03-02T18:20:11.000Z",
"enrollment_age_days": 159, // idade da matrícula, para a sua política
"model_version": "face-reauth-v1" } }
// face_reauth: a comparação foi MEDIDA e não bateu (portão duro: reprova)
{ "module": "face_reauth", "passed": false, "outcome": "failed", "score": 40,
"data": { "match": false, "similarity": 0.21, "similarity_band": "low",
"enrolled_at": "2026-03-02T18:20:11.000Z", "enrollment_age_days": 159,
"reason": "reauth_mismatch",
"model_version": "face-reauth-v1" } }
// face_reauth: banda de dúvida (o cosseno ficou entre os dois limiares). Revisão humana,
// nunca recusa automática, e SEM "reason": quem identifica o caso é a própria banda.
{ "module": "face_reauth", "passed": null, "outcome": "pending", "score": 80,
"data": { "match": null, "similarity": 0.39, "similarity_band": "gray",
"enrolled_at": "2026-03-02T18:20:11.000Z", "enrollment_age_days": 159,
"model_version": "face-reauth-v1" } }
// face_reauth: não havia matrícula utilizável (nunca houve, foi revogada ou venceu).
// Também revisão, e aqui o "reason" vem preenchido.
{ "module": "face_reauth", "passed": null, "outcome": "pending", "score": 80,
"data": { "match": null, "similarity": null, "similarity_band": null,
"enrolled_at": null, "enrollment_age_days": null,
"reason": "reauth_enrollment_unavailable",
"model_version": "face-reauth-v1" } }No resumo checks o módulo sai com o vocabulário da própria pergunta: "face_reauth": "match", "no_match" ou "pending". O pending cobre toda a família de revisão. Na banda de dúvida o reason não vem, e quem identifica o caso é o similarity_band igual a "gray"; nos demais casos de revisão o reason vem preenchido.
Os três caminhos de recusa por veredito, e só eles: a comparação medida abaixo do limiar (reauth_mismatch), o desafio de gestos executado por um rosto e a selfie enviada de outro (challenge_selfie_mismatch) e o documento que você mesmo pôs na sua lista de bloqueio (document_blocklisted). Todo o resto que dependa do titular é revisão, e essa escolha é deliberada: quem não tem matrícula, ou está com a matrícula vencida, não tem selfie nenhuma que possa tirar para fazer aparecer uma matrícula que não existe, e recusar seria punir o titular legítimo pela ausência de um dado nosso.
Existe ainda um quarto desfecho, e ele não é um veredito sobre a pessoa: quando a falha é nossa (a selfie não chegou, o serviço de visão não respondeu, a consulta à matrícula falhou), o módulo sai failed e sem o bloco data. Bloco ausente é a assinatura de erro interno, nunca de fraude: a leitura correta é repetir a autenticação, e jamais punir a conta por ela.
Os motivos que chegam a você em data.reason: reauth_mismatch (recusa medida), document_blocklisted (o documento estava na sua lista de bloqueio), challenge_selfie_mismatch (o vínculo entre desafio e selfie reprovou), reauth_binding_unavailable (não foi possível provar esse vínculo, que é diferente de tê-lo provado falso), reauth_enrollment_unavailable (sem matrícula utilizável, incluindo a vencida), reauth_locked (matrícula travada por tentativas seguidas que não bateram), reauth_rate_limited (teto de tentativas da conta estourado), reauth_capture_unusable (a captura não serviu) e reauth_embedder_drift (a matrícula foi feita com outra versão do extrator e comparar seria comparar espaços diferentes).
O reauth_rate_limited sai como 429 com o cabeçalho Retry-After, sempre em segundos e sempre um prazo real: é quando a vaga efetivamente abre para aquela conta, nunca um número fixo. Respeite o cabeçalho em vez de retentar em laço; a conta tem mais de um relógio, e quando mais de um está cheio o prazo devolvido já é o do relógio que libera por último. Esperar o que o cabeçalho diz basta: você não vai gastar uma chamada para descobrir que ainda falta outra espera.
reauth_locked como um evento de segurança. Ele significa tentativas seguidas contra a matrícula daquela conta, e travar a conta do seu lado é a única reação que encerra um ataque de força bruta de rosto. O titular, por outro lado, recebe sempre o mesmo motivo genérico: os códigos finos existem para o seu backend e para a sua fila de revisão, nunca para quem está do outro lado da câmera.A matrícula tem prazo, e ele é curto por escolha. Cada autenticação aprovada renova a guarda por 180 dias; quem passa 180 dias sem reautenticar perde a matrícula, que deixa de valer e entra na fila de expurgo, e existe um teto absoluto de um ano desde a criação. Passado o prazo, a próxima reautenticação sai como pending com reauth_enrollment_unavailable, e o caminho é refazer o onboarding, que cria uma matrícula nova.
No painel. A matrícula se liga no construtor de flow, na opção Criar matrícula para reautenticação facial, que só aparece habilitada quando o flow tem Face Match e Liveness (pela API, o campo é enroll_reauth, e o mesmo par de módulos é exigido, com o erro enroll_reauth_requires_face_liveness). O estado da matrícula de cada titular (ativa, travada, vencida ou ausente), com a data de criação e a validade, aparece no detalhe de qualquer verificação dele e na linha dele em Sessões. O painel mostra estado e datas, nunca o modelo do rosto.
Matrícula travada não se destrava. Um proprietário ou administrador da sua conta pode revogar a matrícula pelo painel, a partir da verificação ou da sessão do titular. A revogação pede o segundo fator de quem revoga e fica registrada com quem fez e quando. Depois dela, a matrícula renasce no próximo onboarding aprovado daquele titular. É também o que fazer quando você descobre que a conta foi tomada: tirar a matrícula até a pessoa provar de novo quem é.
Tenha sempre um caminho sem biometria. A reautenticação facial confirma que é a mesma pessoa, e não deve ser a única porta para a ação sensível: ofereça ao titular uma alternativa que não dependa do rosto dele. A aprovação com passkey, vinculada à conta do titular, é esse caminho no produto e está em breve.
Pronto para integrar? A chave de sandbox sai no painel, logo depois do cadastro. Criar conta grátis