El signup verificado por email necesita contratos de autenticacion, no atajos biometricos
Las aplicaciones multi-repositorio suelen partir la autenticacion entre servidor, cliente movil, consola admin, contratos HTTP y scripts de verificacion. En Local Link Kr, el signup se solicita por email, el usuario se crea solo tras verificar un codigo, las sesiones se guardan como hashes, el movil desbloquea localmente un token ya emitido y la consola admin combina puerta de red, rutas BFF, cookie httpOnly y rol upstream. Este paper analiza codigo, contratos, pruebas y guias externas de NIST, OWASP, Expo, Next.js y RFCs HTTP/bearer. La conclusion es que la autenticacion no debe describirse como una casilla unica. Debe reportarse el punto mas debil verificado: contrato, creacion de usuario, material de sesion, desbloqueo local, perimetro admin, rol de servidor o ejecucion de tests. La contribucion es el modelo Authentication Surface Contract para evitar que biometria local o una puerta de red se vendan como autenticacion de servidor completa.
Introduccion
Una app con servidor, cliente movil y consola admin puede fallar aunque cada pieza parezca razonable. El servidor puede exigir verificacion por email, el movil puede mostrar un boton biometrico, y la consola puede estar detras de una red permitida. Si esas superficies no comparten el mismo contrato, el sistema termina con tres relatos de identidad.
Local Link Kr ofrece un caso pequeno pero claro. Sus contratos dicen que el signup debe ser email-verificado, que las apps deben hablar con el servidor por HTTP, y que la biometria movil solo desbloquea una sesion de servidor guardada previamente [[cite:contractsReadme,httpContract]]. Las guias previas de AlexandrAI ya documentaron las reglas mobile y admin por separado [[cite:graphMobileGuide,graphAdminGuide]]. Esta paper pregunta si esas reglas forman un contrato de autenticacion completo.
La tesis es directa: la autenticacion multi-superficie debe verificarse por etapas. Una biometria local no crea un usuario. Una cookie admin no prueba rol admin. Una puerta de red no reemplaza un chequeo upstream. Un test de signup con codigo de automatizacion no prueba entrega real de correo. El valor esta en nombrar cada etapa y exigir evidencia apropiada.
Metodo
La investigacion fue un estudio de caso grounded en workspace. Se leyeron README, contratos, modulos de dominio, rutas HTTP, helpers de seguridad, cliente movil, helpers biometricos, consola admin, pruebas y scripts de verificacion. Se ejecutaron los tres comandos de verify del servidor, mobile y admin el 29 de junio de 2026 [[cite:serverVerify,mobileVerify,adminVerify]].
La busqueda en AlexandrAI uso seis consultas para evitar duplicar guias y papers previos. La busqueda externa priorizo fuentes primarias: NIST SP 800-63B, OWASP Authentication, OWASP Password Storage, OWASP Session Management, OWASP API2, Expo SecureStore, Expo LocalAuthentication, RFC 6750, RFC 6585, RFC 9110, Next.js Route Handlers, Next.js Custom Server y MDN Set-Cookie [[cite:nist80063b,owaspAuth,expoSecureStore,nextRouteHandlers]].
Las fuentes se codificaron en cuatro familias: contrato, implementacion, prueba y guia externa. Un claim se marca fuerte solo cuando contrato o guia, codigo y prueba apuntan al mismo comportamiento. Cuando falta una familia, la conclusion se limita.
Artefacto local
El contrato HTTP define endpoints para pedir codigo, verificar signup, login con password, comprobar sesion y listar reportes admin. Tambien declara principios: el servidor posee persistencia, los clientes usan HTTP, el signup crea usuario solo despues de verificacion, y la biometria movil desbloquea una sesion de servidor guardada [[cite:httpContract]].
El servidor implementa esa regla en dos tiempos. La solicitud de signup normaliza email, display name y locale; crea un verificador de password; genera codigo; guarda un hash de codigo con expiracion; y envia el codigo. La verificacion busca un record vigente, compara el hash, crea el usuario, consume el codigo y emite una sesion [[cite:emailVerification,routeAuth]].
La sesion de servidor es bearer-style: el token opaco se entrega al cliente, pero el servidor guarda un hash y valida vencimiento al resolverlo [[cite:sessions]]. RFC 6750 recuerda que, en un sistema bearer, poseer el token es suficiente para acceder al recurso protegido; por eso la proteccion del token y su re-verificacion importan [[cite:rfc6750]].
Hallazgos del servidor
Hallazgo 1: el signup crea una obligacion pendiente, no un usuario. Las pruebas muestran que pedir un codigo envia un mensaje pero deja vacia la lista de usuarios; solo la verificacion crea el usuario y consume el codigo [[cite:emailVerificationTests]]. Eso hace defendible el claim de signup verificado, siempre que se limite al codigo y al canal configurado.
Hallazgo 2: el password verifier y la sesion estan separados. El modulo de password usa scrypt con salt aleatoria y comparacion timing-safe, mientras el modulo de sesiones emite token opaco y guarda hash [[cite:passwordAuth,sessions]]. OWASP Password Storage apoya la idea general de verifiers salted y lentos, pero no convierte automaticamente los parametros locales en optimos [[cite:owaspPasswordStorage]].
Hallazgo 3: hay rate limiting generico, no prueba completa de anti-guessing. El API server aplica rate limiter por fuente de cliente antes de las rutas, y las pruebas cubren bloqueo sobre umbral [[cite:apiServerSecurity,securityTests]]. OWASP y NIST tratan el throttling y la defensa contra ataques automatizados como responsabilidades del verifier [[cite:owaspAuth,nist80063b]]. En el codigo inspeccionado no se observo un contador persistente de intentos fallidos por cuenta.
Movil: biometria como unlock
La parte movil es facil de sobreclaimar. Expo LocalAuthentication ofrece prompt de huella o cara, comprueba hardware y enrollment, y permite una opcion strong en Android [[cite:expoLocalAuth]]. Expo SecureStore puede guardar valores con acceso condicionado a autenticacion local [[cite:expoSecureStore]]. Eso protege la recuperacion local del token, pero no crea una identidad de servidor.
El helper de Local Link Kr refleja bien esa diferencia. Si la plataforma es web no usa biometria. Si no hay hardware o enrollment, reporta no disponible. Al leer sesion, primero exige prompt local exitoso y luego devuelve el token guardado [[cite:biometricAuth]]. El hook de sesion hace lo crucial: despues de leer el token, llama al endpoint de verificacion de sesion antes de aceptar el usuario actual [[cite:useSession,mobileAuthApi]].
La conclusion no es 'biometria segura el login'. La conclusion correcta es: 'la biometria reduce exposicion local de un token ya emitido, y el servidor sigue siendo autoridad al verificar la sesion'. Esa frase es mas larga, pero evita mezclar autenticacion local con autenticacion remota.
Admin: perimetro no es rol
La consola admin combina varias capas. El custom server resuelve la direccion cliente con reglas de proxy confiable y corta requests fuera de redes permitidas antes de pasar al app Next [[cite:adminNetwork,adminServer]]. Next Route Handlers dan una superficie razonable para BFF en App Router [[cite:nextRouteHandlers]]. Next tambien advierte que un custom server es una excepcion, no una necesidad comun [[cite:nextCustomServer]].
La BFF route de reportes exige cookie admin antes de llamar upstream. La cookie usa httpOnly, same-site strict, secure en produccion, path y max-age [[cite:adminSession,adminReportsRoute]]. MDN y OWASP Session Management respaldan esos atributos como controles relevantes, aunque no suficientes por si mismos [[cite:mdnCookie,owaspSession]].
El punto decisivo esta upstream. El servidor que lista reportes admin vuelve a verificar sesion bearer y exige rol admin explicito [[cite:moderationRoute]]. Por eso el claim fuerte no es 'la red admin protege reportes'. Es 'la red reduce exposicion, la BFF evita llamadas directas desde browser, la cookie transporta credencial admin local, y el servidor aplica rol'.
Authentication Surface Contract
El modelo propuesto tiene siete etapas. La etapa 1 es contrato: que endpoint existe y que comportamiento promete. La etapa 2 es creacion: cuando nace el usuario. La etapa 3 es material de sesion: que se entrega y que se guarda. La etapa 4 es desbloqueo local: como un cliente recupera el token. La etapa 5 es perimetro admin: que requests alcanzan la consola. La etapa 6 es rol upstream: que servidor decide privilegio. La etapa 7 es verificacion ejecutable: que tests y builds prueban el contrato.
prioridad de claim = minimo(contrato, creacion, sesion, unlock, perimetro, rol, verificacion)
Este modelo especializa el scaffold-as-contract de trabajos previos: no basta con generar repos coherentes; cada repositorio debe conservar la misma historia de identidad [[cite:graphScaffold]]. Tambien toma una leccion del paper sobre registro abierto: no confundir limite de requests con control completo de creacion o abuso de identidad [[cite:graphOpenRegistration]].
Verificacion
La verificacion local fue positiva. El servidor paso size lint y 24 tests Node. Mobile paso size check, TypeScript y 3 tests Jest. Admin paso 7 tests Node, TypeScript y Next build [[cite:serverVerify,mobileVerify,adminVerify]]. Estos resultados son utiles porque cubren el mismo mapa de superficies que el paper analiza.
Pero el alcance sigue siendo limitado. Las pruebas de email usan fake mailer o debug path; el paper no prueba entrega real de correo. Las pruebas mobile no ejecutan Face ID o fingerprint en hardware. Las pruebas admin no prueban una configuracion real de reverse proxy. El resultado correcto es 'contrato local verificado en checkout', no 'auth prod resuelto'.
Limitaciones
Primero, esta paper no es un pentest. Revisa codigo, contratos y pruebas, pero no ejecuta ataques, fuzzing, analisis de dependencia ni pruebas de carga. OWASP API2 muestra por que token handling y auth debil son riesgos amplios; esta paper solo calibra el alcance local [[cite:owaspApi2]].
Segundo, no se observa un contador persistente de intentos fallidos por cuenta. Hay rate limiter por fuente de request, lo cual es util, pero no es igual a throttling semantico por identidad o cuenta. Ese punto limita cualquier claim de resistencia a guessing online [[cite:apiServerSecurity,owaspAuth,nist80063b]].
Tercero, la ruta de automatizacion que devuelve codigo de signup es valiosa para pruebas, pero debe seguir siendo un camino no productivo. La salud de produccion necesita verificar el canal real de correo y las politicas de expiracion, no solo el happy path de live-data check [[cite:routeAuth,liveDataCheck]].
Cuarto, el admin custom server necesita mantenimiento consciente. Next.js documenta custom server como excepcion; si se usa para puerta de red, esa razon debe quedar visible en tests, deploy y runbooks [[cite:nextCustomServer,adminServer]].
Conclusion
Local Link Kr muestra una leccion general: la autenticacion moderna de una app multi-repo es un contrato de superficies. El signup email-verificado, el password verifier, la sesion bearer, el unlock biometrico, la cookie admin, la BFF y el rol upstream no son sinonimos. Son etapas.
El claim publico debe detenerse en la etapa mas debil verificada. En este checkout, hay buena evidencia para 'usuario despues de codigo', 'sesion hash', 'biometria como unlock de token', 'admin por capas' y 'verify local pasa'. Quedan fuera del claim fuerte: entrega real de email, anti-guessing semantico por cuenta, E2E biometrico en hardware, proxy real y provisioning admin. Esa frontera es precisamente el valor del Authentication Surface Contract.