Tipos de Flujo
El iframe de firma detecta automáticamente qué flujo ejecutar según el estado del usuario. Existen 3 flujos principales y 2 flujos legacy para compatibilidad con usuarios antiguos.
Resumen de flujos
| Flujo | ID técnico | Condición | Pasos | Duración aprox. |
|---|---|---|---|---|
| Usuario nuevo | REGISTER_ISSUE_SIGN | Usuario nuevo | 10 pasos | 5-8 min |
| Usuario existente sin certificado activo | LOGIN_ISSUE_SIGN | Usuario existente sin certificado | 9 pasos | 3-5 min |
| Usuario con certificado activo | LOGIN_SIGN | Usuario con certificado activo | 5 pasos | 1-2 min |
| Usuario legacy sin certificado activo | LOGIN_LEGACY_USER | Usuario legacy sin certificado | 11 pasos | 5-8 min |
| Usuario legacy con certificado activo | LOGIN_LEGACY_USER_SIGN | Usuario legacy con certificado | 7 pasos | 2-3 min |
1. Usuario nuevo
Flujo completo para usuarios nuevos que nunca usaron Lakaut.
Cuándo se activa
- El email proporcionado no existe en el sistema
Pasos del flujo
SET_PASSWORD → OTP → PHONE_VALIDATION → BIOMETRIC_VALIDATION → BIOMETRIC_VALIDATION_SUCCESS
→ CERTIFICATE_PASSWORD → CERTIFICATE_SUCCESS → DOCUMENT_VIEWER → SIGN_CREDENTIALS
→ PHONE_VALIDATION_SIGN → SUCCESS
| # | Paso | Descripción |
|---|---|---|
| 1 | SET_PASSWORD | El usuario crea su contraseña de cuenta |
| 2 | OTP | Verificación por código Email (puede auto-saltearse) |
| 3 | PHONE_VALIDATION | Verificación por código SMS de autenticación |
| 4 | BIOMETRIC_VALIDATION | Validación de identidad con RENAPER (selfie + DNI) |
| 5 | BIOMETRIC_VALIDATION_SUCCESS | Confirmación de validación biométrica exitosa |
| 6 | CERTIFICATE_PASSWORD | Crea la contraseña del certificado digital |
| 7 | CERTIFICATE_SUCCESS | Confirmación de emisión del certificado |
| 8 | DOCUMENT_VIEWER | Visualización del documento a firmar |
| 9 | SIGN_CREDENTIALS | Ingreso de contraseña del certificado |
| 10 | PHONE_VALIDATION_SIGN | OTP SMS previo a la firma (puede auto-saltearse) |
| 11 | SUCCESS | Firma completada, descarga disponible |
Diagrama visual
┌─────────────────────────────────────────────────────────────────┐
│ Usuario nuevo (REGISTER_ISSUE_SIGN) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌─────┐ ┌──────────┐ ┌───────────┐ │
│ │ Crear │ → │ OTP │ → │ OTP SMS │ → │ Biometría │ │
│ │ Password │ │Email│ │ │ │ (RENAPER) │ │
│ └──────────┘ └─────┘ └──────────┘ └───────────┘ │
│ ↓ │
│ ┌──────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────┐ │
│ │ SUCCESS │ ← │ Firmar │ ← │ Ver Doc │ ← │ Emitir Cert. │ │
│ │ ✅ │ │ │ │ │ │ │ │
│ └──────────┘ └─────────┘ └─────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
2. Usuario existente sin certificado activo
Flujo para usuarios existentes que no tienen certificado activo (expiró, fue revocado, o nunca emitió uno).
Cuándo se activa
- El email existe en el sistema
- El usuario no tiene certificado activo
- El usuario no es legacy
Pasos del flujo
LOGIN → OTP → PHONE_VALIDATION → SUBSCRIBER_AGREEMENT → BIOMETRIC_VALIDATION
→ BIOMETRIC_VALIDATION_SUCCESS → CERTIFICATE_PASSWORD → CERTIFICATE_SUCCESS
→ DOCUMENT_VIEWER → SIGN_CREDENTIALS → PHONE_VALIDATION_SIGN → SUCCESS
| # | Paso | Descripción |
|---|---|---|
| 1 | LOGIN | Ingreso con email y contraseña existente |
| 2 | OTP | Verificación por email (puede auto-saltearse) |
| 3 | PHONE_VALIDATION | Verificación por SMS de autenticación |
| 4 | SUBSCRIBER_AGREEMENT | Aceptación del acuerdo de suscriptor |
| 5 | BIOMETRIC_VALIDATION | Validación de identidad |
| 6 | BIOMETRIC_VALIDATION_SUCCESS | Confirmación de validación exitosa |
| 7 | CERTIFICATE_PASSWORD | Crea la contraseña del nuevo certificado |
| 8 | CERTIFICATE_SUCCESS | Confirmación de emisión |
| 9 | DOCUMENT_VIEWER | Visualización del documento |
| 10 | SIGN_CREDENTIALS | Contraseña del certificado |
| 11 | PHONE_VALIDATION_SIGN | OTP SMS previo a firma |
| 12 | SUCCESS | Firma completada |
Diagrama visual
┌─────────────────────────────────────────────────────────────────┐
│ Usuario existente sin certificado activo (LOGIN_ISSUE_SIGN) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌─────┐ ┌──────────┐ ┌───────────┐ │
│ │ Login │ → │ OTP │ → │ OTP SMS │ → │ Acuerdo │ │
│ │ │ │Email│ │ │ │ Suscript. │ │
│ └──────────┘ └─────┘ └──────────┘ └───────────┘ │
│ ↓ │
│ ┌──────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐ │
│ │ SUCCESS │ ← │ Firmar │ ← │ Ver Doc │ ← │ Biometría │ │
│ │ ✅ │ │ │ │ │ │ │ │
│ └──────────┘ └─────────┘ └─────────┘ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
3. Usuario con certificado activo
Flujo rápido para usuarios con certificado activo. Es el más corto y común para firmantes recurrentes.
Cuándo se activa
- El email existe en el sistema
- El usuario tiene un certificado digital activo (no expirado)
- El usuario no es legacy
Pasos del flujo
LOGIN → PHONE_VALIDATION → DOCUMENT_VIEWER → SIGN_CREDENTIALS
→ PHONE_VALIDATION_SIGN → SUCCESS
| # | Paso | Descripción |
|---|---|---|
| 1 | LOGIN | Ingreso con credenciales |
| 2 | PHONE_VALIDATION | Verificación SMS de autenticación (puede auto-saltearse) |
| 3 | DOCUMENT_VIEWER | Visualización del documento |
| 4 | SIGN_CREDENTIALS | Contraseña del certificado existente |
| 5 | PHONE_VALIDATION_SIGN | OTP SMS previo a firma (puede auto-saltearse) |
| 6 | SUCCESS | Firma completada |
Diagrama visual
┌─────────────────────────────────────────────────────────────────┐
│ Usuario con certificado activo (LOGIN_SIGN) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌─────────────┐│
│ │ Login │ → │ OTP SMS │ → │ Ver Doc. │ → │ Firmar + ││
│ │ │ │ │ │ │ │ OTP SMS ││
│ └──────────┘ └──────────┘ └───────────┘ └─────────────┘│
│ ↓ │
│ ┌──────────┐ │
│ │ SUCCESS │ │
│ │ ✅ │ │
│ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
4. Usuario legacy sin certificado activo
Flujo para usuarios legacy sin certificado activo. Incluye captura de teléfono si no está registrado.
Cuándo se activa
- El usuario está marcado como legacy (
isLegacy: true) - El usuario no tiene certificado activo
Pasos del flujo
LOGIN → OTP → PHONE_CAPTURE → PHONE_VALIDATION → SUBSCRIBER_AGREEMENT
→ BIOMETRIC_VALIDATION → BIOMETRIC_VALIDATION_SUCCESS → CERTIFICATE_PASSWORD
→ CERTIFICATE_SUCCESS → DOCUMENT_VIEWER → SIGN_CREDENTIALS
→ PHONE_VALIDATION_SIGN → SUCCESS
| # | Paso | Descripción |
|---|---|---|
| 1 | LOGIN | Ingreso con credenciales legacy |
| 2 | OTP | Verificación por email (puede auto-saltearse) |
| 3 | PHONE_CAPTURE | Captura de número de teléfono si no existe |
| 4 | PHONE_VALIDATION | Verificación SMS de autenticación |
| 5 | SUBSCRIBER_AGREEMENT | Aceptación del acuerdo de suscriptor |
| 6 | BIOMETRIC_VALIDATION | Validación de identidad con RENAPER |
| 7 | BIOMETRIC_VALIDATION_SUCCESS | Confirmación de validación exitosa |
| 8 | CERTIFICATE_PASSWORD | Crea la contraseña del certificado |
| 9 | CERTIFICATE_SUCCESS | Confirmación de emisión |
| 10 | DOCUMENT_VIEWER | Visualización del documento |
| 11 | SIGN_CREDENTIALS | Contraseña del certificado |
| 12 | PHONE_VALIDATION_SIGN | OTP SMS previo a firma |
| 13 | SUCCESS | Firma completada |
5. Usuario legacy con certificado activo
Flujo para usuarios legacy con certificado activo.
Cuándo se activa
- El usuario está marcado como legacy (
isLegacy: true) - El usuario tiene certificado activo
Pasos del flujo
LOGIN → OTP → PHONE_CAPTURE → PHONE_VALIDATION → BIOMETRIC_VALIDATION
→ BIOMETRIC_VALIDATION_SUCCESS → DOCUMENT_VIEWER → SIGN_CREDENTIALS
→ PHONE_VALIDATION_SIGN → SUCCESS
| # | Paso | Descripción |
|---|---|---|
| 1 | LOGIN | Ingreso con credenciales legacy |
| 2 | OTP | Verificación por email (puede auto-saltearse) |
| 3 | PHONE_CAPTURE | Captura de número de teléfono si no existe |
| 4 | PHONE_VALIDATION | Verificación SMS de autenticación |
| 5 | BIOMETRIC_VALIDATION | Re-validación de identidad |
| 6 | BIOMETRIC_VALIDATION_SUCCESS | Confirmación de validación exitosa |
| 7 | DOCUMENT_VIEWER | Visualización del documento |
| 8 | SIGN_CREDENTIALS | Contraseña del certificado |
| 9 | PHONE_VALIDATION_SIGN | OTP SMS previo a firma |
| 10 | SUCCESS | Firma completada |
Comparativa de flujos
| Aspecto | Usuario nuevo | Usuario existente sin cert. | Usuario con cert. activo | Legacy (sin cert.) | Legacy (con cert. activo) |
|---|---|---|---|---|---|
| Usuario nuevo | ✅ | ❌ | ❌ | ❌ | ❌ |
| Requiere biometría | ✅ | ✅ | ❌ | ✅ | ✅ |
| Emite certificado | ✅ | ✅ | ❌ | ✅ | ❌ |
| Captura teléfono | ❌ | ❌ | ❌ | ✅ | ✅ |
| Pasos totales | 11 | 12 | 6 | 13 | 10 |
| Tiempo estimado | 5-8 min | 3-5 min | 1-2 min | 5-8 min | 2-3 min |
Detección automática
El iframe detecta automáticamente qué flujo usar basándose en:
- Verificación de email: Consulta si el usuario existe
- Verificación de certificado: Si existe, consulta si tiene certificado activo
- Verificación de legacy: Detecta si el usuario es legacy según el token JWT
// Lógica interna simplificada
if (!userExists) {
return 'REGISTER_ISSUE_SIGN';
}
if (userData.isLegacy === true) {
return hasActiveCertificate
? 'LOGIN_LEGACY_USER_SIGN'
: 'LOGIN_LEGACY_USER';
}
const scope = getTokenScope(userData.pendingToken);
if (scope === 'verify_email') {
return 'LOGIN_ISSUE_SIGN';
}
if (!hasActiveCertificate && userExists) {
return 'LOGIN_ISSUE_SIGN';
}
return 'LOGIN_SIGN';
💡 Tip: Como integrador, no necesitás preocuparte por elegir el flujo. Solo enviá los datos del usuario y el iframe se encarga del resto.
Detalles de Autenticación (OTP y Tokens)
OTP Multi-paso (Email y SMS)
El sistema de autenticación utiliza dos tipos de OTP según el flujo:
1. OTP por Email (verify_email)
- Cuándo se usa: Después del registro o login cuando el email no está verificado
- Propósito: Verificar la propiedad del email
- Token recibido:
pendingTokencon scopeverify_email - Siguiente paso: OTP por SMS
2. OTP por SMS (verify_sms)
- Cuándo se usa:
- Después de verificar el email (autenticación)
- Antes de firmar un documento (sesión)
- Propósito:
- Autenticación: Completar el login y obtener token final
- Sesión: Validar la identidad antes de firmar
- Token recibido:
- Autenticación:
tokenfinal (sin scope restrictivo) - Sesión: No cambia el token, solo valida
- Autenticación:
Tokens transitorios vs finales
| Tipo | Cuándo se obtiene | Scope | Uso |
|---|---|---|---|
| pendingToken (verify_email) | Después de login si email no verificado | verify_email | Validar OTP email |
| pendingToken (verify_sms) | Después de validar OTP email | verify_sms | Validar OTP SMS de autenticación |
| token (final) | Después de validar OTP SMS | Sin scope restrictivo | Acceso completo a la API |
Auto-skip de pasos OTP
El iframe salta automáticamente ciertos pasos de OTP según condiciones:
| Paso | Condición de auto-skip | Razón |
|---|---|---|
| OTP Email | scope !== 'verify_email' | El email ya está verificado |
| PHONE_VALIDATION (autenticación) | Token final existe Y OTP validado hace menos de 5 min | El usuario ya completó autenticación recientemente |
| PHONE_VALIDATION_SIGN (firma) | OTP validado hace menos de 5 min | El usuario ya validó su identidad recientemente |
Ventana de validez del OTP
- Duración: 5 minutos desde la validación
- Propósito: Evitar solicitar múltiples OTPs en un flujo continuo
- Ejemplo: Si el usuario valida OTP SMS en el login, no se le pedirá otro OTP antes de firmar si no pasaron 5 minutos
// Ejemplo interno de validación de ventana
const OTP_VALIDITY_WINDOW = 5 * 60 * 1000; // 5 minutos
function isOtpStillValid(otpValidatedAt) {
if (!otpValidatedAt) return false;
const elapsed = Date.now() - otpValidatedAt;
return elapsed < OTP_VALIDITY_WINDOW;
}
Flujo de autenticación completo (ejemplo)
1. Usuario → Login con email/password
2. Backend → Responde con pendingToken (scope: verify_email) + requiresOtp: true
3. Usuario → Recibe OTP por email
4. Usuario → Ingresa OTP email
5. Backend → Valida OTP → Responde con pendingToken (scope: verify_sms)
6. Usuario → Recibe OTP por SMS
7. Usuario → Ingresa OTP SMS
8. Backend → Valida OTP → Responde con token final (sin scope)
9. Usuario → Autenticado completamente
10. [5 minutos después]
11. Usuario → Intenta firmar documento
12. Sistema → Auto-skip PHONE_VALIDATION_SIGN (OTP aún válido)
13. Usuario → Firma directamente
Validación Biométrica con RENAPER
¿Qué es RENAPER y por qué se usa?
RENAPER (Registro Nacional de las Personas) es el organismo oficial de Argentina que mantiene los datos de identidad de todos los ciudadanos.
Propósito en el flujo:
- Validar que la persona que firma es quien dice ser
- Obtener datos oficiales del usuario (nombre, domicilio, CUIL completo)
- Cumplir con requisitos legales de firma digital calificada
Inicio automático de validación
Cuando el usuario llega al paso BIOMETRIC_VALIDATION, el iframe automáticamente:
- Llama a la API de RENAPER con el DNI/CUIL y género del usuario
- Obtiene los datos oficiales del usuario
- Actualiza el estado interno con estos datos
// Datos obtenidos automáticamente de RENAPER
{
nombres: "Juan Carlos",
apellido: "Pérez",
cuil: "20-12345678-9",
calle: "Av. Corrientes",
numero: "1234",
piso: "5",
departamento: "B",
ciudad: "Ciudad Autónoma de Buenos Aires",
provincia: "Capital Federal",
codigo_postal: "C1043"
}
Datos obtenidos automáticamente
El iframe completa automáticamente los siguientes campos del usuario:
| Campo | Origen | Uso posterior |
|---|---|---|
| nombre completo | RENAPER | Emisión del certificado |
| CUIL completo | RENAPER | Identificación única |
| domicilio completo | RENAPER | Datos del certificado |
⚠️ Importante: Estos datos sobrescriben cualquier dato enviado en
userDatadellakaut.init.
Requisitos de la selfie
Para que la validación facial sea exitosa, el usuario debe:
✅ Permitir acceso a la cámara del dispositivo
✅ Rostro completamente visible sin obstrucciones
✅ Sin lentes (anteojos de sol o recetados)
✅ Sin gorra, sombrero o accesorios que cubran la cara
✅ Buena iluminación (evitar contraluz)
✅ Mirar directamente a la cámara
❌ No usar:
- Fotos de fotos
- Máscaras o caretas
- Maquillaje excesivo que altere rasgos
- Filtros o efectos de cámara
Permisos de cámara necesarios
El iframe requiere el permiso camera en el atributo allow:
<iframe
id="lakaut-firma"
src="https://iframe.lakautac.com.ar/embed?sessionToken=TU_SESSION_TOKEN"
allow="clipboard-read; clipboard-write; camera *; microphone"
></iframe>
Errores comunes:
| Error | Causa | Solución |
|---|---|---|
NotAllowedError | Usuario bloqueó el acceso | Pedir al usuario que permita cámara en configuración del navegador |
NotFoundError | No hay cámara disponible | Usar dispositivo con cámara |
SecurityError | Iframe sin permiso camera | Agregar camera * al atributo allow |
Validación facial (HIT/NO HIT)
Después de capturar la selfie, RENAPER compara el rostro con la foto del DNI:
- HIT ✅: El rostro coincide → Continúa el flujo
- NO HIT ❌: El rostro no coincide → Muestra error y permite reintentar
Causas comunes de NO HIT:
- Foto borrosa o con poca luz
- Rostro parcialmente oculto
- Ángulo incorrecto de la cámara
- Cambios significativos en la apariencia vs foto del DNI
💡 Tip: Si el usuario recibe múltiples NO HIT, puede deberse a que la foto del DNI en RENAPER es muy antigua. En estos casos, contactar a soporte.
Flujo completo de validación biométrica
1. Usuario llega a BIOMETRIC_VALIDATION
2. Iframe → Llama a RENAPER con DNI + género
3. RENAPER → Devuelve datos oficiales del usuario
4. Iframe → Actualiza userData con datos de RENAPER
5. Iframe → Solicita permiso de cámara
6. Usuario → Permite acceso a cámara
7. Iframe → Muestra vista previa de cámara con guías
8. Usuario → Captura selfie
9. Iframe → Envía selfie a RENAPER para validación
10. RENAPER → Compara rostro con foto del DNI
11a. Si HIT → Iframe avanza a BIOMETRIC_VALIDATION_SUCCESS
11b. Si NO HIT → Iframe muestra error y permite reintentar
Generación de Certificado Digital
Diferencia: Contraseña de cuenta vs Contraseña de certificado
| Aspecto | Contraseña de cuenta | Contraseña de certificado |
|---|---|---|
| Uso | Login en la plataforma | Firmar documentos |
| Recuperación | ✅ Se puede recuperar | ❌ NO se puede recuperar |
| Cambio | ✅ Se puede cambiar | ❌ Requiere emitir nuevo certificado |
| Requisitos | Mínimo 8 caracteres | Nivel 3 obligatorio |
| Almacenamiento | Backend de Lakaut | HSM (Hardware Security Module) |
⚠️ CRÍTICO: La contraseña del certificado NO se puede recuperar de ninguna manera. Si el usuario la olvida, debe emitir un nuevo certificado.
Requisitos de contraseña del certificado (3 niveles)
El sistema valida la contraseña en 3 niveles progresivos:
Nivel 1: Longitud mínima
- ✅ Al menos 8 caracteres
- Ejemplo:
password❌ (muy débil, pero cumple nivel 1)
Nivel 2: Longitud + números
- ✅ Al menos 8 caracteres
- ✅ Al menos 1 número
- Ejemplo:
password123✅ (cumple nivel 2)
Nivel 3: Longitud + números + símbolos especiales (OBLIGATORIO)
- ✅ Al menos 8 caracteres
- ✅ Al menos 1 número
- ✅ Al menos 1 símbolo especial (
!@#$%^&*(),.?":{}|<>) - Ejemplo:
Pass123!✅ (cumple nivel 3)
⚠️ Obligatorio: El iframe solo permite continuar si la contraseña cumple con el Nivel 3.
Indicadores visuales en la UI
El iframe muestra indicadores visuales para cada nivel:
Nivel 1: Al menos 8 caracteres [●○○]
Nivel 2: Incluye números [●●○]
Nivel 3: Incluye símbolos especiales [●●●] ✅
- Gris: No cumplido
- Azul: Cumplido
- Checkmark: Nivel completado
Validación de confirmación
Además de los niveles, el usuario debe:
- Ingresar la contraseña
- Confirmar la contraseña (debe coincidir exactamente)
Errores comunes:
- "Las contraseñas no coinciden" → Verificar que ambos campos sean idénticos
- "La contraseña no cumple con todos los niveles" → Falta nivel 3
Advertencias críticas para el usuario
El iframe muestra las siguientes advertencias:
🔴 Importante: Esta contraseña NO se puede recuperar de ninguna manera. Elegí algo que puedas recordar.
🔴 Recordá tu contraseña: La necesitarás cada vez que firmes un documento.
Proceso de emisión del certificado
Una vez que el usuario crea la contraseña:
- Iframe → Envía solicitud de emisión al backend
- Backend → Genera par de claves criptográficas (pública/privada)
- Backend → Almacena clave privada en HSM protegida con la contraseña
- Backend → Genera certificado X.509 con datos del usuario (de RENAPER)
- Backend → Devuelve
serialNumberysolicitudIddel certificado - Iframe → Guarda referencia del certificado en el estado
- Iframe → Avanza a CERTIFICATE_SUCCESS
Datos incluidos en el certificado
El certificado X.509 incluye:
- Nombre completo (de RENAPER)
- CUIL (de RENAPER)
- Email del usuario
- Número de serie único
- Fecha de emisión
- Fecha de expiración (típicamente 1-3 años)
- Clave pública (la privada queda protegida en HSM)
Uso posterior del certificado
Una vez emitido, el certificado se usa para:
- Firmar documentos: Cada firma requiere la contraseña del certificado
- Validar identidad: El certificado prueba que el firmante es quien dice ser
- No repudio: La firma no puede ser negada posteriormente
Renovación y revocación
- Renovación: Cuando el certificado expira, el usuario debe generar uno nuevo (nuevo flujo LOGIN_ISSUE_SIGN)
- Revocación: Si la contraseña se compromete, el certificado puede ser revocado y se debe emitir uno nuevo
Siguiente paso
Continuá con Fundamentos de Integración para aprender cómo implementar el iframe en tu aplicación.