Autorización sin autenticación
La autenticación y la autorización resuelven problemas distintos
La mayoría de las aplicaciones empiezan con una barrera. Antes de hacer nada, el usuario debe establecer su identidad: escribir un correo, recibir un código de verificación, elegir una contraseña o seguir un enlace mágico. Ese paso es la autenticación, el proceso de confirmar quién es alguien frente a un registro que guarda una autoridad central.
La autorización responde a otra pregunta: ¿qué tiene permitido hacer esta persona? Los equipos suelen juntar ambas en un único flujo de “inicio de sesión”, pero siguen siendo operaciones distintas. Separarlas revela una idea útil.
Un servidor no necesita saber quién es un usuario para hacer cumplir lo que tiene permitido hacer.
JustCall se basa en esa separación. No hay registro, ni tabla de cuentas, ni contraseña, ni datos personales en el servidor. La autorización sostiene todo el sistema, mientras que la autenticación en el sentido convencional no existe. Tres componentes lo hacen posible: una clave privada, una clave pública y un rol delegado al que llamamos clave maestra.
Cómo la identidad de clave pública reemplaza a las cuentas
La primera vez que abres JustCall, el navegador genera un secreto localmente y nunca lo transmite. De ese secreto deriva un par de claves, y la mitad pública se convierte en tu ID de usuario:
// The private key is generated on your device. The server never sees it.
privateKey = crypto.randomUUID();
// The PUBLIC half, encoded as text, becomes your user ID.
userId = await derivePublicUserId(privateKey);
El identificador es la clave pública en sí, no una fila de base de datos que apunta a ella. Esa sola decisión elimina varias cargas que arrastran los sistemas de cuentas tradicionales:
- Sin paso de registro. El servidor acepta las solicitudes firmadas con una ID en cuanto la ve por primera vez.
- Sin correo ni teléfono. La ID deriva de un secreto aleatorio en tu dispositivo, no de ningún dato personal.
- Sin contraseña. No hay secreto compartido que almacenar, hashear o filtrar, ya que el servidor solo guarda la clave pública.
- Sin flujo de restablecimiento de contraseña ni relleno de credenciales, porque no hay credenciales reutilizables que atacar.
Nunca revelas una identidad al servidor. Demuestras, de forma criptográfica, que posees la clave privada detrás de una clave pública dada, y esa prueba basta como autorización.
Cómo autoriza el servidor una solicitud
Sin sesiones ni tokens de inicio de sesión, cada solicitud lleva su propia prueba. El cliente construye una carga útil, la firma con la clave privada y envía ambas. En el servidor, la autorización se reduce a una sola verificación de firma, sin búsqueda de sesión ni consulta a un almacén de credenciales:
const isValid = await verifyPayload(
request.userId, // the public key = the claimed identity
request.payload, // exactly what was signed
request.signature,
);
if (!isValid) {
return jsonResponse({ message: "invalid signature" }, 401);
}
Una firma válida hace la solicitud auténtica y autorizada en una sola operación. Un atacante no puede falsificar una solicitud para una ID cuya clave privada no posee, porque no puede producir una firma coincidente. Poseer la clave privada es la autoridad.
La clave maestra: vincular dispositivos sin compartir secretos
Un modelo donde un dispositivo guarda la única clave se rompe en cuanto alguien añade un segundo dispositivo. Si tu teléfono guarda la única clave de tu identidad, tu portátil es un extraño para el sistema.
La clave maestra resuelve esto. El primer dispositivo se convierte en el maestro y guarda el secreto original del que deriva tu ID. Cada dispositivo adicional genera su propio par de claves separado. Un dispositivo nuevo no puede firmar en tu nombre, y la clave maestra nunca se copia entre dispositivos. La vinculación funciona por delegación: el maestro firma un breve certificado que liga la clave pública del nuevo dispositivo a tu ID.
// Only the master can authorize a new device.
const authorization = {
action: "device-authorization",
userId: identity.userId,
devicePublicKey: newDevice.devicePublicKey, // the new device's PUBLIC key
role: newDevice.role,
createdAt: Date.now(),
};
const signature = await signPayload(identity.privateKey, authorization);
A partir de ahí, el nuevo dispositivo firma sus propias solicitudes con su propia clave, y el servidor las verifica contra la clave que avaló el maestro. El maestro emite una credencial sin exponer jamás su secreto, igual que una autoridad de certificación avala un sitio web cuya clave privada no posee.
Esto te da todo el vocabulario de un sistema de permisos en producción: roles, delegación, revocación y mínimo privilegio, todo expresado mediante firmas. El maestro puede renombrar o revocar cualquier dispositivo vinculado, y un dispositivo revocado falla su siguiente verificación de firma mientras su conexión activa se cierra.
Qué almacena un servidor sin cuentas
Mira lo que contiene realmente la base de datos. Cada cuenta guarda un nombre visible que eligió el usuario, un avatar opcional y una lista de claves de dispositivo públicas. Nada más. No hay correos, teléfonos, hashes de contraseña ni preguntas de seguridad, y no hay claves privadas, que nunca salen de los dispositivos del usuario.
Considera el escenario clásico de filtración en el que se escapa toda la base de datos. El atacante obtiene un conjunto de claves públicas, que son públicas por diseño e inútiles sin las claves privadas correspondientes, más un puñado de nombres visibles elegidos por los usuarios. No puede suplantar a nadie, porque la suplantación exige una clave privada que el servidor nunca almacenó. No puede cruzar usuarios con un volcado de contraseñas, porque no existen contraseñas. No puede hacer phishing por “tu correo”, porque nunca se recogió ninguno.
Un sistema no puede filtrar datos que nunca tiene. La forma más fiable de proteger la información personal es no recopilarla, y un modelo de identidad donde la ID es una clave pública lo hace literal.
Por qué la autorización sin contraseñas reduce el riesgo de filtración
Compara las superficies de ataque de forma directa. Una app convencional de correo y contraseña debe defender una base de credenciales, flujos de restablecimiento de contraseña, envío de códigos por correo y SMS, tokens de sesión y un conjunto de datos personales regulados de los que ahora es responsable. Cada uno es una fuente recurrente de robo de cuentas e incidentes de filtración.
El modelo de clave pública defiende una sola cosa: que el usuario conserve su clave. Es un compromiso real, ya que ninguna autoridad central puede restablecer una clave perdida. A cambio, cada elemento de la lista anterior desaparece. El impacto de un servidor comprometido se reduce a que un atacante lea claves públicas y nombres visibles, información que nunca fue sensible.
Cómo aplicar la autorización con clave pública en tu propia app
El patrón se generaliza mucho más allá de una app de llamadas:
- Haz que la identidad sea un par de claves y que la ID de usuario sea la clave pública. Genérala en el cliente, nunca transmitas la mitad privada y deja que la cuenta nazca la primera vez que el servidor vea una firma válida.
- Autoriza verificando firmas en lugar de comprobar sesiones. Cada acción lleva una carga útil y una firma. Firma sobre bytes canónicos para que cliente y servidor coincidan en qué se firmó.
- Usa una clave maestra para delegar, no para compartir. Cuando una entidad necesite extender confianza a un segundo dispositivo, a un compañero o a un cliente de API, haz que la clave raíz firme un certificado acotado y revocable para una clave nueva. El secreto raíz nunca se mueve.
- Almacena solo material público, para que la respuesta a “qué pasa si nos filtran” siga siendo anodina.
Algunas restricciones merecen atención antes de lanzar. La custodia de claves se vuelve el problema central, así que los sistemas en producción añaden opciones de recuperación como recuperación social, una copia de seguridad cifrada opcional o una llave de hardware. Las solicitudes firmadas necesitan una marca de tiempo o un nonce para evitar la repetición. Como no hay identidad, la prevención de spam pasa a límites de tasa o invitaciones en lugar de verificación por correo. Nada de esto socava el modelo. Son las preocupaciones habituales de cualquier sistema, sin la base de contraseñas en el medio.
Preguntas frecuentes
¿Cómo puede una app autorizar a un usuario sin autenticación? Trata la posesión de una clave privada como la autoridad. La clave pública sirve de ID de usuario, cada acción se firma con la clave privada correspondiente y el servidor verifica esa firma contra la clave pública. El usuario demuestra que puede actuar sin demostrar su identidad ante un sistema central de cuentas.
¿Es un modelo sin cuenta menos seguro que correo y contraseña? En la mayoría de los aspectos es más seguro. No hay base de contraseñas que filtrar, ni flujo de restablecimiento que abusar, ni datos personales que perder. El compromiso es la custodia de la clave: si un usuario pierde su clave sin copia de seguridad, ninguna autoridad central puede recuperar la cuenta.
¿Cuál es la diferencia entre autenticación y autorización? La autenticación establece quién eres. La autorización establece qué tienes permitido hacer. La mayoría de los sistemas las combinan, pero un par de claves te permite hacer lo segundo sin lo primero.
¿Qué pasa si comprometen los servidores de JustCall? Un atacante encontraría claves públicas y nombres visibles. Las claves públicas están hechas para ser públicas y son inútiles sin las privadas, que nunca salen de tus dispositivos. No hay contraseñas, correos ni números de teléfono que robar.
¿Puedo usar más de un dispositivo sin cuenta? Sí. El primer dispositivo actúa como maestro y firma un certificado que liga la clave pública de cada nuevo dispositivo a tu ID. El secreto maestro nunca se copia, y el maestro puede revocar cualquier dispositivo en cualquier momento.