Integração ONP em modo incorporado
Este documento descreve como incorporar a experiência de onboarding da Guardline diretamente na sua aplicação usando um iframe. O modo incorporado (embed) permite que seus usuários concluam a verificação de identidade sem sair da sua interface.
O modo incorporado e o modo de link direto compartilham o mesmo backend, o mesmo motor de decisão e os mesmos parceiros de verificação. As únicas diferenças são o ponto de entrada (src do iframe versus navegação em página completa) e a presença de um canal PostMessage para comunicação em tempo real com a página hospedeira. Para tudo o que não é específico do iframe, consulte a Referência da API ONP.
Esta página foca no que é específico da incorporação em iframe: atributos do iframe e permissões necessárias, a flag do modo incorporado (surface_hint=embed), eventos PostMessage, compatibilidade de navegadores e questões de segurança específicas de um contexto de iframe cross-origin.
Princípios de design
Seção intitulada “Princípios de design”Quatro princípios orientam a integração incorporada:
- Transparência para o cliente final: o onboarding deve parecer uma parte nativa da aplicação do integrador. O usuário não deve perceber que está interagindo com um sistema externo. A identidade visual (cores, logotipos, sobrescrita de textos) é totalmente configurável por fluxo e é gerenciada pelo backend da Guardline, não por parâmetros de URL ou código no cliente.
- Segurança por padrão: o iframe opera em um contexto cross-origin, ou seja, o site do integrador e o onboarding da Guardline rodam em domínios diferentes. Toda a comunicação entre os dois usa canais seguros: PostMessage com validação estrita de origem, webhooks com assinaturas HMAC-SHA256. Os tokens de sessão são efêmeros, criptograficamente seguros e vinculados a uma única execução.
- Backend como fonte da verdade: todas as informações persistentes (estado da sessão, dados coletados, resultados de verificação, configuração visual) ficam no backend da Guardline. O frontend do iframe não mantém estado que não possa ser reconstruído a partir do backend. Isso garante que as sessões possam ser retomadas mesmo que o iframe seja destruído e recriado.
- Mesma infraestrutura, dois pontos de entrada: o modo incorporado e o modo de link direto compartilham toda a stack. O frontend detecta automaticamente se está rodando dentro de um iframe e ativa o canal PostMessage de acordo. Nenhuma configuração separada é necessária.
Fluxo de integração
Seção intitulada “Fluxo de integração”O onboarding incorporado envolve quatro participantes que se comunicam em sequência: o backend do integrador, a API da Guardline, o frontend do integrador e o iframe da Guardline.
O processo começa quando o backend do integrador cria uma sessão. Ele chama POST /api/v1/onboarding/sessions com surface_hint: "embed" para habilitar a sanitização de PII no resolvedor. A API retorna o token, o ID da execução e a embed_url que o frontend do integrador usa como src do iframe.
O iframe carrega, resolve o token via GET /api/v1/link/{token} e recebe tudo o que precisa para renderizar o onboarding: configuração do fluxo, identidade visual e dados do cliente (sanitizados). O usuário navega pelas etapas; cada etapa concluída é persistida no backend. O iframe envia eventos PostMessage para a página hospedeira informando o progresso.
Quando a última etapa é concluída, o backend executa automaticamente o motor de decisão. O iframe comunica a conclusão à página hospedeira via PostMessage, e o backend dispara um webhook para o backend do integrador com o resultado.
Criação de sessão para o modo incorporado
Seção intitulada “Criação de sessão para o modo incorporado”A criação de sessão usa o mesmo endpoint POST /api/v1/onboarding/sessions do modo de link direto. Consulte Criação de sessão para o schema completo da requisição e o contrato de resposta.
A única diferença específica do modo incorporado é o campo surface_hint na requisição:
{ "flow_type": "kyc", "surface_hint": "embed", "primary": { "full_name": "Maria Santos", "tax_id": "12345678900" }}Quando surface_hint: "embed" é definido:
- A sessão é marcada como modo incorporado no momento da criação.
GET /api/v1/link/{token}retorna um payload sanitizado que remove os campos de PII que o iframe não deve exibir (CPF, email, phone, birth_date, URLs do representante).- A flag é interna ao servidor e não é devolvida em nenhuma resposta. Os integradores observam seu efeito pelo formato sanitizado da resposta do resolvedor.
Para o comportamento completo de sanitização, consulte Comportamento da sanitização de PII na referência da API.
O campo embed_url na resposta da sessão é a URL canônica a ser montada no iframe. Ele aponta para a mesma execução que url (o ponto de entrada do link direto). As duas URLs resolvem pelo mesmo endpoint GET /api/v1/link/{token} no servidor; a diferença é em qual shell de frontend o usuário chega.
Para autenticação (X-API-Key), idempotência (Idempotency-Key), respostas de erro e o schema completo de requisição e resposta, consulte a Referência da API ONP.
Incorporação do iframe
Seção intitulada “Incorporação do iframe”O frontend do integrador incorpora o onboarding montando um elemento iframe que aponta para a embed_url retornada pelo endpoint de criação de sessão.
A embed_url é retornada sem query string e, nesse formato, não emite nenhum evento PostMessage. A ponte de PostMessage permanece inerte até que o iframe receba uma origem pai válida, que ele lê de um parâmetro de query origin na própria URL. Acrescente ?origin=<origem da sua página> à embed_url antes de montá-la, em que a origem é o esquema, o host e a porta exatos da página que hospeda o iframe (por exemplo, https://app.acme.com ou https://app.acme.com:8443 quando uma porta não padrão é usada). Na ausência do parâmetro, o iframe recorre ao referrer do documento, o que não é confiável e é suprimido pelas políticas de referrer mais comuns. Defina o parâmetro explicitamente. A origem também precisa estar presente nas origens permitidas configuradas para a sua instância.
Atributos obrigatórios
Seção intitulada “Atributos obrigatórios”O iframe exige declarações explícitas de permissão para funcionar corretamente. Sem elas, o navegador bloqueia silenciosamente o acesso à câmera e aos sensores de movimento, e o onboarding não consegue avançar além da verificação biométrica.
| Atributo | Valor | Finalidade |
|---|---|---|
src | embed_url da resposta de criação de sessão, com ?origin= acrescentado | Aponta para o onboarding da Guardline desta sessão. O parâmetro origin é obrigatório: sem ele, o iframe não emite nenhum evento PostMessage. |
allow | camera; geolocation; accelerometer; gyroscope; magnetometer | A câmera é necessária para a captura de documentos e a verificação biométrica. Os sensores de movimento são necessários em dispositivos móveis para a prova de vida (liveness). A geolocalização permite que a tela de termos registre o local do aceite como evidência de consentimento; o usuário final pode recusar o pedido do navegador sem que isso bloqueie a jornada. |
width | 100% | O layout do onboarding é responsivo e se adapta à largura do contêiner. |
height | 100% da viewport ou valor fixo (mínimo de 600px) | O layout foi desenhado para ocupar toda a altura do contêiner. |
Atributos a evitar
Seção intitulada “Atributos a evitar”O atributo sandbox não deve ser usado. Ele restringe recursos do iframe (formulários, scripts, popups, acesso à câmera) de formas que tornam o onboarding inoperante.
Dimensionamento
Seção intitulada “Dimensionamento”A altura do iframe deve ser definida pelo integrador com um valor fixo, normalmente 100% da viewport. O layout do onboarding foi desenhado para preencher todo o contêiner.
O redimensionamento automático da altura com base no conteúdo está disponível pelo evento PostMessage height-changed. O iframe informa a altura do seu conteúdo conforme ela muda, com throttle a um intervalo mínimo de 200 ms, de modo que a página hospedeira recebe no máximo cinco atualizações de altura por segundo e deve tratar cada valor como a última altura conhecida, e não como um fluxo contínuo. A página hospedeira pode ajustar o elemento iframe de acordo. Essa abordagem é opcional e funciona melhor em layouts em que o iframe não ocupa a viewport inteira.
Exemplo
Seção intitulada “Exemplo”<iframe src="https://acme.onp.prod.guardline.com.br/embed/t/abc123def456?origin=https://app.acme.com" allow="camera; geolocation; accelerometer; gyroscope; magnetometer" width="100%" height="100vh" style="border: none;"></iframe>Token na URL: mitigações de vazamento
Seção intitulada “Token na URL: mitigações de vazamento”O token de sessão está presente no caminho da URL do iframe. Esse é um trade-off deliberado: permite a incorporação sem estado, sem exigir que a página hospedeira injete credenciais via PostMessage antes que o iframe possa inicializar. As mitigações a seguir limitam a superfície de exposição:
| Vetor de vazamento | Mitigação |
|---|---|
| Cabeçalho Referer | O documento incorporado não define Referrer-Policy, portanto vale o padrão do navegador. Os navegadores atuais adotam strict-origin-when-cross-origin por padrão; sob essa política, as requisições de saída do iframe (para parceiros de verificação, CDNs) enviam apenas a origem (https://acme.onp.prod.guardline.com.br) e nunca o caminho completo que contém o token. Um navegador configurado com uma política mais permissiva enviaria mais. |
| Histórico do navegador | A URL com o token é carregada dentro de um iframe, não na barra de navegação de nível superior. As navegações do iframe não são registradas na barra de endereços nem no histórico do navegador. |
| Analytics e scripts de terceiros | O frontend do onboarding não inclui scripts genéricos de analytics de terceiros. Os SDKs dos parceiros são carregados apenas para fins de verificação, e a Guardline não repassa valores de token como identificadores de analytics. |
| Logs do integrador | O integrador deve tratar os campos embed_url e token da resposta de criação de sessão como dados sensíveis. Evite registrar esses valores em texto puro. O execution_id é o identificador seguro para logs e correlação. |
Configuração visual
Seção intitulada “Configuração visual”A identidade visual do onboarding é totalmente dinâmica e gerenciada pelo backend da Guardline. Nenhum parâmetro visual é passado via URL, query strings ou código no cliente.
Quando o iframe resolve o token de sessão, o backend retorna a configuração visual completa associada ao fluxo:
| Configuração | Descrição |
|---|---|
| Cores primária e secundária | Nas variantes escura e clara, usadas em botões, destaques e elementos interativos. |
| URLs dos logotipos | Hospedadas em CDN, em versões para fundos escuros e claros. |
| Modo de tema | Escuro, claro ou automático (segue a preferência do sistema do usuário). |
| Estilo dos botões | Cores de fundo, de texto e de ícone por tema. |
| Sobrescritas por etapa | Etapas individuais podem sobrescrever as cores base e as configurações de layout. |
O frontend aplica essas configurações como CSS custom properties no momento da renderização. Alterar a identidade visual não exige mudanças de código nem um novo deploy: atualize as configurações no painel administrativo da Guardline ou via API, e a próxima sessão refletirá a nova configuração.
Esse design garante consistência visual entre o modo de link direto e o modo incorporado. Ambos usam a mesma fonte de configuração (o backend), portanto o integrador não precisa sincronizar parâmetros visuais entre vários pontos de integração.
Eventos PostMessage
Seção intitulada “Eventos PostMessage”O iframe e a página hospedeira se comunicam exclusivamente via PostMessage, o mecanismo nativo do navegador para comunicação entre janelas cross-origin. Toda mensagem enviada pelo iframe carrega um identificador source que permite à página hospedeira filtrar as mensagens relevantes.
Estrutura da mensagem
Seção intitulada “Estrutura da mensagem”Todas as mensagens seguem este formato:
{ "source": "<slug>-onboarding", "event": "event-name", "payload": {}}O campo source é <slug>-onboarding, em que <slug> é o identificador de cliente da sua instância Guardline. O valor é fixo para uma dada instância, mas varia entre instâncias, ou seja, não é a mesma string para todos os integradores. Confirme o valor exato da sua instância com a equipe da Guardline durante a configuração inicial e filtre por esse valor. Um listener que filtra por um identificador genérico fixo no código descarta todos os eventos em uma instância que define o próprio slug.
Referência de eventos
Seção intitulada “Referência de eventos”Emitido quando o iframe é montado e está pronto para exibir a primeira etapa. Nas rotas com token, ele é emitido duas vezes: uma na montagem, antes de o token de sessão ser resolvido, e outra depois da resolução.
| Campo do payload | Tipo | Descrição |
|---|---|---|
executionId | UUID | O identificador da execução desta sessão de onboarding. Use-o para correlacionar a sessão incorporada com os seus registros internos. Normalmente ausente no primeiro ready, que ocorre antes de a sessão ser resolvida, e presente no segundo. |
A página hospedeira pode usar esse evento para ocultar um indicador de carregamento e exibir o iframe. Trate-o de forma idempotente: uma página hospedeira que exibe o iframe no ready executa essa lógica duas vezes, e uma página hospedeira que lê executionId no ready precisa tolerar a ausência do campo na primeira vez.
step-changed
Seção intitulada “step-changed”Emitido cada vez que o usuário avança para a próxima etapa ou volta para a anterior.
| Campo do payload | Tipo | Descrição |
|---|---|---|
executionId | UUID | O identificador da execução. |
stepId | string | O identificador da etapa atual (por exemplo, document-front, biometric-iproov). |
stepIndex | integer | Índice da etapa atual no fluxo, começando em zero. |
totalSteps | integer | Número total de etapas do fluxo. |
O conjunto de códigos de etapa é específico de cada fluxo e de cada país, portanto os códigos acima são exemplos e não uma lista fixa. Confirme os códigos do seu fluxo com a equipe da Guardline antes de ramificar por stepId e não fixe no código um switch baseado nos exemplos deste documento.
A página hospedeira pode usar esse evento para exibir um indicador de progresso externo, registrar analytics ou ajustar a interface ao redor.
completed
Seção intitulada “completed”Emitido quando o usuário enviou todas as etapas obrigatórias. Esse evento sinaliza que a parte do usuário na jornada terminou, não que uma decisão final foi tomada. O campo decision fornece uma indicação imediata do resultado, mas o webhook é a fonte autoritativa para o resultado final da decisão.
| Campo do payload | Tipo | Descrição |
|---|---|---|
executionId | UUID | O identificador da execução. |
decision | string | Indicação imediata da decisão: approved, rejected, in_review ou unconfirmed. Quando é in_review, a execução foi encaminhada para um analista humano e o resultado final chegará exclusivamente via webhook (onboarding.approved ou onboarding.rejected). Quando é unconfirmed, o frontend não conseguiu confirmar o veredito do backend; a jornada terminou, mas o resultado é desconhecido para o iframe. |
Tratamento típico no frontend conforme o valor de decision:
decision | UX sugerida |
|---|---|
approved | Feche o iframe e exiba uma confirmação de sucesso. |
rejected | Feche o iframe e exiba uma mensagem apropriada ou redirecione para um fluxo de atendimento. |
in_review | Feche o iframe e informe ao usuário que a verificação está em análise e que ele será notificado. O backend do integrador receberá o resultado final via webhook. |
unconfirmed | Feche o iframe, mas não apresente um resultado final ao usuário. A jornada terminou e o resultado não está confirmado. Trate o webhook como autoritativo e informe o usuário quando ele chegar. |
blocked
Seção intitulada “blocked”Emitido quando o fluxo é interrompido por motivos de segurança.
| Campo do payload | Tipo | Descrição |
|---|---|---|
executionId | UUID | O identificador da execução. |
reason | string | O motivo do bloqueio: fraud_detected, invalid_data, max_attempts_exceeded, identity_mismatch. |
A página hospedeira pode exibir uma mensagem de atendimento ou oferecer canais alternativos.
Emitido quando um erro técnico impede o avanço.
| Campo do payload | Tipo | Descrição |
|---|---|---|
code | string | Um código de erro padronizado (consulte Códigos de erro do PostMessage). |
message | string | Uma descrição legível do erro. |
status | integer | Presente apenas quando o erro se originou de uma resposta HTTP. O código de status HTTP dessa resposta. |
Esse evento não carrega um executionId. Correlacione-o com a execução que o seu backend criou para a sessão ou com o executionId recebido no evento ready já resolvido.
height-changed
Seção intitulada “height-changed”Emitido quando a altura do conteúdo do iframe muda, com throttle a um intervalo mínimo de 200 ms (no máximo cinco atualizações por segundo). Isso é útil em layouts em que o iframe não está definido como 100% da viewport.
| Campo do payload | Tipo | Descrição |
|---|---|---|
height | integer | A altura do conteúdo em pixels. |
Os dois eventos a seguir também são emitidos pelo iframe.
retry: emitido quando o usuário aciona o botão de nova tentativa na tela de erro. A página hospedeira pode usá-lo para limpar qualquer estado de erro que ela tenha exibido ao redor em resposta a um evento error anterior, antes de o iframe tentar novamente a operação que falhou.
dismissed: emitido quando o usuário fecha uma tela terminal, ou seja, quando o próprio usuário dispensa a tela final da jornada, em vez de a página hospedeira fechá-la. Esse é o sinal necessário para que a página hospedeira feche o próprio modal ou overlay em uma saída conduzida pelo usuário. Uma página hospedeira que fecha apenas no completed deixa um contêiner vazio na tela depois que o usuário dispensa a tela terminal.
| Campo do payload | Tipo | Descrição |
|---|---|---|
state | string | A tela terminal que o usuário dispensou: review, approved, rejected ou unconfirmed. |
Validação de origem
Seção intitulada “Validação de origem”O PostMessage é um canal aberto por natureza: qualquer janela pode enviar mensagens para qualquer outra. A segurança depende de validação rigorosa nos dois lados.
Do lado do iframe, a entrega não é difundida para uma lista de domínios. O iframe resolve exatamente uma origem de destino, obtida do parâmetro de query origin da própria URL ou do referrer do documento quando esse parâmetro está ausente. Ele valida se essa origem consta na lista de origens permitidas configurada para a instância do integrador e então envia todas as mensagens para essa única origem. As mensagens enviadas com uma origem restrita são rejeitadas pelo navegador se o destinatário estiver em um domínio diferente.
Uma origem em HTTP puro é rejeitada, a menos que seja localhost. Portanto, um host de homologação servido por HTTP não recebe mensagem nenhuma, e isso acontece de forma silenciosa: o iframe é renderizado e a jornada funciona, mas nenhum evento PostMessage chega à página hospedeira. Sirva os hosts de homologação por HTTPS ou teste contra localhost.
Do lado do integrador, a página hospedeira deve comparar a propriedade origin de cada mensagem recebida com o domínio exato da instância Guardline. A validação por substring ou por regex é insegura (um domínio como guardline.com.br.attacker.com passaria em validações ingênuas). Deve-se usar apenas a igualdade exata de domínio.
Comunicação da página hospedeira para o iframe
Seção intitulada “Comunicação da página hospedeira para o iframe”Na versão atual, a página hospedeira não precisa enviar comandos ao iframe. O onboarding é autônomo depois de iniciado: o usuário navega pelas etapas e o iframe gerencia todo o estado internamente.
Versões futuras darão suporte a comandos como reiniciar o fluxo programaticamente ou encerrar a sessão.
Retomada de sessão
Seção intitulada “Retomada de sessão”O onboarding pode ser interrompido por muitos motivos: o usuário fecha o navegador, perde a conectividade, navega para outra página ou a página hospedeira destrói e recria o iframe. Em todos esses casos, o usuário pode retomar de onde parou acessando o mesmo token.
A retomada funciona porque o backend persiste o estado de cada etapa individualmente. Quando o iframe carrega com um token, ele consulta o backend para obter o estado da execução. Se a execução estiver em andamento, o frontend identifica a primeira etapa pendente e posiciona o usuário nela. A posição da etapa é retomada corretamente, mas o conteúdo dos campos não: no modo incorporado, o backend remove da resposta do resolvedor os dados de exibição de cada etapa e os campos de pré-preenchimento, portanto os valores informados anteriormente não são repreenchidos no formulário.
Essa abordagem é crítica no contexto do iframe. O sessionStorage do navegador é isolado por origem em iframes cross-origin. Se a página hospedeira destruir o iframe e recriá-lo (por exemplo, porque o usuário saiu da página e voltou), todo o sessionStorage é perdido. O backend como fonte da verdade garante que a sessão sobreviva a qualquer cenário de destruição do iframe.
Se o token estiver expirado, se a execução estiver em um estado terminal ou se o token for inválido, o iframe exibe uma tela informativa adequada ao cenário e não tenta iniciar um novo fluxo.
Para o ciclo de vida completo da execução e a semântica dos estados, consulte Ciclo de vida da execução na referência da API.
Contrato de sessão e webhooks
Seção intitulada “Contrato de sessão e webhooks”O contrato de tudo o que não é específico do iframe está na Referência da API ONP:
- Autenticação e idempotência
- Jornadas disponíveis
- Criação de sessão
- Sujeitos vinculados (para
kyc_minore futuros fluxoskybde representantes) - Opt-in de notificações
- Resolução do link (o endpoint que o iframe chama no servidor)
- Reenvio do link do representante
- Ciclo de vida da execução
- Consulta de uma execução
- Webhooks (taxonomia de eventos, payload, modos de autenticação, política de retentativas)
- Polling de notificações
- Referência de erros (códigos de status HTTP e códigos de erro de domínio)
- Resumo dos endpoints
As orientações específicas do modo incorporado a seguir se aplicam sobre esses contratos.
Segurança
Seção intitulada “Segurança”Isolamento de instâncias
Seção intitulada “Isolamento de instâncias”A arquitetura da Guardline é single-tenant. Cada integrador recebe instâncias dedicadas de backend, banco de dados e frontend. Não há compartilhamento de dados nem de código de aplicação entre instâncias. A infraestrutura subjacente (cluster Kubernetes, rede, observabilidade) é compartilhada, mas o isolamento lógico é aplicado em todas as camadas: bancos de dados separados, processos de aplicação separados, armazenamento separado e credenciais separadas. O iframe de um integrador não tem acesso aos dados de outro integrador, nem mesmo de forma indireta.
Cabeçalhos de segurança HTTP
Seção intitulada “Cabeçalhos de segurança HTTP”O documento incorporado é um build estático servido por nginx. O único cabeçalho de segurança que ele define é X-Content-Type-Options: nosniff. Ele não inclui a diretiva frame-ancestors do Content Security Policy, nem X-Frame-Options, nem Permissions-Policy, nem Referrer-Policy. Não confie nos cabeçalhos de resposta do documento incorporado para restringir a incorporação em frames e não espere que um Permissions-Policy conceda acesso aos sensores: o acesso à câmera e aos sensores de movimento dentro do iframe é concedido pelo atributo allow que o integrador define no elemento iframe.
Restringir quais páginas podem incorporar o onboarding em um frame é um item de configuração inicial, não um cabeçalho de resposta. As origens pai permitidas são configuradas por instância pela equipe da Guardline e são aplicadas pela verificação de origem do PostMessage descrita na seção Validação de origem: o iframe envia mensagens apenas para uma origem que esteja presente nessa lista. Mudanças na lista exigem coordenação com a equipe Guardline.
Cookies cross-origin
Seção intitulada “Cookies cross-origin”A jornada de onboarding não se autentica com cookies. A credencial da jornada é o cabeçalho de requisição X-Journey-Token, combinado com o token do link presente no caminho da URL. Nenhum cookie de jornada é definido, portanto a política de cookies de terceiros do navegador não tem efeito sobre a jornada em si, e nenhuma configuração de domínio próprio ou de cookies é necessária do lado do integrador para que o onboarding funcione em um iframe cross-origin.
As restrições a cookies de terceiros continuam relevantes para o parceiro de device profiling, o que é uma questão separada. Consulte Device profiling (Nethone) no Apêndice A.
Proteção contra ataques
Seção intitulada “Proteção contra ataques”| Vetor de ataque | Mitigação |
|---|---|
| Clickjacking | O documento incorporado não define nenhum cabeçalho de framing, portanto a incorporação em frames não é bloqueada no nível do navegador. Uma página que incorpora o onboarding sem estar nas origens permitidas da instância não recebe nenhum evento PostMessage, o que impede que uma página disfarçada conduza o fluxo do lado da página hospedeira. |
| Replay de token | Os tokens são vinculados a uma única execução e têm tempo limitado (validade do link de 7 dias, janela de sessão ativa de 24 horas). Um token capturado dá acesso apenas à execução para a qual foi criado. |
| XSS via PostMessage | Validação de origem nos dois lados. O iframe envia mensagens apenas para a origem configurada; a página hospedeira deve validar a origem de cada mensagem recebida. |
| Replay de webhook | Assinatura HMAC com timestamp sobre o corpo, que carrega o event_id do evento. O endpoint do integrador deveria rejeitar webhooks com mais de 5 minutos e fazer a deduplicação pelo event_id do corpo assinado, não pelo cabeçalho. |
| Enumeração de tokens | Os tokens são valores hexadecimais de 32 caracteres gerados por uma fonte criptograficamente segura (128 bits de entropia). A enumeração por força bruta é computacionalmente inviável. |
| Man-in-the-middle | HTTPS (TLS 1.2+) é obrigatório em toda a comunicação de rede: chamadas de API, carregamento do iframe e entrega de webhooks. O PostMessage é um mecanismo interno do navegador entre janelas do mesmo user agent e não trafega pela rede, portanto não é suscetível a interceptação em nível de rede. |
Compatibilidade de navegadores
Seção intitulada “Compatibilidade de navegadores”O onboarding incorporado é suportado em todos os navegadores modernos. A câmera em iframes cross-origin é suportada a partir do Chrome 64+, Firefox 90+, Safari 15+ e Edge 79+. O suporte em dispositivos móveis inclui Chrome (Android) 64+ e Safari (iOS) 15+.
O iframe requer os seguintes atributos allow: camera (obrigatório em todas as plataformas), accelerometer, gyroscope e magnetometer (obrigatórios em dispositivos móveis para a detecção biométrica de prova de vida (liveness)). Sem camera, o onboarding não consegue avançar além das etapas de documento ou biometria. Sem os sensores de movimento, o parceiro biométrico pode operar em modo degradado em dispositivos móveis.
Para matrizes detalhadas de compatibilidade de navegadores, notas sobre dispositivos legados (iOS 14) e comportamento de provedores externos, consulte o Apêndice A: detalhes de compatibilidade de navegadores.
Códigos de erro do PostMessage
Seção intitulada “Códigos de erro do PostMessage”Os códigos de erro a seguir podem ser emitidos pelo evento error do PostMessage. Eles representam condições técnicas que impedem o onboarding de avançar dentro do iframe. Para os códigos de erro de nível HTTP retornados pela API, consulte a Referência de erros na referência da API.
| Código | Descrição | Ação sugerida |
|---|---|---|
camera_denied | O usuário negou o acesso à câmera quando solicitado pelo navegador. | Exiba uma mensagem explicando que o acesso à câmera é obrigatório e oriente o usuário a conceder a permissão nas configurações do navegador. |
camera_not_found | Nenhuma câmera foi detectada no dispositivo. | Exiba uma mensagem sugerindo que o usuário troque para um dispositivo com câmera. |
camera_play_failed | O stream da câmera foi obtido, mas a reprodução no elemento de vídeo não conseguiu iniciar. | Exiba uma mensagem de erro e permita que o usuário tente a etapa novamente. Se o problema persistir, sugira fechar outros aplicativos ou abas que possam estar ocupando a câmera. |
device_unsupported | O dispositivo ou o navegador não suporta um recurso exigido pela etapa atual. | Exiba uma mensagem sugerindo que o usuário troque para um navegador ou dispositivo suportado. Consulte o Apêndice A: detalhes de compatibilidade de navegadores. |
permission_not_granted | O iframe não tem o atributo allow necessário para a câmera. Esse é um erro de configuração do lado do integrador. | Verifique se o elemento iframe inclui allow="camera". |
api_unavailable | A API da Guardline está inacessível. | Exiba uma mensagem de erro genérica e sugira uma nova tentativa. Se o problema persistir, entre em contato com o suporte da Guardline. |
sdk_load_failed | O SDK de verificação biométrica falhou ao carregar (problema de rede ou falha de CDN). | Exiba uma mensagem de erro e sugira uma nova tentativa. O usuário pode tentar a etapa novamente. |
load_error | Um recurso exigido pela etapa atual falhou ao carregar. | Exiba uma mensagem de erro e permita que o usuário tente a etapa novamente. |
token_invalid | O token de sessão está malformado ou não existe. | Exiba uma mensagem informando ao usuário que o link é inválido. O integrador deve gerar uma nova sessão. |
token_expired | O token de sessão expirou. | Exiba uma mensagem informando ao usuário que o link expirou. O integrador deve gerar uma nova sessão. |
session_completed | A execução associada a esse token já está no status rejected. Esse código não é emitido para outras decisões finais. | Exiba uma mensagem informando ao usuário que o onboarding já foi finalizado. |
session_cancelled | A sessão foi cancelada antes da conclusão da jornada. | Exiba uma mensagem informando ao usuário que a sessão não está mais ativa. O integrador deve gerar uma nova sessão se o usuário precisar tentar de novo. |
session_blocked | A sessão foi bloqueada por motivos de segurança. | Exiba uma mensagem e direcione o usuário aos canais de suporte. |
Solução de problemas
Seção intitulada “Solução de problemas”| Sintoma | Causa | Solução |
|---|---|---|
| Eventos PostMessage não recebidos | Falta o ?origin= na URL do iframe, a página hospedeira filtra pelo valor de source errado, ou a origem permitida está mal configurada. | Confirme que a embed_url carrega ?origin= com a origem exata da sua página. Verifique se o listener de eventos filtra pelo valor de source da sua instância (<slug>-onboarding). Confirme que as origens permitidas correspondem à origem exata da sua página hospedeira (protocolo + domínio + porta). |
| A câmera não funciona no iframe | O elemento iframe não tem allow="camera". | Adicione allow="camera" ao iframe. Em dispositivos móveis, inclua também accelerometer; gyroscope; magnetometer. |
| A biometria falha em dispositivos móveis | Permissões de sensores de movimento não declaradas no iframe. | Adicione accelerometer; gyroscope; magnetometer ao atributo allow do iframe. |
| O aceite dos termos é sempre registrado sem localização | O elemento iframe não tem allow="geolocation", então o navegador nega o pedido sem exibir o prompt. | Adicione geolocation ao atributo allow do iframe. A jornada nunca é bloqueada por isso: uma localização recusada ou indisponível é registrada como tal na evidência de consentimento. |
| O usuário perde o progresso após sair da página | A página hospedeira destruiu e recriou o iframe, perdendo o sessionStorage. | Comportamento esperado. O backend persiste todos os dados das etapas. A sessão é retomada automaticamente a partir da última etapa concluída com o mesmo token. |
| Webhooks não chegam | Endpoint inacessível, retornando status diferente de 2xx, ou verificação de assinatura rejeitando payloads válidos. | Verifique a acessibilidade do endpoint via HTTPS. Consulte os logs no painel administrativo da Guardline. Confirme que a assinatura é calculada sobre timestamp + "." + body. |
Fluxo de dados e privacidade
Seção intitulada “Fluxo de dados e privacidade”Os dados principais do onboarding (nome, CPF, dados de contato, metadados do documento e imagens do documento) são armazenados nos sistemas da Guardline e criptografados em repouso. As capturas biométricas são processadas pela iProov e não são retidas pela Guardline. Os device fingerprints são processados pela Nethone e não são retidos pela Guardline. O integrador é o controlador de dados sob a LGPD; a Guardline atua como operador de dados. Prazos de retenção, base legal e termos do DPA são definidos por contrato.
Para o diagrama completo de residência de dados, a tabela de retenção e a matriz de responsabilidades de compliance, consulte o Apêndice B: detalhes de fluxo de dados e compliance.
Desempenho
Seção intitulada “Desempenho”Um fluxo KYC típico com 6 etapas é concluído em 3-5 minutos de interação do usuário. As operações de backend (resolução do token, envio de etapa, motor de decisão) levam menos de um segundo. A etapa de verificação biométrica (5-15s) é a mais variável, dependendo da latência de rede até os servidores da iProov e do hardware de câmera do dispositivo.
Esses números são referência de engenharia, não compromissos de SLA. Os SLAs de desempenho são definidos por contrato. Para métricas P95 detalhadas com o contexto de medição, consulte o Apêndice C: detalhes de desempenho.
Checklist de integração
Seção intitulada “Checklist de integração”Use este checklist para validar sua integração com iframe antes de entrar em produção.
Integração de backend
Seção intitulada “Integração de backend”- O endpoint de criação de sessão inclui
surface_hint: "embed"para sessões renderizadas em iframe. - O endpoint de webhook está implementado, acessível via HTTPS e responde com 2xx.
- A verificação da assinatura do webhook está implementada usando o segredo compartilhado.
- A idempotência dos webhooks está implementada usando o
event_iddo corpo assinado, comexecution_id+event_sequencecomo alternativa quando a entrega não o traz; o cabeçalhoX-Guardline-Event-IDcontinua chegando com o mesmo valor, mas não é coberto pela assinatura. - A validação de timestamp do webhook rejeita eventos com mais de 5 minutos.
- O polling de status da sessão está implementado como fallback para webhooks não recebidos.
- A API key é armazenada com segurança (variável de ambiente, secret manager), não no código-fonte.
Integração de frontend
Seção intitulada “Integração de frontend”- O
srcdo iframe é aembed_urlcom?origin=acrescentado, carregando a origem exata da página hospedeira (esquema + host + porta). Sem isso, nenhum evento PostMessage é emitido. - O elemento iframe inclui
allow="camera; geolocation; accelerometer; gyroscope; magnetometer". - O iframe não inclui o atributo
sandbox. - O listener de PostMessage filtra pelo valor de
sourceda sua instância (<slug>-onboarding), confirmado com a equipe da Guardline durante a configuração inicial. - A validação de origem do PostMessage verifica o domínio exato da Guardline (sem correspondência por substring ou regex).
- O evento
readyé tratado (ocultar o indicador de carregamento, exibir o iframe). - O evento
completedé tratado com ramificação pelo valor dedecision:approved(confirmação),rejected(mensagem adequada),in_review(informar o usuário sobre a revisão pendente),unconfirmed(nenhum resultado final exibido, aguardar o webhook). - O evento
erroré tratado (exibir mensagem amigável ao usuário). - O evento
blockedé tratado (exibir informações de suporte).
- O fluxo de onboarding ponta a ponta funciona no Chrome, Safari e Firefox (desktop).
- O fluxo de onboarding ponta a ponta funciona no Chrome (Android) e no Safari (iOS 15+).
- O acesso à câmera funciona dentro do iframe em todos os navegadores alvo.
- A verificação biométrica é concluída com sucesso dentro do iframe.
- A retomada de sessão funciona: destrua o iframe, recrie-o com o mesmo token e verifique se o fluxo é retomado a partir da etapa correta.
- Um token expirado exibe a tela informativa adequada.
- Um token inválido exibe a tela informativa adequada.
- A entrega do webhook é confirmada no painel administrativo da Guardline.
- A verificação da assinatura do webhook rejeita corretamente payloads adulterados.
Ambiente
Seção intitulada “Ambiente”- As origens permitidas estão configuradas para o(s) seu(s) domínio(s) de produção (obrigatório para a validação de origem do PostMessage).
- Os certificados SSL são válidos e não expiram em breve.
- A API key do ambiente de produção está provisionada e armazenada com segurança.
- O segredo compartilhado do webhook está armazenado com segurança.
Para acesso ao sandbox e suporte a testes, entre em contato com a equipe técnica da Guardline.
Apêndice A: detalhes de compatibilidade de navegadores
Seção intitulada “Apêndice A: detalhes de compatibilidade de navegadores”As versões de navegador, as estatísticas de dispositivos, as versões de SDK e os timeouts dos parceiros citados neste apêndice são informados pelos fabricantes dos navegadores, pela plataforma e pelos parceiros de verificação. O produto não faz detecção de recursos (feature detection) nem verifica nenhum desses valores em tempo de execução, portanto trate-os como orientação dos fornecedores, e não como comportamento garantido pelo onboarding.
Navegadores desktop
Seção intitulada “Navegadores desktop”| Navegador | Versão mínima | Câmera no iframe | Observações |
|---|---|---|---|
| Chrome | 64+ (2018) | Sim | Suporte completo a Permissions Policy e ao acesso à câmera em iframes cross-origin. |
| Firefox | 90+ (2021) | Sim | Suporte completo. O Enhanced Tracking Protection pode afetar o device profiling da Nethone. |
| Safari | 15+ (2021) | Sim | Suporte completo. O Intelligent Tracking Prevention pode afetar o device profiling da Nethone. |
| Edge | 79+ (2020) | Sim | Baseado em Chromium. Mesmo comportamento do Chrome. |
Navegadores móveis
Seção intitulada “Navegadores móveis”| Navegador | Versão mínima | Câmera no iframe | Observações |
|---|---|---|---|
| Chrome (Android) | 64+ | Sim | Suporte completo. |
| Safari (iOS) | 15+ | Sim | Suporte completo à câmera em iframes cross-origin. |
| Safari (iOS) | 14 e anteriores | Não | Não suporta câmera em iframes cross-origin. O parceiro biométrico oferece um padrão de ponte que abre a captura em uma nova aba e retorna o resultado via PostMessage. Essas versões representam menos de 5% dos dispositivos iOS ativos e estão em queda. |
| Samsung Internet | 12+ | Sim | Baseado em Chromium. Mesmo comportamento do Chrome. |
Detalhes das permissões do iframe
Seção intitulada “Detalhes das permissões do iframe”| Permissão | Obrigatória | Finalidade | Impacto se ausente |
|---|---|---|---|
camera | Sim | Captura de documento e verificação biométrica. | O onboarding não consegue avançar além das etapas de documento ou biometria. O iframe exibe uma mensagem de erro. |
accelerometer | Somente em dispositivos móveis | Detecção de prova de vida em dispositivos móveis. | O parceiro biométrico pode operar em modo degradado (sem detecção de movimento) ou falhar em alguns dispositivos. |
gyroscope | Somente em dispositivos móveis | Detecção de prova de vida em dispositivos móveis. | O mesmo que accelerometer. |
magnetometer | Somente em dispositivos móveis | Detecção de prova de vida em dispositivos móveis. | O mesmo que accelerometer. |
Verificação biométrica (iProov)
Seção intitulada “Verificação biométrica (iProov)”O iProov Web SDK (versão 5.4.3+) suporta operação dentro de iframes. O SDK se comunica com os servidores da iProov usando seus próprios tokens obtidos do backend da Guardline e não depende de cookies de terceiros nem de armazenamento compartilhado.
Em dispositivos móveis, a iProov usa sensores de movimento para a detecção de prova de vida (verificando que o dispositivo está sendo segurado por uma pessoa real). O iframe precisa declarar as permissões de accelerometer, gyroscope e magnetometer. Sem essas declarações, a iProov pode operar em modo degradado (sem detecção de movimento) ou falhar.
Device profiling (Nethone)
Seção intitulada “Device profiling (Nethone)”A Nethone coleta informações do dispositivo (fingerprint, padrões de digitação, sinais de fraude) usando um agente JavaScript carregado de uma CDN externa. Esse agente opera com cookies de terceiros para o rastreamento do dispositivo entre sessões.
Em um contexto de iframe cross-origin, navegadores com políticas de privacidade restritivas podem limitar a funcionalidade da Nethone:
| Navegador | Política | Impacto |
|---|---|---|
| Safari | Intelligent Tracking Prevention (ITP) | Cookies de terceiros bloqueados. Device fingerprint reduzido ao escopo da sessão. |
| Firefox | Enhanced Tracking Protection (ETP) | Cookies de terceiros bloqueados no modo estrito. Impacto semelhante ao do Safari. |
| Chrome | Configurável pelo usuário | Cookies de terceiros permitidos por padrão. Os usuários podem desativá-los. |
O onboarding foi projetado com degradação graciosa para a Nethone: se o script falhar ao carregar, se o profiling não for concluído dentro do timeout (5 segundos) ou se os cookies estiverem bloqueados, o fluxo continua normalmente. A análise de risco perde a dimensão de device intelligence, mas todas as demais verificações (biometria, documentoscopia, validação em bureaus) funcionam de forma independente.
Para cenários em que o device profiling é crítico, executar a Nethone no domínio do integrador (contexto first-party, sem restrições de cookies de terceiros) e comunicar o resultado ao iframe via PostMessage é uma alternativa suportada. Entre em contato com a equipe da Guardline para essa configuração.
Apêndice B: detalhes de fluxo de dados e compliance
Seção intitulada “Apêndice B: detalhes de fluxo de dados e compliance”Onde os dados residem
Seção intitulada “Onde os dados residem”Retenção de dados
Seção intitulada “Retenção de dados”| Tipo de dado | Local de armazenamento | Retenção | Criptografado em repouso |
|---|---|---|---|
| Token de sessão | Banco de dados da Guardline | Até a expiração ou a conclusão | Sim |
| Dados pessoais (nome, CPF, e-mail) | Banco de dados da Guardline | Conforme a política de retenção de dados (configurável) | Sim |
| Imagens de documentos | Object storage da Guardline | Conforme a política de retenção de dados (configurável) | Sim |
| Dados biométricos | Processados pela iProov, não armazenados pela Guardline | Não retidos | N/A |
| Device fingerprint | Processado pela Nethone, não armazenado pela Guardline | Não retido | N/A |
| Resultados de decisão | Banco de dados da Guardline | Trilha de auditoria imutável | Sim |
| Payloads de webhook | Banco de dados da Guardline (log de entregas) | 90 dias | Sim |
Matriz de responsabilidades de compliance
Seção intitulada “Matriz de responsabilidades de compliance”| Área | O que a Guardline fornece (técnico) | Contratual / configurável | Responsabilidade do integrador |
|---|---|---|---|
| LGPD | Os dados são coletados com uma finalidade específica e documentada (verificação de identidade). | A duração da retenção, a base legal para o tratamento e o DPA (Data Processing Agreement) são definidos por contrato. A retenção dos dados de onboarding é um compromisso contratual e não é aplicada automaticamente pela plataforma. | O integrador é o controlador de dados e precisa garantir a base legal para iniciar o onboarding (por exemplo, consentimento do usuário, necessidade contratual). A Guardline atua como operador de dados. |
| Residência de dados | A plataforma suporta deploy em regiões geográficas específicas ou on-premise. | A seleção de região e o deploy on-premise estão sujeitos a acordo contratual. | O integrador precisa definir os requisitos de residência com base nas suas próprias obrigações regulatórias. |
| Trilha de auditoria | Todas as operações são registradas em um log de auditoria imutável, acessível pelo painel administrativo. | O prazo de retenção dos logs e o formato de exportação são configuráveis por contrato. | O integrador é responsável por consumir e arquivar os logs de auditoria conforme exigido pelas suas próprias políticas de compliance. |
| Minimização de dados | Apenas os dados necessários para as etapas configuradas do fluxo são coletados. | A configuração do fluxo (quais etapas estão ativas, quais campos são obrigatórios) é definida durante a configuração inicial. | O integrador controla quais dados de pré-preenchimento enviar. Enviar dados pessoais desnecessários na requisição é responsabilidade do integrador. |
| Direito à exclusão | A plataforma suporta tecnicamente as solicitações de exclusão de dados. | Os procedimentos de exclusão e os SLAs são definidos por contrato. | O integrador precisa encaminhar à Guardline as solicitações de exclusão dos titulares dos dados e confirmar a conclusão ao solicitante. |
Apêndice C: detalhes de desempenho
Seção intitulada “Apêndice C: detalhes de desempenho”Os valores abaixo são medições P95 observadas na região da Europa sob condições normais de carga. O desempenho real varia conforme a infraestrutura do integrador, a qualidade da rede do cliente final e as capacidades do dispositivo. Esses números são fornecidos como referência de engenharia, não como compromissos de SLA. Os SLAs de desempenho são definidos por contrato.
| Métrica | P95 | Contexto da medição |
|---|---|---|
| Carregamento inicial do iframe | < 2s | Banda larga padrão (10 Mbps+). Inclui o bundle da SPA (gzipped), fontes e resolução do token. Assets em cache reduzem os carregamentos seguintes para < 500ms. |
| Resolução do token | < 200ms | Apenas o tempo de processamento no backend (consulta ao banco de dados + montagem da configuração do fluxo). Não inclui o round-trip de rede a partir do cliente. |
| Envio de etapa | < 300ms | Apenas o tempo de processamento no backend (validação + persistência). |
| Captura de documento (inicialização da câmera) | 1-3s | Varia conforme o hardware de câmera do dispositivo e o navegador. A primeira captura em um carregamento de página é mais lenta por causa do pedido de permissão de câmera e da inicialização do hardware. |
| Verificação biométrica | 5-15s | Ponta a ponta, incluindo a inicialização do SDK da iProov, a captura e o processamento no servidor. Fortemente dependente da latência de rede até os servidores da iProov. |
| Motor de decisão | < 500ms | Apenas o tempo de processamento no backend. Opera exclusivamente sobre dados já coletados durante as etapas do onboarding. Nenhuma chamada a provedores externos nesse estágio. |
| Entrega do PostMessage | < 1ms | Interno ao navegador, no mesmo dispositivo. Não é uma operação de rede. |
| Primeira tentativa de entrega do webhook | < 5s | Tempo entre a decisão e a requisição HTTP ao endpoint do integrador. Não inclui o tempo de processamento do integrador. |
Fatores que afetam a experiência do cliente final:
- Qualidade da rede: o upload de documentos e a verificação biométrica são as etapas que mais consomem banda. Em conexões abaixo de 3 Mbps, os tempos de captura e upload aumentam significativamente.
- Qualidade da câmera do dispositivo: câmeras de menor qualidade podem exigir várias tentativas de captura para a documentoscopia.
- Número de etapas do fluxo: cada etapa adiciona tempo de navegação do usuário. Um fluxo KYC com 6 etapas normalmente é concluído em 3-5 minutos de interação do usuário.
- Navegador: navegadores modernos (Chrome 90+, Safari 16+, Firefox 100+) oferecem o melhor desempenho para o acesso à câmera e para a renderização WebGL usada pelo SDK biométrico.
Versão 18, atualizada em