Niveles y seguridad
El servidor es la única autoridad. La app nunca “ejecuta” una decisión: solo envía una intención de respuesta, y el servidor la acepta si es válida, está a tiempo y cumple el nivel exigido.
Niveles de decisión
Sección titulada «Niveles de decisión»| Nivel | Exige | Ejemplo |
|---|---|---|
| 0 | Un toque | Ver un panel, marcar como leído |
| 1 | Dispositivo desbloqueado (sesión iniciada) | Reiniciar un contenedor, responder a un lead |
| 2 | Biometría o PIN del dispositivo, o el código 2FA | Un agente de IA quiere actuar, aprobar un despliegue |
| 3 | Biometría o código 2FA en cada acción, en línea y con un plazo corto | Borrar datos, dar acceso, mover dinero |
| 4 | Nivel 3 y quórum | 2 de 3 directores aprueban |
El servicio define el nivel en ask(). El workspace puede endurecerlo, y el servicio nunca puede bajarlo. Vale el nivel más alto entre las preguntas.
Biometría en el dispositivo
Sección titulada «Biometría en el dispositivo»En la app nativa, la clave privada se crea en el Secure Enclave (iOS) o en el Keystore (Android) con la regla “solo firma tras autenticar al usuario”. Sin huella, rostro o código del dispositivo, el propio chip se niega a firmar.
- El dispositivo crea una clave por membresía/servidor, así una organización revoca la suya sin afectar a las demás.
- La respuesta firmada incluye el id del grupo de preguntas, la versión, las respuestas, la hora, un nonce y el hash del contenido mostrado.
- La solicitud de biometría muestra un resumen de lo que se firma, para que nadie apruebe a ciegas.
- La biometría siempre es una solicitud por decisión.
El código 2FA en lugar de la biometría
Sección titulada «El código 2FA en lugar de la biometría»No todo dispositivo tiene lector de huellas, y el navegador no tiene biometría. Para los niveles 2 y 3, una persona puede activar la verificación en dos pasos en Cuenta con cualquier app autenticadora TOTP (Google Authenticator, Microsoft Authenticator, 1Password, Authy o la app de la propia empresa) y firmar con el código de 6 dígitos.
- El código se verifica en el servidor (±30 segundos) y vale una sola vez. 5 códigos erróneos en 15 minutos bloquean nuevos intentos.
- La respuesta registra
auth_method: "totp"y el nivel comprobado. - El nivel 3 siempre pide un código, en cada acción.
- El nivel 4 (quórum) sigue exigiendo la app con biometría.
- Desactivar el 2FA exige un código válido, así quien robe una sesión no puede desactivarlo.
La ventana 2FA (nivel 2)
Sección titulada «La ventana 2FA (nivel 2)»Con 50 aprobaciones esperando, escribir un código en cada una no es razonable. En Cuenta, cada persona elige una ventana 2FA: desactivada (pedir siempre), 5, 15, 30, 60, 120 o 240 minutos. Tras un código válido, esa sesión firma decisiones de nivel 2 sin volver a escribir el código hasta que termine la ventana.
- La ventana es de la sesión: otros navegadores y dispositivos necesitan su propio código.
- Solo cubre el nivel 2. El nivel 3 siempre pide un código nuevo.
- Desactivar el 2FA borra la ventana de todas las sesiones.
Respuestas sin conexión
Sección titulada «Respuestas sin conexión»- Cada grupo de preguntas declara
offline: allowed | deniedy un vencimiento. - El servidor rechaza una respuesta para una versión antigua o una pregunta vencida, y la app explica el motivo (“tu respuesta no se aceptó porque la pregunta venció a las 12:30”).
- Idempotencia: la misma respuesta enviada dos veces se ejecuta una vez.
- El nivel 3 o más nunca se acepta sin conexión.
Aceptación atómica y outbox
Sección titulada «Aceptación atómica y outbox»UPDATE question_sets SET status = 'answered', answered_by = $3, answered_at = now() WHERE id = $1 AND version = $2 AND status = 'open';-- 0 filas = ya decidido, vencido o versión distintaLa respuesta y el aviso a tu sistema se guardan en la misma transacción (outbox transaccional). Un proceso aparte entrega el webhook firmado con reintentos automáticos, así la decisión nunca se pierde.
La respuesta firmada
Sección titulada «La respuesta firmada»La respuesta que recibe tu sistema está firmada con la clave Ed25519 del servidor. Las claves públicas están en <api>/.well-known/notificme-keys.json, y el SDK las verifica por ti. Mira Webhooks.
Otros controles
Sección titulada «Otros controles»- Revocación de un dispositivo perdido desde la app web (Dispositivos).
- Auditoría: quién, qué dispositivo, qué nivel, cuándo y el hash del contenido, inmutable y exportable.
- Los tokens de servicio tienen alcances, y los tokens de agentes de IA pueden exigir aprobación humana en cada escritura. Mira Agentes de IA y MCP.