Na web aberta, um toque de passkey abre o autenticador do sistema e faz o login. Dentro de um WebView integrado, esse mesmo fluxo é o que quebra: o WebAuthn depende de capacidades do navegador e da plataforma que o WebView não oferece com confiança, e as passkeys são vinculadas ao domínio do app host, não ao seu. Um runtime próprio do host faz a ponte do autenticador nativo do dispositivo: uma API que faz login em cada motor.

Android: o WebView não suporta WebAuthn

Guias de integração autorizadas são explícitas: o WebView de sistema do Android "não suporta WebAuthn", e o FIDO no Android depende do Google Play Services alcançar a página. Dentro de um WebView integrado, a cerimônia não garante um autenticador de plataforma, então navigator.credentials.create() e .get() podem lançar erro ou não fazer nada em silêncio. Mesmo onde o motor subjacente poderia suportar, quem controla o WebView é o app host, não um navegador real, então a cerimônia completa de passkey que Safari ou Chrome executam não está garantida. A matriz de compatibilidade da Yubico confirma o quadro: no Android, o suporte FIDO é entregue pelo Google Play Services, não pelo componente WebView.

iOS: navigator.credentials ausente no WKWebView

No iOS a situação é mais aguda. Relatos de desenvolvedores e guias de passkeys mostram que navigator.credentials só está disponível em SFSafariViewController e ASWebAuthenticationSession, não no WKWebView que a maioria dos apps embute —chamá-lo produz "WebAuthn not implemented on iOS". Pior ainda, as passkeys dentro de um WKWebView são vinculadas aos Associated Domains do app host, não ao seu domínio de relying party: um usuário que chega ao seu site dentro do Instagram ou TikTok não pode usar suas passkeys porque o WebView está vinculado ao domínio deles, não ao seu. A UI condicional —o autopreenchimento de passkey que aparece no campo de usuário— também não é suportada dentro de um WebView.

O que quebra quando as passkeys morrem

  • O login sem senha termina em beco sem saída. O login rápido e resistente a phishing é o que falha dentro do navegador integrado.
  • O MFA com chave de segurança falha. O segundo fator WebAuthn e as credenciais detectáveis nunca iniciam.
  • Os usuários caem em senhas e OTP. As rotas mais lentas e propensas ao abandono se tornam as únicas.
  • As falhas são invisíveis. Uma cerimônia que nunca inicia não deixa chamada ao servidor, então o analytics mostra um abandono inexplicado, não um erro.

A solução do runtime

Um runtime próprio do host faz a ponte do autenticador nativo do dispositivo. A página chama uma API uniforme —runtime.createPasskey() e runtime.authenticateWithPasskey()— e o host conduz FIDO2 / Play Services no Android e ASAuthorizationPlatformPublicKeyCredentialProvider no iOS (ou abre uma ASWebAuthenticationSession para a etapa de autenticação). Os Associated Domains que o host controla vinculam a passkey ao seu site. Uma integração, cada motor, um login real com apoio de hardware.

DimensãoWebViewRuntime próprio do host
API WebAuthnAusente / inconsistentePonte uniforme
Caminho AndroidWebView não tem WebAuthnFIDO2 / Play Services
Caminho iOSWKWebView: navigator.credentials ausenteASAuthorization nativo
Vinculação de domínioApp host, não seu siteAssociated Domains do host
UI condicionalNão no WebViewNativa
ObservabilidadeFalha silenciosa no clienteVisível no backend

Um app nativo faz login com passkey em cada dispositivo. Um WebView padrão em quase nenhum. Um runtime dá à página um autenticador — e um login real, com apoio de hardware, no fim.

Fontes