Un passkey es una credencial basada en criptografía de clave pública. En lugar de una contraseña que el usuario memoriza y que tu servidor guarda, hay un par de claves: la privada vive en el dispositivo, protegida por el hardware seguro, y no sale de ahí; la pública la guarda tu backend. Para entrar, el usuario desbloquea la clave con su huella o su cara y el dispositivo firma un reto que tu servidor verifica. No hay secreto que robar en tu base de datos ni contraseña que caiga en un correo de phishing.

En Flutter esto ya es terreno de producción, no de experimento. Apple expuso las APIs de passkeys en AuthenticationServices con iOS 16 y Google estabilizó Credential Manager en Android 14, así que una misma app Flutter puede ofrecer acceso sin contraseña en ambas plataformas. Escribimos esto porque la parte difícil de los passkeys no es el login: eso lo resuelve un plugin en una tarde. La parte difícil es qué pasa cuando el usuario cambia de móvil, lo pierde, o quiere entrar desde el portátil de un amigo. Ahí es donde se cae la mayoría de las implementaciones que hemos visto.

Qué es exactamente un passkey

Un passkey es una credencial WebAuthn, el estándar del W3C que se apoya en FIDO2. Cuando el usuario se registra, su dispositivo genera un par de claves para tu dominio. La clave privada queda en el llavero del sistema o en el enclave seguro; la pública viaja a tu backend y se asocia a la cuenta. En cada login, tu servidor manda un reto aleatorio, el dispositivo lo firma con la privada tras verificar al usuario, y tú validas la firma con la pública que ya tenías.

Dos propiedades hacen que esto importe. La primera: no hay secreto compartido. Un atacante que vacíe tu base de datos se lleva claves públicas, que por definición no sirven para suplantar a nadie. La segunda: el passkey está atado al dominio para el que se creó. El navegador o el sistema operativo no entregan la credencial a un dominio distinto, así que una página clonada en tu-banco-seguro.example no puede pedir la firma de tubanco.com. Eso corta el phishing por diseño, que es la vía de entrada de la mayoría de los robos de cuenta.

Qué problema resuelve, y cuál no

El caso a favor es concreto, no aspiracional. Las contraseñas generan tres costes que arrastras siempre: el usuario las reutiliza y una filtración ajena se convierte en tu problema (credential stuffing); el phishing sigue funcionando porque el usuario teclea el secreto donde no debe; y el soporte de "he olvidado mi contraseña" consume tickets y fricción en el alta. Los passkeys atacan los tres a la vez. En la práctica, el primer acceso convierte mejor, porque desbloquear con la cara es más rápido que esperar un SMS y teclear seis dígitos.

Lo que los passkeys no resuelven es la identidad. Un passkey demuestra que quien entra controla la clave que se registró, no quién es esa persona. Si tu producto necesita KYC (una app bancaria, una aseguradora), el passkey es la capa de autenticación recurrente, no la verificación de identidad del alta. Son dos problemas distintos y conviene no mezclarlos en el diseño.

Cómo se monta en Flutter

La arquitectura tiene cuatro piezas y ninguna es opcional.

En el cliente, un plugin de Dart hace de puente hacia AuthenticationServices en iOS y Credential Manager en Android. Paquetes como credential_manager o el passkeys de Corbado cubren el flujo; para web, el mismo código llama a la Web Authentication API del navegador. El plugin no implementa la criptografía, solo habla con las APIs nativas que ya la traen.

En el backend necesitas un servidor WebAuthn en condiciones: genera los retos, guarda las claves públicas y valida las firmas. No es un endpoint que improvises. Usa una librería mantenida (SimpleWebAuthn en Node, py_webauthn en Python, la que corresponda a tu stack en Go), porque los detalles de la verificación de la firma y del origin son donde se cuelan los fallos de seguridad.

La tercera pieza es la asociación de dominio, y es la que más tiempo se lleva la primera vez. iOS exige un fichero Apple App Site Association servido en tu dominio; Android pide su Digital Asset Links (assetlinks.json). Sin esa asociación bien publicada, el sistema operativo se niega a crear o usar el passkey, y el error no siempre es explícito. Presupuesta una tarde de depuración solo para esto.

La cuarta pieza son los fallbacks: la parte que decide si tu implementación aguanta el mundo real.

Passkeys sincronizados frente a ligados al dispositivo

Aquí hay una decisión de arquitectura que mucha gente toma por omisión sin darse cuenta.

Un passkey sincronizado se replica en la nube del fabricante: iCloud Keychain en Apple, Gestor de Contraseñas de Google en Android. El usuario cambia de móvil, inicia sesión en su cuenta de plataforma y sus passkeys aparecen. La experiencia es excelente y la recuperación deja de ser tu problema para pasar a ser el de Apple o Google. El coste: la clave privada, que en el modelo puro nunca salía del dispositivo, ahora vive también en la nube del fabricante, con la seguridad de esa cuenta como límite.

Un passkey ligado al dispositivo no se sincroniza. Vive en ese hardware y solo ahí. Es más resistente, porque ni un compromiso de la cuenta de iCloud lo expone, pero si el usuario pierde el dispositivo pierde la credencial, y la recuperación es cosa tuya. Es el modelo de las llaves de hardware tipo YubiKey y el que quieren los entornos de alta seguridad.

Para la mayoría de las apps de consumo, los passkeys sincronizados son la respuesta correcta: la usabilidad gana y la recuperación se externaliza. Si trabajas en banca, salud o un sector con requisitos de dispositivo gestionado, la conversación es otra y probablemente necesites soportar ambos. Para entrar desde otro equipo, los dos modelos usan el transporte híbrido: un QR que el móvil escanea y una comprobación de proximidad por Bluetooth, sin exponer la clave al ordenador prestado.

El caso fintech: passkeys y SCA

Si operas bajo PSD2, los passkeys encajan con la autenticación reforzada de cliente de forma natural. La SCA exige dos de tres factores independientes; una sola operación con passkey aporta dos: posesión, porque la clave privada está en el dispositivo del usuario, e inherencia, porque el desbloqueo pasa por la biometría. Un solo gesto satisface el requisito.

Con dos matices que no puedes saltarte. Para autorizar pagos, PSD2 pide vinculación dinámica: la firma tiene que atar el importe y el beneficiario concretos de esa operación, así que el reto WebAuthn debe incluir esos datos y no un valor aleatorio genérico. Y el marco se mueve: PSD3 y el reglamento de servicios de pago empujan hacia métodos resistentes al phishing, justo donde los passkeys son fuertes, pero conviene diseñar mirando el texto que viene y no solo el vigente. Si estás en este terreno, lo desarrollamos en nuestro artículo sobre SCA y biometría en apps bancarias y en el repaso de DORA, PSD3 y AI Act para fintech.

El problema de verdad: recuperación y fallbacks

Un passkey elimina la contraseña, pero no elimina la pregunta de qué haces cuando el usuario no puede usarlo. Y esa pregunta es más difícil que antes, porque ya no tienes un "restablecer contraseña por correo" universal al que agarrarte.

Piensa en los casos: el usuario tenía un passkey ligado al dispositivo y perdió el móvil; un usuario de Android que se pasa a iPhone y sus passkeys de Google no viajan a Apple; alguien que entra por primera vez desde un equipo sin su móvil a mano. En todos necesitas una segunda vía. Las opciones sensatas son permitir varios passkeys por cuenta (que registre el del móvil y el de la tablet), un enlace mágico al correo verificado como red de seguridad, y códigos de respaldo de un solo uso para el caso extremo.

El error clásico es dejar la recuperación tan floja que se convierte en el eslabón débil. De poco sirve un login resistente al phishing si tu "he perdido el acceso" es un SMS que un atacante puede interceptar con un SIM swap. La recuperación tiene que ser tan fuerte como el método principal, o habrás movido el problema en vez de resolverlo. Diséñala el primer día, no cuando lleguen los tickets.

Cómo se compara con las alternativas

MétodoResistente a phishingFricción para el usuarioCoste de soporteRecuperación
Contraseña + OTP por SMSNoAltaAltoFácil pero insegura
Contraseña + app TOTPParcialMediaMedioMedia
Enlace mágico por correoParcialMediaBajoDepende del correo
Passkey sincronizadoMuy bajaBajoExternalizada a la plataforma
Passkey ligado al dispositivoBajaBajoA tu cargo, exigente

Cuándo NO usar passkeys

No son la respuesta a todo. Nosotros no los pondríamos como método único en estos casos:

En dispositivos compartidos o de kiosko, donde el modelo de "esta credencial es de esta persona en este aparato" se rompe. En flotas gestionadas por MDM donde la política corporativa bloquea la sincronización: acabas con passkeys ligados al dispositivo y una recuperación pesada en cada rotación de terminal. Cuando tu base de usuarios arrastra versiones de sistema anteriores a iOS 16 o Android 14, donde tendrás que mantener el camino con contraseña en paralelo un tiempo. En productos B2B donde el acceso ya lo resuelve el proveedor de identidad de la empresa vía SSO, y añadir passkeys por tu cuenta duplica la superficie sin ganar nada; ahí tiene más sentido apoyarse en el SSO corporativo. Y en apps de bajo valor donde no vas a mantener un backend WebAuthn: un enlace mágico bien hecho te da casi todo el beneficio con una fracción del trabajo.

La regla que aplicamos: passkeys cuando la cuenta guarda algo que a alguien le interesa robar y el volumen justifica operar la infraestructura. Por debajo de eso, hay opciones más baratas que hacen el trabajo.

En resumen

Los passkeys en Flutter son adoptables hoy, con soporte nativo estable en iOS y Android y paquetes que resuelven el cliente. Eliminan la contraseña y, con ella, el phishing y el credential stuffing, con menos fricción en el acceso. Pero el trabajo real no está en el login, sino en tres decisiones: sincronizado o ligado al dispositivo, cómo verificas la asociación de dominio, y cómo recuperas una cuenta sin abrir un agujero. Resuelto eso, es de las pocas mejoras de seguridad que además mejoran la experiencia.

Si estás valorando pasar tu app Flutter a passkeys y quieres partir de una arquitectura que aguante la recuperación y el caso fintech, es justo el tipo de decisión que trabajamos en High-Performance Engineering. Cuéntanos dónde estás y lo miramos contigo.