Mantén la coherencia de las llaves de acceso con las credenciales de tu servidor con la API de Signal

Fecha de publicación: 12 de noviembre de 2024

La API de WebAuthn Signal permite que las partes de confianza indiquen credenciales existentes a los proveedores de llaves de acceso conectados. Con esto, un proveedor de llaves de acceso compatible puede actualizar o quitar las llaves de acceso incorrectas o revocadas de su almacenamiento para que ya no se ofrezcan a los usuarios.

Compatibilidad

Chrome para computadoras admite la API de Signal a partir de Chrome 132. El Administrador de contraseñas de Google puede actualizar las llaves de acceso para que reflejen la señal. En el caso de los proveedores de llaves de acceso basados en extensiones de Chrome, depende de ellos si reflejan el indicador o no.

La compatibilidad con Chrome en Android llegará más adelante.

Safari es compatible, pero aún no se implementó. Firefox aún no comparte sus opiniones.

Segundo plano

Cuando se crea una llave de acceso (una credencial detectable), los metadatos, como un nombre de usuario y un nombre visible, se guardan en el proveedor de llaves de acceso (como un administrador de contraseñas) junto con la clave privada, mientras que la credencial de clave pública se guarda en el servidor de la parte de confianza (RP). Guardar el nombre de usuario y el nombre visible ayuda al usuario a identificar con cuál de las llaves de acceso ofrecidas acceder cuando se le solicite. Esto es especialmente útil cuando tienen más de dos llaves de acceso de diferentes proveedores.

Sin embargo, hay algunos casos en los que las inconsistencias entre la lista de llaves de acceso del proveedor y la lista de credenciales del servidor pueden generar confusión.

El primer caso es cuando un usuario borra una credencial del servidor y deja intacta la llave de acceso en el proveedor de llaves de acceso. La próxima vez que el usuario intente acceder con una llave de acceso, el proveedor de llaves de acceso le presentará esa llave. Sin embargo, el intento de acceso fallará porque el servidor no podrá verificar con la clave pública que se borró.

El segundo caso es cuando un usuario actualiza su nombre de usuario o el nombre visible en el servidor. La próxima vez que el usuario intente acceder, la llave de acceso en el proveedor de llaves de acceso seguirá mostrando el nombre de usuario y el nombre visible anteriores, a pesar de que se hayan actualizado en el servidor. Idealmente, deberían estar sincronizados.

API de Signal

La API de Signal es una API de WebAuthn que resuelve estas confusiones, ya que permite que los RP indiquen cambios al proveedor de llaves de acceso. Existen tres métodos:

Indica que una credencial no existe

const credential = await navigator.credentials.get({ ... });
const payload = credential.toJSON();

const result = await fetch('/login', { ... });

// Detect authentication failure due to lack of the credential
if (result.status === 404) {
  // Feature detection
  if (PublicKeyCredential.signalUnknownCredential) {
    await PublicKeyCredential.signalUnknownCredential({
      rpId: "example.com",
      credentialId: "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA" // base64url encoded credential ID
    });
  } else {
    // Encourage the user to delete the passkey from the password manager nevertheless.
    ...
  }
}

Cuando se llama a PublicKeyCredential.signalUnknownCredential() con un ID de RP y un ID de credencial, el RP puede informar al proveedor de llaves de acceso que la credencial especificada se quitó o no existe. Depende del proveedor de llaves de acceso cómo abordar este indicador, pero se espera que se quite la llave de acceso asociada para que el usuario no acceda con una llave de acceso, ya que la credencial asociada no existe.

Esta API se puede invocar cuando falla un acceso basado en una llave de acceso debido a la ausencia de una credencial. De esta manera, el RP puede evitar que el usuario intente acceder con una llave de acceso que no tenga una credencial asociada. A diferencia de signalAllAcceptedCredentials, este método no requiere pasar toda la lista de IDs de credenciales, por lo que se debe usar cada vez que el usuario no está autenticado para evitar revelar la cantidad de llaves de acceso de un usuario determinado.

Diálogo que se muestra cuando se borra una llave de acceso del Administrador de contraseñas de Google en Chrome.
Un diálogo que se muestra cuando se borra una llave de acceso del Administrador de contraseñas de Google en Chrome.

Señala una lista de credenciales guardadas

// After a user deletes a passkey or a user is signed in.

// Feature detection
if (PublicKeyCredential.signalAllAcceptedCredentials) {
  await PublicKeyCredential.signalAllAcceptedCredentials({
    rpId: "example.com",
    userId: "M2YPl-KGnA8", // base64url encoded user ID
    allAcceptedCredentialIds: [ // A list of base64url encoded credential IDs
      "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA",
      ...
    ]
  });
}

Cuando se llama a PublicKeyCredential.signalAllAcceptedCredentials() con un ID de RP, un ID de usuario y una lista de IDs de credenciales de las credenciales almacenadas, el RP puede informar al proveedor de llaves de acceso las credenciales restantes en su almacenamiento. Depende del proveedor de llaves de acceso cómo abordar este indicador, pero se espera que se quiten las llaves de acceso que no coincidan con esta lista para que el usuario no vea llaves de acceso en el acceso para las que no existe la credencial asociada.

Esta API se debe invocar cuando un usuario borra una llave de acceso en la RP y en cada acceso, de modo que el proveedor de llaves de acceso pueda mantener una lista sincronizada de llaves de acceso.

Se actualizaron el nombre de usuario y el nombre visible del indicador

// After a user updated their username and/or display name
// or a user is signed in.

// Feature detection
if (PublicKeyCredential.signalCurrentUserDetails) {
  await PublicKeyCredential.signalCurrentUserDetails({
    rpId: "example.com",
    userId: "M2YPl-KGnA8", // base64url encoded user ID
    name: "a.new.email.address@example.com", // username
    displayName: "J. Doe"
  });
} else {
}

Cuando llama a PublicKeyCredential.signalCurrentUserDetails() con un ID de RP, un ID de usuario, un nombre de usuario y un nombre visible, el RP puede informar al proveedor de llaves de acceso de la información del usuario actualizada. Depende del proveedor de llaves de acceso cómo manejar este indicador, pero se espera que las llaves de acceso que posee el usuario se actualicen con la nueva información del usuario.

Esta API se puede invocar cuando se actualiza el nombre de usuario o el nombre visible del usuario y en cada acceso, de modo que el proveedor de llaves de acceso pueda mantener esta información sincronizada con el servidor.

Un diálogo que se muestra cuando se actualizan los metadatos de una llave de acceso en el Administrador de contraseñas de Google en Chrome.
Diálogo que se muestra cuando se actualizan los metadatos de una llave de acceso en el Administrador de contraseñas de Google en Chrome.

Resumen

La API de Signal te ayuda a crear una mejor experiencia de llave de acceso, ya que elimina las posibilidades de fallas de acceso inesperadas. Con la API de Signal, las partes de confianza pueden indicar la lista de credenciales existentes y sus metadatos para mantener sincronizadas las llaves de acceso en el proveedor de llaves de acceso.

Para obtener más información sobre las llaves de acceso, consulta Accede sin contraseñas mediante llaves de acceso.