Authagonal
Documentación
Todo lo que necesitas para empezar con Authagonal — desde crear tu primer inquilino hasta configurar SSO, SCIM y personalización de marca.
Primeros pasos
Authagonal proporciona a cada inquilino un servidor OIDC totalmente compatible con estándares. Cada inquilino obtiene su propia URL de emisor, documento de descubrimiento y endpoints de token — sin infraestructura compartida entre inquilinos. Puedes pasar de cero a un flujo de inicio de sesión funcional en menos de 5 minutos.
Crear un inquilino
Regístrate en authagonal.io y elige un slug para tu inquilino. El slug se convierte en tu dominio de emisor: {slug}.authagonal.io. Después de crear tu cuenta, verifica tu dirección de correo electrónico para activar el inquilino.


Elige un slug único para tu inquilino durante el registro
Registrar un cliente
Navega a Clientes en la barra lateral del portal y haz clic en Crear. Ingresa un clientId y un clientName para tu aplicación. Luego configura al menos una URI de redirección — aquí es donde se envían los usuarios después de autenticarse. Por ejemplo: https://app.example.com/callback.


Registrar un nuevo cliente OAuth en el portal
Desarrollo local
http://localhost:3000/callback como URI de redirección para desarrollo local. Authagonal permite URIs de redirección sin HTTPS para orígenes localhost.Tu primer inicio de sesión
La forma más rápida de integrar es con oidc-client-ts, una biblioteca de cliente OIDC ligera para aplicaciones JavaScript y TypeScript.
import { UserManager } from 'oidc-client-ts';
const mgr = new UserManager({
authority: 'https://acme.authagonal.io',
client_id: 'my-app',
redirect_uri: 'https://app.example.com/callback',
response_type: 'code',
scope: 'openid profile email',
});
// Redirect to login
mgr.signinRedirect();
// On callback page
const user = await mgr.signinRedirectCallback();
console.log(user.profile); // { sub, email, name, ... }Si prefieres un enfoque mínimo sin biblioteca, puedes usar el flujo estándar de código de autorización OAuth 2.0 con fetch simple:
// 1. Redirect the user to the authorization endpoint
const authorizeUrl = new URL('https://acme.authagonal.io/connect/authorize');
authorizeUrl.searchParams.set('client_id', 'my-app');
authorizeUrl.searchParams.set('redirect_uri', 'https://app.example.com/callback');
authorizeUrl.searchParams.set('response_type', 'code');
authorizeUrl.searchParams.set('scope', 'openid profile email');
authorizeUrl.searchParams.set('code_challenge', codeChallenge);
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
window.location.href = authorizeUrl.toString();
// 2. On the callback page, exchange the code for tokens
const res = await fetch('https://acme.authagonal.io/connect/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: new URLSearchParams(window.location.search).get('code')!,
redirect_uri: 'https://app.example.com/callback',
client_id: 'my-app',
code_verifier: codeVerifier,
}),
});
const tokens = await res.json();
// tokens.id_token, tokens.access_token, tokens.refresh_token

La página de inicio de sesión predeterminada para tu inquilino
Modo sandbox
{slug}-sandbox.authagonal.io) y pueden actualizarse desde producción en cualquier momento sin afectar a los usuarios activos.Panel de control
El panel de control del portal te ofrece una visión en tiempo real de tu inquilino. Presenta las métricas más importantes — crecimiento de usuarios, actividad de autenticación y navegación rápida a todas las funcionalidades del portal.
Resumen
En la parte superior del panel de control verás un mensaje de bienvenida junto con tu recuento total actual de usuarios. Debajo, un gráfico de Usuarios activos diarios muestra un historial de 7 días de usuarios únicos que se autenticaron cada día, dándote un pulso rápido sobre las tendencias de interacción.


La pantalla principal del panel de control con gráfico de DAU y resumen de actividad
Métricas de actividad
El panel de métricas de actividad muestra cuatro tarjetas de estadísticas que resumen eventos clave de autenticación:
- Inicios de sesión exitosos — flujos de autenticación completados en total
- Inicios de sesión fallidos — credenciales incorrectas, cuentas bloqueadas o rechazos por política
- Usuarios activos — usuarios únicos que se autenticaron en el período seleccionado
- Operaciones SCIM — eventos de aprovisionamiento de usuarios y grupos desde IdPs conectados
Usa los filtros de rango de tiempo para alternar entre 24 horas, 3 días, 7 días y 30 días. Todas las tarjetas de estadísticas y gráficos se actualizan para reflejar la ventana seleccionada.


Métricas de actividad con rango de tiempo configurable
Navegación rápida
Debajo del panel de métricas, las tarjetas de navegación enlazan directamente a cada funcionalidad principal: Clientes, Usuarios, Grupos, Roles, SSO, SCIM, Marca y Configuración. Cada tarjeta muestra una breve descripción para que los nuevos miembros del equipo puedan orientarse rápidamente.
Clientes
Los clientes OAuth representan las aplicaciones que autentican usuarios a través de tu inquilino. Cada cliente tiene su propia configuración de URIs de redirección, alcances, tipos de concesión, duraciones de tokens y política de MFA.
Lista de clientes
La página de Clientes muestra una tabla con todos los clientes registrados. Cada fila muestra el clientId, nombre para mostrar, tipos de concesión permitidos como insignias de colores y si PKCE está habilitado. Haz clic en cualquier fila para abrir el editor de configuración completo.


Lista de clientes con insignias de tipo de concesión e indicadores de PKCE
Crear un cliente
Haz clic en Crear cliente para registrar una nueva aplicación. Necesitas proporcionar dos campos:
clientId— un identificador único para el cliente (por ejemplo,my-spa)clientName— un nombre para mostrar legible por humanos


Registrar un nuevo cliente OAuth
Eliminar un cliente
Para eliminar un cliente, abre la configuración del cliente y haz clic en el botón Eliminar cliente en la parte inferior de la página. Se te pedirá confirmar antes de que el cliente sea eliminado permanentemente. Todas las sesiones activas y tokens del cliente eliminado se invalidan inmediatamente.
Referencia de configuración de cliente
Cada cliente tiene un conjunto completo de opciones de configuración organizadas en varias secciones.
Configuración general
| Configuración | Descripción | Predeterminado |
|---|---|---|
clientName | Nombre para mostrar en las pantallas de consentimiento y el portal | — |
requirePkce | Requerir Proof Key for Code Exchange en los flujos de código de autorización | Activado |
requireClientSecret | Requerir un secreto de cliente para solicitudes de token (deshabilitar para clientes públicos como SPAs) | Desactivado |
allowOfflineAccess | Permitir que el cliente solicite tokens de actualización a través del alcance offline_access | Desactivado |
alwaysIncludeUserClaimsInIdToken | Incluir todas las reclamaciones del usuario directamente en el token de ID en lugar de requerir una llamada a UserInfo | Desactivado |
includeGroupsInTokens | Incluir las membresías de grupo del usuario como una reclamación groups en el token de ID | Desactivado |
Seguridad PKCE
URIs
Los campos de URI utilizan una entrada de etiquetas — escribe un valor y presiona Enter o coma para añadirlo. Haz clic en la X de cualquier etiqueta para eliminarla.
| Configuración | Descripción |
|---|---|
redirectUris | URLs de callback permitidas después de la autenticación. Deben coincidir exactamente con el parámetro redirect_uri en las solicitudes de autorización. |
postLogoutRedirectUris | URLs permitidas para redirigir después del cierre de sesión. |
allowedCorsOrigins | Orígenes permitidos para solicitudes de origen cruzado a los endpoints de token y UserInfo. |


Campos de entrada de etiquetas para configurar URIs
Alcances y tipos de concesión
| Configuración | Opciones |
|---|---|
allowedScopes | openid profile email offline_access |
allowedGrantTypes | authorization_code client_credentials refresh_token device_code |
Duraciones de tokens
| Configuración | Descripción | Predeterminado |
|---|---|---|
accessTokenLifetimeSeconds | Cuánto tiempo son válidos los tokens de acceso | 1800 (30 min) |
identityTokenLifetimeSeconds | Cuánto tiempo son válidos los tokens de ID | 300 (5 min) |
authorizationCodeLifetimeSeconds | Cuánto tiempo son válidos los códigos de autorización para el intercambio | 300 (5 min) |
absoluteRefreshTokenLifetimeSeconds | Duración máxima de un token de actualización independientemente de la actividad | 2592000 (30 días) |
slidingRefreshTokenLifetimeSeconds | La expiración del token de actualización se reinicia con cada uso, hasta la duración absoluta | 1296000 (15 días) |


Configurar duraciones de tokens por cliente
URIs de logout
Los clientes pueden registrar URIs de logout tanto back-channel como front-channel. Ambas son opcionales — configura las que coincidan con cómo tu aplicación limpia su sesión.
| Configuración | Descripción |
|---|---|
backChannelLogoutUri | POST servidor a servidor con un token de logout firmado. Fiable incluso si el navegador está offline. |
frontChannelLogoutUri | Se carga en un iframe oculto durante el logout para que el navegador limpie cookies y almacenamiento local. |
frontChannelLogoutSessionRequired | Si está activo, la URL de logout recibe los parámetros iss y sid para que tu app correlacione el logout con la sesión específica. |
Usa ambos juntos
Política de MFA
Cada cliente puede anular la política de MFA a nivel de inquilino con una configuración por cliente. El menú desplegable de política de MFA ofrece tres opciones:
| Política | Comportamiento |
|---|---|
| Deshabilitado | MFA nunca se solicita para este cliente |
| Habilitado | Los usuarios pueden inscribirse opcionalmente en MFA; se les solicitará si están inscritos |
| Obligatorio | Todos los usuarios deben completar MFA para autenticarse a través de este cliente |


Anulación de política de MFA por cliente
SSO empresarial
El SSO empresarial permite que tus clientes traigan su propio proveedor de identidad. Authagonal soporta tanto la federación SAML 2.0 como OIDC con enrutamiento basado en dominio, para que los usuarios sean dirigidos automáticamente al IdP correcto según su dirección de correo electrónico.
Enrutamiento SSO basado en dominio
Conexiones SAML 2.0
Para crear una conexión SAML, navega a la página de SSO y selecciona la pestaña SAML. Proporciona lo siguiente:
| Campo | Descripción |
|---|---|
connectionName | Un nombre legible para esta conexión (por ejemplo, "Acme Corp Okta") |
entityId | Su ID de entidad del SP. Registre exactamente este valor en su IdP como identificador (Entity ID) de la aplicación; las aserciones deben nombrarlo como Audience |
metadataUrl | URL del documento XML de metadatos SAML del IdP |
metadataXml | XML de metadatos del IdP pegado, para IdP sin URL de metadatos (Google Workspace) o cuya URL no es accesible desde Internet. Proporcione esto o metadataUrl, no ambos |
nameIdFormat | Formato de NameID opcional solicitado al IdP. Omítalo para el valor predeterminado emailAddress, o use "none" para omitir NameIDPolicy por completo (recomendado para ADFS) |
Cuando guardas la conexión, Authagonal obtiene el documento de metadatos e importa el certificado de firma del IdP, la URL del endpoint SSO y el formato del identificador de nombre. Los metadatos se actualizan periódicamente para incorporar las rotaciones de certificados.


Crear una conexión SSO SAML 2.0
Conexiones OIDC
Para crear una conexión de federación OIDC, selecciona la pestaña OIDC y proporciona:
| Campo | Descripción |
|---|---|
connectionName | Un nombre legible para esta conexión |
discoveryUrl | La URL de descubrimiento OpenID Connect (por ejemplo, https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration) |
clientId | El client ID registrado con el IdP externo para esta federación |
clientSecret | El client secret para el registro del IdP externo |


Crear una conexión de federación OIDC
Enrutamiento de dominio
El enrutamiento de dominio redirige automáticamente a los usuarios al proveedor de identidad correcto según el dominio de su correo electrónico. Cuando un usuario ingresa su correo en la página de inicio de sesión, Authagonal verifica si la parte del dominio (por ejemplo, acme.com) coincide con alguna conexión SSO configurada. Si coincide, el usuario es redirigido de forma transparente al IdP de su organización.
| Dominio de correo electrónico | Proveedor SSO | Protocolo |
|---|---|---|
| acme.com | Acme Corp Okta | SAML 2.0 |
| contoso.com | Contoso Azure AD | OIDC |
| example.org | Example OneLogin | SAML 2.0 |


El enrutamiento de dominio mapea dominios de correo electrónico a proveedores de identidad
Flujo iniciado por SP
/saml/{connectionId}/login o /oidc/{connectionId}/login.Aprovisionamiento JIT
Por defecto, cuando un usuario inicia sesión a través de SSO por primera vez y no existe ya en tu inquilino, Authagonal crea su cuenta automáticamente (aprovisionamiento Just-In-Time). Esto se puede deshabilitar por conexión marcando Deshabilitar aprovisionamiento JIT al crear o editar la conexión.
Cuando el aprovisionamiento JIT está deshabilitado, solo los usuarios que han sido pre-aprovisionados — a través de SCIM, la página de Usuarios del portal o la API — pueden iniciar sesión a través de esa conexión. Los usuarios desconocidos reciben un error access_denied y son dirigidos a contactar a su administrador.
Configuración por conexión
Probar antes de implementar
Usuarios
La página de Usuarios te permite gestionar todos los usuarios finales en tu inquilino. Puedes buscar usuarios, ver sus detalles, crear nuevas cuentas y ver cómo fue aprovisionado cada usuario.
Búsqueda y paginación
La barra de búsqueda admite filtrado por dirección de correo electrónico o ID de usuario. La búsqueda tiene un retardo de 300ms para que los resultados se actualicen mientras escribes sin sobrecargar la API. Los resultados están paginados a 50 usuarios por página — usa los controles de navegación en la parte inferior de la tabla para moverte entre páginas.
Tabla de usuarios
La tabla de usuarios muestra las siguientes columnas para cada usuario:
| Columna | Descripción |
|---|---|
| Correo electrónico | La dirección de correo electrónico del usuario, mostrada con una insignia de verificación si el correo ha sido confirmado |
| ID de usuario | El identificador único asignado al usuario |
| Nombre completo | Nombre y apellido combinados |
| Estado | Active o Inactive — indica si la cuenta está habilitada |
| MFA | Enabled o Off — si la autenticación multifactor está inscrita |
| Origen | SCIM o Local — cómo fue creado el usuario |
| Creado | La fecha en que se creó la cuenta de usuario |


La lista de usuarios con barra de búsqueda y paginación
Crear usuarios
Haz clic en Crear usuario para añadir un nuevo usuario local. El formulario requiere:
| Campo | Descripción |
|---|---|
email | La dirección de correo electrónico del usuario (debe ser única dentro del inquilino) |
password | Contraseña inicial (mínimo 8 caracteres, debe cumplir con la política de contraseñas de tu inquilino) |
firstName | El nombre del usuario |
lastName | El apellido del usuario |
language | Idioma preferido. Define el idioma de la interfaz y de los correos del usuario; opcional, recurre al inglés. |


Crear un nuevo usuario local
Usuarios aprovisionados por SCIM
Idioma preferido
Cada usuario tiene un idioma preferido que controla tanto su interfaz alojada como los correos transaccionales que Authagonal le envía (verificación, restablecimiento de contraseña, bienvenida y más). Puedes definirlo al crear un usuario y cambiarlo en cualquier momento desde su página de detalle. Si un usuario no tiene un idioma preferido definido, Authagonal recurre al inglés. El selector ofrece todos los idiomas soportados: inglés, alemán, francés, español, portugués, vietnamita y chino simplificado.


Definir el idioma preferido de un usuario en su página de detalle
Detalle del usuario
Haz clic en cualquier fila de la lista de usuarios para abrir su página de detalle. Desde ahí puedes editar datos de perfil, gestionar roles, restablecer MFA, revisar atributos personalizados y eliminar al usuario.


Perfil
Edita correo electrónico, nombre/apellidos, teléfono, empresa, ID externo y el indicador de activo del usuario. Los cambios de correo deben permanecer únicos en el inquilino; la API devuelve email_in_use si ya está en uso.
Roles
Asigna y retira roles definidos en la página Roles. La pertenencia a roles se incluye en los tokens ID y de acceso cuando el cliente tiene activado includeRolesInTokens.
Autenticación multifactor
Consulta todas las credenciales MFA registradas para el usuario — aplicación autenticadora (TOTP), WebAuthn/passkeys y códigos de recuperación — cada una con marcas de tiempo de registro y último uso. Elimina credenciales individuales o restablece todo MFA. Restablecer obliga al usuario a volver a registrarse en el próximo inicio de sesión.
Atributos personalizados
Datos clave/valor arbitrarios asociados al usuario. Las claves deben ser únicas. Los atributos se exponen vía la API de perfil de usuario y SCIM, y pueden mapearse a reclamaciones del token de acceso configurando los userClaims de un ámbito personalizado.
Organización
La organización a la que pertenece este usuario. Es un identificador de texto libre propio, emitido como reclamación org_id en sus tokens y en /connect/userinfo bajo el ámbito profile. Authagonal nunca lo deriva: lo define tu aplicación de aprovisionamiento, el token SCIM que creó al usuario, o tú mismo a mano aquí.
El enlace junto al campo lista a todos los que comparten ese valor, y el mismo filtro está disponible en la API como GET /api/v1/users?organizationId=. Úsalo para saber quién pertenece a un cliente final concreto sin paginar todo el directorio.
Eliminar usuario
Elimina permanentemente al usuario y todas sus credenciales MFA. Escribe el correo del usuario para confirmar — no hay deshacer.
Grupos
Los grupos te permiten organizar usuarios e incluir la membresía de grupo en los tokens. Los grupos pueden crearse manualmente en el portal o aprovisionarse automáticamente a través de SCIM desde un proveedor de identidad externo.
Lista de grupos
La página de Grupos muestra todos los grupos en tu inquilino con la siguiente información:
| Columna | Descripción |
|---|---|
| Nombre del grupo | El nombre para mostrar del grupo |
| Miembros | El número de usuarios actualmente en el grupo |
| Origen | SCIM o Manual — cómo fue creado el grupo |
| Creado | La fecha en que se creó el grupo |


Lista de grupos con indicadores de origen
Crear un grupo
Haz clic en Crear grupo e ingresa un displayName para el grupo. Los nombres de grupo deben ser descriptivos y únicos dentro de tu inquilino (por ejemplo, "Engineering", "Billing Admins", "Beta Testers").
Detalle del grupo y miembros
Haz clic en cualquier grupo para abrir la vista de detalle. Aquí puedes ver todos los miembros actuales y gestionar la membresía:
- Añadir miembros — Ingresa un ID de usuario para añadir un usuario al grupo.
- Eliminar miembros — Haz clic en el botón de eliminar junto a cualquier miembro para eliminarlo individualmente.


Gestionar la membresía del grupo en la vista de detalle
Grupos en tokens
Cuando includeGroupsInTokens está habilitado en un cliente, el token de ID incluye una reclamación groups que contiene las membresías de grupo del usuario. Cada entrada incluye el id y name del grupo:
{
"sub": "user-123",
"email": "[email protected]",
"groups": [
{ "id": "grp-001", "name": "Engineering" },
{ "id": "grp-002", "name": "Beta Testers" }
]
}Habilitar por cliente
includeGroupsInTokens se configura en cada cliente individualmente. Navega a la Configuración general del cliente para habilitarla.Roles
Los roles soportan el control de acceso basado en roles (RBAC) en tu aplicación. Define roles en Authagonal, asígnalos a usuarios y usa la reclamación roles en los tokens para aplicar la autorización en la lógica de tu aplicación.
Gestionar roles
La página de Roles muestra una tabla con todos los roles definidos con edición en línea. Cada rol tiene:
| Columna | Descripción |
|---|---|
| Nombre | Un identificador único para el rol (por ejemplo, "admin", "editor", "viewer") |
| Descripción | Una descripción legible de lo que otorga el rol |
| Creado | La fecha en que se creó el rol |
Crear un rol
Haz clic en Crear rol y proporciona un nombre y una descripción. Los nombres de los roles deben ser concisos y seguir una convención de nomenclatura consistente en tu aplicación (por ejemplo, minúsculas con guiones: billing-admin).
Edición en línea
Los roles soportan edición en línea directamente en la tabla. Haz clic en el icono de lápiz en cualquier rol para entrar en modo de edición — los campos de nombre y descripción se vuelven editables. Modifica los valores y luego haz clic en el icono de marca de verificación para guardar. Los cambios entran en vigor inmediatamente.
Eliminar un rol
Haz clic en el icono de eliminar en cualquier rol para eliminarlo. Se te pedirá confirmar antes de que el rol sea eliminado permanentemente. Eliminar un rol no invalida retroactivamente los tokens existentes — el rol estará ausente de los nuevos tokens emitidos después de la eliminación.


Edición en línea de roles en la tabla de roles
Roles en tokens
Los roles asignados a un usuario se incluyen como una reclamación roles en el token de ID. Tu aplicación puede leer esta reclamación para tomar decisiones de autorización:
{
"sub": "user-123",
"email": "[email protected]",
"roles": ["admin", "billing-admin"]
}Aprovisionamiento SCIM
SCIM 2.0 (System for Cross-domain Identity Management) permite el aprovisionamiento automático de usuarios y grupos desde proveedores de identidad empresariales como Okta, Azure AD, OneLogin y JumpCloud. Una vez configurado, las cuentas de usuario y las membresías de grupo se sincronizan automáticamente desde el IdP ascendente a tu inquilino de Authagonal.
Sincronización del ciclo de vida de usuarios SCIM con aprovisionamiento descendente
Pasos de configuración
Sigue estos pasos para habilitar el aprovisionamiento SCIM para un cliente:
- Selecciona la aplicación cliente — Elige el cliente OAuth con el que se asociará el aprovisionamiento SCIM.
- Genera un token SCIM — Proporciona una descripción y un período de expiración en días, luego genera el token.
- Copia el token inmediatamente — El valor del token sin procesar se muestra solo una vez. Cópialo antes de cerrar el diálogo.
- Configura tu IdP — En la configuración SCIM de tu proveedor de identidad, ingresa la URL base y el token bearer.
- Prueba la sincronización de usuarios — Activa una sincronización de prueba desde tu IdP y verifica que los usuarios aparezcan en el portal de Authagonal.
URL base de SCIM
Configura tu proveedor de identidad con la siguiente URL base:
https://{slug}.authagonal.io/scim/v2Reemplaza {slug} con el slug de tu inquilino.


Página de configuración SCIM con generación de tokens
Gestión de tokens
Los tokens SCIM autentican las solicitudes de aprovisionamiento desde tu IdP. Puedes gestionar múltiples tokens por cliente:
| Campo | Descripción |
|---|---|
| Descripción | Una etiqueta para identificar el token (por ejemplo, "Okta Production SCIM") |
| Expiración | Duración del token en días (1 a 3650). Deja en blanco o establece un valor largo para tokens que no deben rotarse frecuentemente. |
| Estado | Los tokens activos están en uso. Los tokens revocados muestran una Revoked insignia y ya no pueden autenticar solicitudes. |
Para revocar un token, haz clic en el botón Revocar junto a él. Los tokens revocados permanecen visibles en la lista con fines de auditoría pero dejan de aceptar solicitudes inmediatamente.


Gestión de tokens con indicadores de tokens activos y revocados
Copia el token inmediatamente
Probar la conectividad
Verifica que tu integración SCIM está funcionando consultando el endpoint ServiceProviderConfig:
curl -H "Authorization: Bearer YOUR_TOKEN" \ https://acme.authagonal.io/scim/v2/ServiceProviderConfig
Una respuesta exitosa devuelve un documento JSON que describe las funcionalidades SCIM soportadas, incluyendo operaciones masivas, filtrado y capacidad de cambio de contraseña.
Idioma preferido
preferredLanguage (con recurso a locale) se asigna al idioma almacenado del usuario. Los usuarios SSO aprovisionados mediante SCIM reciben automáticamente correos localizados en el idioma que envía su IdP.Qué puede ver un token
Un token SCIM solo ve los usuarios y grupos que él mismo aprovisionó. Leer, actualizar o eliminar un usuario creado por otro conector responde 404, el listado devuelve solo los propios y la membresía de un grupo solo puede nombrar usuarios aprovisionados por ese mismo conector. Las cuentas creadas de cualquier otra forma, por un administrador, por registro de autoservicio o por aprovisionamiento justo a tiempo mediante SSO, son completamente invisibles para SCIM.
Ese límite es por cliente OAuth, no por token. Dos tokens emitidos sobre el mismo cliente OAuth son una sola identidad con dos secretos, y cada uno puede modificar lo que creó el otro. Da a cada conector que no confíe en los demás su propio cliente OAuth. externalId tiene el mismo alcance, así que dos conectores pueden usar cada uno ext-001 para personas distintas sin colisionar.
Desaprovisionamiento
DELETE /scim/v2/Users/{id} desactiva la cuenta y la marca como eliminada. El registro se conserva, tal como permite RFC 7644, pero responde 404 a cualquier operación posterior y se omite de los listados. Sus inscripciones MFA y sus membresías de grupo se purgan, su asignación de externalId se libera y todos los tokens emitidos se revocan, de modo que el acceso termina de inmediato y no en la siguiente expiración de token.
Si más adelante se vuelve a contratar a la misma persona y se crea de nuevo, recibe un nuevo ID de usuario. Los identificadores nunca se reutilizan: el ID es el sujeto de cada token que has emitido, así que reutilizarlo daría de forma silenciosa al nuevo empleado el historial del titular anterior en todas las aplicaciones que confían en él.
Etiquetar usuarios sincronizados con una organización
SCIM no ofrece a un conector ninguna forma de indicar cuál de tus clientes finales está sincronizando. El SCIM básico no define ningún atributo de organización, así que una creación de usuario simple te da el nombre y el correo de la persona y nada sobre a quién pertenece. Si varios clientes finales aprovisionan en tu inquilino, sus usuarios llegan indistinguibles.
Es el token el que lo responde, no la solicitud. Cuando creas un token SCIM, asigna a Organización un identificador propio. Cada usuario aprovisionado mediante ese token queda etiquetado con él, y a partir de entonces se emite como reclamación org_id en sus tokens. Emite un token por cada cliente final sobre el mismo cliente OAuth y sus usuarios sincronizados quedan correctamente atribuidos sin necesidad de registrar un cliente OAuth para cada uno. Déjalo en blanco y los usuarios quedan sin etiquetar, que es como se comportaba cada token antes de que esto existiera.
Etiquetar no es aislar
La etiqueta se aplica cuando se crea el usuario y nunca en una actualización posterior, de modo que una sincronización incremental rutinaria no puede mover de forma silenciosa una cuenta existente. Si además ejecutas una aplicación de aprovisionamiento, la etiqueta explícita del token prevalece: una respuesta de /try solo rellena una organización que todavía está vacía.
Esquemas soportados
Implementamos los esquemas básicos User y Group de SCIM 2.0 (RFC 7643). Los atributos de usuario soportados son userName, name.givenName, name.familyName, displayName, emails, active, externalId y preferredLanguage / locale.
La extensión enterprise user no está implementada, por lo que department, manager, employeeNumber, costCenter, division y organization se aceptan y se ignoran en lugar de almacenarse, tanto en la creación como en el reemplazo y en PATCH. Entra y Okta mapean algunos de ellos por defecto, así que no necesitas quitarlos de tu mapeo de atributos. Para atribuir un usuario a uno de tus clientes finales, define la organización en el token SCIM: el atributo enterprise organization lo afirma el proveedor de identidad de tu cliente final, y deliberadamente no se convierte en la org_id del usuario.
Ámbitos de OAuth
Los ámbitos permiten a los clientes solicitar porciones específicas de los datos o permisos de un usuario. Authagonal admite tanto los ámbitos estándar de OIDC como los ámbitos personalizados que definas para tus API.
Ámbitos integrados
| Ámbito | Descripción |
|---|---|
openid | Obligatorio para cualquier flujo de OpenID Connect. Emite un token de identidad. |
profile | Devuelve reclamaciones estándar de perfil (name, given_name, family_name). |
email | Devuelve el correo electrónico del usuario y su estado de verificación. |
offline_access | Emite un token de actualización junto al token de acceso. |
Ámbitos personalizados
Define tus propios ámbitos en la página Ámbitos. Cada ámbito describe un permiso o recurso que un cliente puede solicitar (por ejemplo, billing.read, orders.write).


| Campo | Descripción |
|---|---|
name | El identificador del ámbito enviado en las solicitudes de token (p. ej. billing.read). |
displayName | Etiqueta legible mostrada en la pantalla de consentimiento. |
description | Explicación más larga mostrada bajo el nombre en el consentimiento. |
userClaims | Reclamaciones adicionales añadidas al token de acceso cuando se concede este ámbito. |
showInDiscoveryDocument | Si está activo, el ámbito aparece en /.well-known/openid-configuration. |
emphasize | Destaca el ámbito en la pantalla de consentimiento como sensible. |
required | Impide que el usuario deseleccione el ámbito durante el consentimiento. |
Integración con el consentimiento
Reclamaciones personalizadas en los tokens
Las reclamaciones personalizadas tienen dos mitades. La fuente son los datos por usuario: cada AuthUser tiene un diccionario customAttributes que puedes poblar desde el Portal (Usuarios → usuario → Atributos personalizados), vía SCIM o mediante un hook de aprovisionamiento TCC. La liberación es por ámbito: la lista userClaims de cada ámbito nombra las claves que pueden salir del servidor.
Cuando un cliente solicita ámbitos, Authagonal recorre los ámbitos concedidos, une sus listas userClaims y emite solo esas claves de los customAttributes del usuario. Las claves desconocidas se descartan silenciosamente — un cliente no puede leer un atributo adivinando su nombre. Las reclamaciones OIDC estándar (sub, email, name, etc.) siguen la especificación y no están sujetas a la lista de permitidos.
# 1. On the user (Portal → Users → {user} → Custom Attributes)
department = "engineering"
employee_id = "E-1042"
seat_tier = "enterprise"
# 2. On a custom scope (Portal → Scopes → projects.read)
name = "projects.read"
userClaims = ["department", "seat_tier"] # <-- whitelist
# 3. Client requests scope=openid projects.read
# Decoded access token (relevant fields only):
{
"sub": "u-9b…",
"scope": "openid projects.read",
"department": "engineering",
"seat_tier": "enterprise"
// employee_id is NOT emitted — it's not in the whitelist for any granted scope.
}Las reclamaciones de federación tienen prioridad por sesión
department mapeado desde una aserción SAML — pasan por la misma lista de permitidos de ámbitos pero ganan en colisión de claves frente a los customAttributes persistidos. Se emiten en los tokens de esta sesión (y sobreviven a las rotaciones de refresh) sin escribirse de vuelta en el registro del usuario.Asignar ámbitos a clientes
Añade los ámbitos permitidos en la pestaña Clientes → Ámbitos y Concesiones. Un cliente solo puede solicitar ámbitos que se le hayan concedido; los ámbitos desconocidos se rechazan con invalid_scope.
Marca
Personaliza la apariencia de las páginas de inicio de sesión de tu inquilino. La configuración de marca te permite hacer coincidir la experiencia de autenticación con la identidad visual de tu producto — desde logotipos y colores hasta personalizaciones avanzadas de CSS.
Apariencia
| Configuración | Descripción |
|---|---|
appName | El nombre de la aplicación mostrado en el encabezado de la página de inicio de sesión y la pestaña del navegador |
logoUrl | URL de la imagen de tu logotipo. Se muestra en la parte superior de la página de inicio de sesión. Tamaño recomendado: 200x60px o relación de aspecto similar. |
primaryColor | El color primario de marca utilizado para botones, enlaces y estados de enfoque. Se establece a través de un selector de color o entrada hexadecimal. Una vista previa en vivo se actualiza a medida que cambias el valor. |
customCssUrl | URL de un archivo CSS externo cargado después de los estilos predeterminados. Úsalo para personalizaciones avanzadas de estilo. |


Configuración de apariencia con vista previa de color en vivo
Información de contacto
| Configuración | Descripción |
|---|---|
supportEmail | Una dirección de correo electrónico de soporte mostrada en las páginas de inicio de sesión. Los usuarios la ven cuando necesitan ayuda con su cuenta. |
Controles de la página de inicio de sesión
Controla qué elementos aparecen en la página de inicio de sesión de tu inquilino:
| Interruptor | Descripción | Predeterminado |
|---|---|---|
showForgotPassword | Mostrar el enlace "¿Olvidaste tu contraseña?" en el formulario de inicio de sesión | Activado |
showRegistration | Mostrar el enlace "Registrarse" para el registro de usuarios de autoservicio | Activado |
showPoweredBy | Mostrar la insignia "Powered by Authagonal" en la parte inferior de la página de inicio de sesión | Activado |


Ejemplo de página de inicio de sesión con marca personalizada aplicada
CSS personalizado
Para un control total sobre la apariencia de la página de inicio de sesión, proporciona la URL de un archivo CSS en tus ajustes de marca. El archivo se carga después de los estilos por defecto, por lo que tus reglas tienen prioridad.
Propiedades personalizadas CSS
| Variable | Descripción | Predeterminado |
|---|---|---|
--auth-bg | Color de fondo de la página | #f3f4f6 |
--auth-card-bg | Fondo de la tarjeta de inicio de sesión | white |
--auth-heading | Color del texto del encabezado | #111827 |
--auth-radius | Radio del borde de la tarjeta | 0.5rem |
--auth-font | Familia de fuente | inherit |
Modo oscuro
La app de inicio de sesión incluye temas claro, oscuro y del sistema. Los usuarios eligen desde un conmutador en la página de login; la elección se mantiene entre sesiones. Cuando está en system, la SPA sigue prefers-color-scheme en tiempo real.
Los valores claros se declaran en :root; las anulaciones oscuras están limitadas a .dark. El branding del inquilino mediante customCssUrl siempre prevalece — tus colores se mantienen sin importar el tema del usuario.
Selectores de elementos
data-auth. Estos selectores son estables entre actualizaciones — no se romperán cuando cambiemos los nombres de clase internos.| Selector | Elemento |
|---|---|
[data-auth="page"] | Contenedor de fondo de página completa |
[data-auth="header"] | Área de logo y nombre de la app |
[data-auth="logo"] | Imagen del logo |
[data-auth="app-name"] | Encabezado del nombre de la app (cuando no hay logo) |
[data-auth="content"] | Área de contenido principal (formularios, mensajes) |
[data-auth="login-form"] | Elemento de formulario de inicio de sesión |
[data-auth="email-field"] | Contenedor del campo de correo |
[data-auth="password-field"] | Contenedor del campo de contraseña |
[data-auth="submit-button"] | Botón de inicio de sesión |
[data-auth="languages"] | Barra de selector de idioma |
Configuración
Configura las políticas de seguridad, webhooks y configuración del entorno a nivel de inquilino. Estas configuraciones se aplican globalmente a todos los clientes a menos que se anulen a nivel de cliente.
Política de contraseñas
Define los requisitos de complejidad de contraseña para todos los usuarios en tu inquilino:
| Configuración | Rango | Predeterminado |
|---|---|---|
minPasswordLength | 6 – 128 | 8 |
requireUppercase | Activado / Desactivado | Activado |
requireLowercase | Activado / Desactivado | Activado |
requireDigit | Activado / Desactivado | Activado |
requireSpecialChar | Activado / Desactivado | Activado |


Configuración de la política de contraseñas
Política de MFA
La política de MFA a nivel de inquilino establece el comportamiento predeterminado de autenticación multifactor. Los clientes individuales pueden anular esta configuración.
| Política | Comportamiento |
|---|---|
Disabled | MFA no está disponible. Los usuarios no pueden inscribirse en MFA. |
Enabled | MFA es opcional. Los usuarios pueden elegir inscribirse y se les solicitará al iniciar sesión si están inscritos. |
Required | MFA es obligatorio. Todos los usuarios deben inscribirse en MFA y completar un segundo factor en cada inicio de sesión. |
Sesión y bloqueo
Controla la duración de la sesión y el comportamiento de bloqueo de cuenta:
| Configuración | Rango | Predeterminado |
|---|---|---|
sessionLifetimeMinutes | 5 – 43.200 (30 días) | 60 |
maxFailedAttempts | 1 – 100 | 5 |
lockoutDurationMinutes | 1 – 1.440 (24 horas) | 10 |


Configuración de sesión y bloqueo
Webhooks
Los webhooks te permiten reaccionar a eventos de autenticación en tiempo real. Dos eventos (onUserAuthenticated, onTokenIssued) son aplicables — por defecto se disparan de forma asíncrona y no bloquean al usuario, pero puedes activar la aplicación por evento para que una respuesta no 2xx o un cuerpo {"allow": false} rechace la acción. El resto de eventos son notificaciones — siempre fire-and-forget, nunca bloquean.
| Evento | Tipo | Descripción |
|---|---|---|
onUserAuthenticated | Aplicable | Disparado tras un inicio de sesión exitoso. Por defecto es fire-and-forget para que la latencia del login no se vea afectada. Activa <code>webhookEnforceUserAuthenticated</code> para hacerlo bloqueante — una respuesta no 2xx o un cuerpo <code>{"allow": false}</code> rechazará entonces el inicio de sesión. |
onTokenIssued | Aplicable | Disparado antes de emitir tokens (authorization_code, refresh_token, client_credentials). Por defecto es fire-and-forget. Activa <code>webhookEnforceTokenIssued</code> para hacerlo bloqueante — una respuesta no 2xx o un cuerpo <code>{"allow": false}</code> impedirá entonces la emisión del token. |
onUserCreated | Notificación | Notificación de tipo dispara y olvida cuando un nuevo usuario se registra o es aprovisionado a través de SCIM. |
onUserUpdated | Notificación | Notificación fire-and-forget cuando se actualiza un registro de usuario (cambios de perfil, cambios de rol, actualizaciones SCIM). |
onUserDeleted | Notificación | Notificación fire-and-forget cuando se elimina un usuario, ya sea desde el Portal/SCIM o por la política de retención. |
onLoginFailed | Notificación | Notificación de tipo dispara y olvida cuando un intento de inicio de sesión falla por credenciales incorrectas, bloqueo o rechazo de política. |
Configuraciones adicionales de webhooks:
| Configuración | Rango | Predeterminado | Descripción |
|---|---|---|---|
webhookTimeoutSeconds | 1 – 30 | 5 | Tiempo máximo de espera para una respuesta de webhook de aplicación antes de que expire |
webhookFailOpen | Activado / Desactivado | Activado | Cuando está habilitado, si un webhook de aplicación no es alcanzable o expira, la operación se permite continuar |


Configuración de eventos de webhook
Disponibilidad de webhooks de aplicación
webhookFailOpen está deshabilitado, ningún usuario podrá iniciar sesión. Usa el modo de apertura por fallo a menos que tengas requisitos estrictos de cumplimiento que exijan bloqueo en caso de fallo del webhook.Verificar webhooks
Una vez configurada cualquier URL de webhook, Authagonal genera un secreto de firma por inquilino (un valor whsec_… que se muestra en modo de solo lectura en Ajustes → Webhooks). Cada entrega saliente lleva una cabecera X-Authagonal-Signature: t=<unix>,v1=<hex>, donde v1 es HMAC-SHA256(secret, "{t}.{body}") calculado sobre el cuerpo crudo de la solicitud. Vuelve a calcularlo en tu endpoint y compáralo en tiempo constante para confirmar que la solicitud realmente provino de Authagonal y no fue manipulada — y rechaza las entregas cuyo t sea demasiado antiguo para bloquear repeticiones.
import crypto from 'node:crypto';
// rawBody MUST be the exact bytes Authagonal sent — verify before any JSON re-serialization.
function verifyAuthagonalWebhook(signatureHeader, rawBody, signingSecret) {
const parts = Object.fromEntries(signatureHeader.split(',').map((p) => p.split('=')));
const { t, v1 } = parts;
// Replay protection: reject deliveries older than 5 minutes.
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = crypto
.createHmac('sha256', signingSecret)
.update(`${t}.${rawBody}`)
.digest('hex');
return v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}Rotar el secreto de firma
Ventana de mantenimiento
Establece una ventana de mantenimiento preferida para operaciones disruptivas como rotaciones de certificados y actualizaciones de infraestructura. Elige una hora UTC (0-23) — el portal también muestra la hora equivalente en tu zona horaria local para mayor comodidad.
Registro y acceso
Quién puede convertirse en usuario de tu inquilino, y en qué condiciones puede iniciar sesión.
| Configuración | Predeterminado | Descripción |
|---|---|---|
| Registro público | Activado | Si cualquiera puede registrarse por su cuenta. Desactivarlo oculta la página de registro y rechaza la API de registro, lo cual importa: ocultar solo el enlace dejaría el endpoint abierto. Úsalo cuando aprovisionas tú mismo a los usuarios mediante SCIM, la API o invitaciones. |
| Exigir verificación del correo para iniciar sesión | Activado | Una dirección sin confirmar no puede iniciar sesión. Desactívalo si es tu propia aplicación la que controla la verificación; la reclamación email_verified sigue viajando en el token en cualquier caso, así que conservas la señal. |
| Registro dinámico de clientes | Desactivado | Permite que un cliente se registre a sí mismo en tiempo de ejecución conforme al RFC 7591, que es lo que necesita un agente de IA o un conector MCP antes de poder iniciar un flujo. Desactivado de forma predeterminada, y habilitarlo abre la puerta solo para tu inquilino. Los registros siguen con límite de tasa y siguen exigiendo PKCE y consentimiento en cualquier caso. |
| Política de MFA del portal | Deshabilitado | El multifactor para tu propio equipo cuando inicia sesión en el portal, configurado de forma independiente de la política de tus usuarios finales. Deshabilitado, ofrecido en el inicio de sesión u obligatorio. |
| Máximo de usuarios | El límite de tu plan | Un límite estricto de usuarios totales, aplicado en el único punto de creación para que todas las vías queden acotadas: el autorregistro, la API, la creación desde el portal, SCIM, el aprovisionamiento just-in-time, la importación masiva y las invitaciones al equipo. |
Retención de usuarios inactivos
De forma opcional, desactiva y después elimina las cuentas que han dejado de usarse, para que un directorio no acumule identidades inactivas para siempre. Ambas están desactivadas mientras no las configures, y la eliminación es permanente.
| Configuración | Predeterminado | Descripción |
|---|---|---|
| Desactivar después de (días de inactividad) | Nunca | Desactiva una cuenta que lleva este tiempo sin iniciar sesión. El registro se conserva y se puede reactivar. |
| Eliminar después de (días de inactividad) | Nunca | Elimina la cuenta de forma permanente. No hay marcha atrás, así que configura la ventana de aviso y el webhook de abajo antes de activarlo. |
| Días de aviso | 7 | Con cuántos días de antelación a una desactivación o una eliminación se dispara el webhook de aviso, dándote tiempo para intervenir. |
| Webhook de retención | - | Dónde se publican esos avisos y las acciones ejecutadas, para que puedas avisar a la persona o mantener la cuenta abierta. |
Exportación de auditoría y copias de seguridad remotas
Dos formas de sacar tus datos de forma programada en lugar de bajo petición. La exportación de auditoría envía cada día completo de eventos de auditoría a una URL que tú indiques, firmada para que puedas verificar que viene de nosotros, para alimentar un SIEM o un archivo de cumplimiento. Las copias de seguridad remotas mandan copias de tus copias diarias y semanales a un destino que controlas tú, sin autenticación, con autenticación básica o con un token Bearer. Ambas se configuran en Configuración y son tuyas, independientes de las copias que guardamos nosotros.
Entorno sandbox
El entorno sandbox es un clon completo de tu inquilino de producción, disponible en una URL separada. Úsalo para probar cambios de configuración, integraciones SSO y endpoints de webhook sin afectar a los usuarios activos.
| Acción | Descripción |
|---|---|
| Habilitar Sandbox | Crea una copia sandbox de tu inquilino de producción. La URL del sandbox es el slug de tu inquilino con el sufijo -sandbox. |
| Actualizar desde producción | Sincroniza el entorno sandbox con la configuración y datos de usuario de producción actuales. |
| Deshabilitar Sandbox | Elimina permanentemente el entorno sandbox y todos sus datos. |
El sandbox es accesible en {slug}-sandbox.authagonal.io.


Controles del entorno sandbox
Facturación
Gestiona tu suscripción y facturación a través de la página de Facturación del portal. Esta página te ofrece un resumen de tu plan actual y proporciona acceso al portal de facturación de Stripe para gestionar métodos de pago, facturas y cambios de plan.
Información de suscripción
La página de facturación muestra los detalles de tu suscripción actual de un vistazo. Verás una insignia de estado indicando el estado de tu suscripción — active, trialing, past_due, canceled o unpaid — junto con el nombre de tu plan, el período de facturación actual (fechas de inicio y fin), y si tu suscripción está configurada para cancelarse al final del período actual.
Gestionar suscripción
Haz clic en el botón Gestionar suscripción para abrir el portal de facturación de Stripe en una nueva ventana. Desde ahí puedes actualizar tus métodos de pago, ver y descargar facturas, cambiar tu plan o cancelar tu suscripción.
Si aún no existe una suscripción, se muestra un botón de Configurar facturación en su lugar, que te guía a través de la selección de un plan y la introducción de datos de pago.


La página de facturación muestra los detalles de tu suscripción actual y proporciona acceso a Stripe
Seguridad de pagos
Dominios personalizados
Sirve tus páginas de autenticación desde tu propio dominio (por ejemplo, auth.tudominio.com) en lugar del predeterminado {slug}.authagonal.io. Los dominios personalizados brindan a tus usuarios una experiencia de autenticación fluida y con tu marca.
Añadir un dominio
Ingresa el nombre de host que deseas usar en el formulario de añadir dominio (por ejemplo, auth.tudominio.com). Una vez añadido, el dominio aparecerá en tu lista de dominios con un estado pending_verification.
Verificación DNS
Crea un registro CNAME apuntando tu dominio a {slug}.authagonal.io. Una vez que el registro DNS esté configurado, haz clic en Verificar para comprobar la propagación DNS.
auth.yourdomain.com. CNAME acme.authagonal.io.
Propagación DNS
Certificados TLS
Una vez que tu dominio esté verificado, necesitas un certificado TLS para que los usuarios puedan conectarse de forma segura a través de HTTPS. Authagonal soporta dos opciones:
Automático (cert-manager) — Authagonal aprovisiona y renueva certificados TLS automáticamente usando cert-manager. Esta es la opción recomendada para la mayoría de los usuarios. No se requiere configuración adicional.
Traer el propio (BYO) — Sube tu propio certificado y clave privada en formato PEM. Esta opción es útil si tu organización requiere certificados de una autoridad de certificación específica. Se hace seguimiento de la expiración del certificado para que puedas renovarlo antes de que caduque.
Estado del dominio
Cada dominio muestra una insignia de estado indicando su estado actual: pending_verification (DNS aún no confirmado), verified (DNS confirmado, TLS pendiente), active (totalmente operativo) o failed (problema de configuración detectado).


La lista de dominios muestra cada dominio personalizado y su estado actual


Sube tu propio certificado TLS y clave privada en formato PEM
Renovación de certificado BYO
Configuración de correo
Configura cómo tu inquilino envía correos transaccionales — verificación, restablecimiento de contraseña y notificaciones MFA. Elige entre el remitente compartido predeterminado, un dominio personalizado verificado mediante Resend o tu propio servidor SMTP.


Correos localizados
Los correos transaccionales se envían en el idioma preferido del destinatario. Los correos de verificación, restablecimiento de contraseña, cuenta existente, bienvenida, facturación e invitación de administrador están plantillados en siete idiomas: inglés, alemán, francés, español, portugués, vietnamita y chino simplificado. Cuando no existe una plantilla para el idioma del destinatario, el correo recurre al inglés.
El idioma se resuelve a partir de la preferencia almacenada del destinatario en el momento del envío. Esa preferencia puede provenir de varios lugares:
- Registro y alta — capturado del idioma que el usuario eligió en las pantallas de inicio de sesión alojadas.
- La página de Usuarios del portal — definida por un administrador al crear o editar un usuario.
- El aprovisionamiento SCIM — mapeado desde el
preferredLanguagedel IdP cuando los usuarios se sincronizan mediante SSO. - La página de cuenta de autoservicio — elegida por el propio usuario en
/login/account.
No requiere configuración
Proveedores de correo
| Proveedor | Descripción | Configuración |
|---|---|---|
| Default | Correos enviados desde [email protected] usando nuestra infraestructura compartida de Resend. | No requiere configuración — funciona desde el primer momento. |
| Resend Custom Domain | Correos enviados desde tu propio dominio verificado mediante Resend. | Registra tu dominio, añade registros DNS, verifica la propiedad. |
| Custom SMTP | Correos enviados a través de tu propio servidor SMTP. | Proporciona host, puerto, credenciales y ajustes TLS del SMTP. |
Identidad del remitente
El correo y el nombre del remitente se comparten en todos los modos de proveedor. El correo del remitente es obligatorio; si el nombre está vacío, se usa el nombre del inquilino.
| Campo | Descripción |
|---|---|
senderEmail | La dirección From en los correos salientes. Debe estar en un dominio verificado para el modo Dominio personalizado de Resend. |
senderName | Nombre para mostrar que aparece en la bandeja de entrada del destinatario. |
Dominio personalizado de Resend
Verifica tu dominio de envío con Resend una sola vez y úsalo como dirección de remitente para este inquilino. Los registros DNS TXT (SPF, DKIM) se proporcionan en la página de Dominios; Resend los valida automáticamente.
SMTP personalizado
Usa tu propio servidor SMTP — útil para relays internos, proveedores no cubiertos por Resend o fijación regulatoria.
| Campo | Descripción |
|---|---|
host | Nombre de host del servidor SMTP (p. ej. smtp.example.com). |
port | Puerto de conexión. 587 para STARTTLS, 465 para TLS implícito, 25 para relays internos sin autenticación. |
username | Usuario de autenticación (opcional — déjalo en blanco para relays sin autenticación). |
password | Contraseña de autenticación. Se almacena cifrada en el secreto de configuración del inquilino. |
useTls | Requerir TLS. Déjalo activado salvo que dirijas a un relay interno confiable. |
Dominio de envío personalizado
Con el proveedor Resend puedes registrar tu propio dominio para que los correos provengan de tu marca (por ejemplo, [email protected]) en lugar de @authagonal.io.
- Ve a Ajustes → Correo y selecciona el proveedor Dominio personalizado de Resend.
- Introduce tu nombre de dominio y haz clic en Registrar.
- Añade los registros DNS mostrados (DKIM, SPF y return path) al DNS de tu dominio.
- Haz clic en Comprobar verificación — cuando el DNS se propague (normalmente 1–10 minutos), el estado del dominio cambiará a verificado.
Propagación de DNS
Pruebas
Usa el botón Enviar correo de prueba en Ajustes → Correo para verificar tu configuración. Se enviará un correo de prueba a tu dirección de administrador usando los ajustes guardados.
Registro de auditoría
El Registro de auditoría proporciona un registro de solo lectura de todas las acciones administrativas realizadas en tu inquilino. Cada cambio realizado a través del portal o la API se captura con contexto completo, dándote un rastro completo para cumplimiento y resolución de problemas.
Columnas del registro
| Columna | Descripción |
|---|---|
| Marca de tiempo | La fecha y hora en que ocurrió la acción |
| Actor | La dirección de correo electrónico del administrador que realizó la acción, o "system" para acciones automatizadas |
| Acción | El tipo de acción realizada (por ejemplo, Cliente creado, Configuración actualizada) |
| Entidad | El objetivo de la acción en formato tipo:id (por ejemplo, client:my-app) |
| Detalle | Contexto adicional sobre el cambio |
Acciones registradas
Las siguientes acciones administrativas se registran en el registro de auditoría:
| Categoría | Acciones |
|---|---|
| Clientes | Cliente creado, Cliente actualizado, Cliente eliminado |
| Conexiones SSO | Conexión SAML creada, Conexión SAML eliminada, Conexión OIDC creada, Conexión OIDC eliminada |
| Usuarios | Usuario creado, Usuario actualizado |
| Configuración | Configuración actualizada, Marca actualizada |
| Dominios | Dominio añadido, Dominio verificado, Dominio eliminado |
| SCIM | Token SCIM creado, Token SCIM revocado |
| Roles | Rol creado, Rol actualizado, Rol eliminado |
| Grupos | Grupo creado, Grupo eliminado |
| Equipo | Miembro del equipo invitado, Miembro del equipo eliminado |


El registro de auditoría proporciona un registro completo de todas las acciones administrativas
Retención
Copias de seguridad
Authagonal realiza copias de seguridad automáticas de los datos de tu inquilino cada hora. Las copias incluyen todos los usuarios, grupos, roles, clientes, conexiones SSO, tokens SCIM, marca y ajustes. Puedes ver el historial y descargar la última copia completa desde la página de Copias de seguridad.


Cómo funcionan las copias
- Una copia completa se ejecuta una vez al día, capturando todas las tablas del shard de almacenamiento de tu inquilino.
- Las copias incrementales se ejecutan cada hora, capturando solo las filas que cambiaron desde la última copia.
- Las copias se almacenan en Azure Blob Storage con la misma identidad administrada que usa tu inquilino.
- Los registros eliminados se rastrean mediante tombstones y se incluyen en las copias para completitud de auditoría.
Descargar copias
Haz clic en "Descargar última" para obtener un archivo ZIP con la copia completa más reciente fusionada con todas las copias incrementales posteriores. Cada tabla se exporta como un archivo JSONL (un objeto JSON por línea).
Formato de copia
Aplicaciones de aprovisionamiento
Las aplicaciones de aprovisionamiento son tus propios servicios. Authagonal las llama cada vez que se crea un usuario, para que puedan crear una cuenta, asignar una licencia, decidir a qué organización pertenece el usuario o rechazar el registro por completo.
Cómo funciona
Cuando se crea un usuario, Authagonal llama a la URL de callback de tu aplicación de aprovisionamiento siguiendo el patrón TCC (Try/Confirm/Cancel). Todas las aplicaciones deben aceptar en la fase Try antes de confirmar ninguna, de modo que varios sistemas posteriores puedan ponerse de acuerdo, o uno pueda vetar, sin dejar cuentas a medio crear.
| Fase | Endpoint | Propósito |
|---|---|---|
| /try | POST {callbackUrl}/try | Verifica si la aplicación puede manejar al usuario. Devuelve 200 para aceptar o 4xx para rechazar. |
| /confirm | POST {callbackUrl}/confirm | Confirma la operación después de que todas las aplicaciones hayan aceptado la fase /try. |
| /cancel | POST {callbackUrl}/cancel | Revierte la operación si otra aplicación falla durante la fase /try. |
Cuándo se ejecuta el aprovisionamiento
El aprovisionamiento se ejecuta en todas las rutas que crean un usuario, no solo en el registro autoservicio. Las combinaciones de aplicación y usuario ya aprovisionadas se omiten, por lo que una aplicación ve cada usuario una sola vez.
| Ruta de creación | Cuándo se activa |
|---|---|
POST /api/auth/register | Registro autoservicio |
| Callback SAML ACS | Primer inicio de sesión SSO de un usuario nuevo (JIT) |
| Callback OIDC | Primer inicio de sesión SSO de un usuario nuevo (JIT) |
POST /scim/v2/Users | Un conector aprovisiona un usuario desde el directorio del cliente |
| Creación de usuarios en el portal y en el admin | Un operador crea o invita a un usuario manualmente |
La solicitud Try
Authagonal envía este JSON por POST a <code>{callbackUrl}/try</code>. Los campos sin valor se omiten en lugar de enviarse como null.
| Campo | Tipo | Descripción |
|---|---|---|
transactionId | string | Identifica esta transacción de aprovisionamiento. El mismo valor se envía a /confirm y /cancel, así que prepara tu trabajo asociado a él y confírmalo o descártalo cuando llegue esa llamada. |
userId | string | El id de Authagonal del usuario. Es el subject que verás en sus tokens. |
email | string | La dirección de correo electrónico del usuario. |
firstName | string | Nombre de pila, cuando la ruta de creación ha proporcionado uno. |
lastName | string | Apellido, cuando la ruta de creación ha proporcionado uno. |
organizationId | string | La organización a la que ya pertenece el usuario, si la hay. Solo está presente cuando algo le ha asignado una antes. En un primer registro no aparece, y esa es la señal para asignarla. |
customAttributes | object | Los atributos personalizados almacenados del usuario. En un usuario creado mediante SSO incluyen federated_connection, el nombre de la conexión que ha respondido por él. |
El caso habitual que conviene prever es el de un usuario que llega por SSO: todavía no tiene organización, y federated_connection te dice de cuál de tus clientes procede.
{
"transactionId": "8f14e45fceea167a5a36dedd4bea2543",
"userId": "0f6b1c8e-3d2a-4f51-9e77-2c1a4b5d6e7f",
"email": "[email protected]",
"firstName": "Ada",
"lastName": "Lovelace",
"customAttributes": {
"federated_connection": "acme-okta"
}
}La respuesta Try
Tu aplicación responde con un 200 y un cuerpo JSON. El cuerpo no es solo un acuse de recibo: es la forma en que una aplicación posterior asigna la organización y los atributos que acaban en los tokens del usuario.
| Campo | Tipo | Descripción |
|---|---|---|
approved | boolean | Indica si esta aplicación acepta al usuario. Si se omite, el valor por defecto es true. False rechaza el registro y la cuenta nueva se elimina. |
reason | string | Por qué se rechazó al usuario. Se muestra a quien invoca la ruta de creación. |
organizationId | string | La organización a la que pertenece este usuario. Se guarda en el usuario y se emite como el claim org_id en sus tokens. Solo se aplica si el usuario no tiene ya una, de modo que gana la primera aplicación que responde y las posteriores ven esa asignación. |
customAttributes | object | Atributos que se fusionan en el usuario, clave por clave. Se emiten en los tokens a través de la configuración UserClaims de un scope. |
emailVerified | boolean | Tu aplicación garantiza que ha verificado esta dirección, por ejemplo mediante el canje de una invitación enviada a ella. Authagonal marca la cuenta como confirmada y omite su propio correo de verificación. |
{
"approved": true,
"organizationId": "org_acme",
"customAttributes": { "org_role": "member" }
}De aquí viene org_id
org_id de los tokens y de /connect/userinfo es exactamente lo que tu aplicación de aprovisionamiento haya devuelto como organizationId. Authagonal nunca lo deriva: no hay objeto Organization, ni regla de unicidad, ni requisito de formato. Es tu identificador, almacenado en el usuario y devuelto en cada token. También puedes establecerlo directamente con PUT /api/v1/users/{userId} y filtrar por él con GET /api/v1/users?organizationId=.Etiquetar a los usuarios con la organización correcta
Decide la organización aquí, en un solo lugar, en vez de en cada ruta de creación. Un usuario de SSO lleva federated_connection, que identifica la conexión que lo autenticó y, por tanto, al cliente, y sigue siendo correcto cuando un mismo cliente federa varios dominios de correo. Un usuario invitado no tiene conexión, así que identifícalo por la invitación que emitiste. Ambas rutas llegan a /try antes de que el usuario exista, de modo que una sola lógica las cubre y no hay dos reglas que puedan divergir.
// POST {callbackUrl}/try
app.post('/provisioning/try', async (req, res) => {
const { email, customAttributes } = req.body;
// An SSO user carries the connection that vouched for them. That is the
// customer, and it stays right when one customer has several domains.
const connection = customAttributes?.federated_connection;
const org = connection
? await orgByConnection(connection)
: await orgByPendingInvite(email);
if (!org) return res.json({ approved: false, reason: 'No organization for this user' });
// Stamped on the user and emitted as org_id on every token from now on.
res.json({ approved: true, organizationId: org.id });
});El rechazo elimina la cuenta
approved: false, el usuario recién creado se elimina para que no quede ninguna cuenta a medio aprovisionar. Las rutas de creación de la API devuelven 422 con tu reason; los callbacks SAML y OIDC devuelven 400. Devuelve approved: true para un usuario con el que no tengas nada que hacer.Añadir una aplicación de aprovisionamiento
Para añadir una aplicación de aprovisionamiento, proporciona un nombre, una URL de callback y una clave API opcional. La clave API se envía como token Bearer en el encabezado Authorization de cada solicitud de webhook, permitiendo que tu aplicación autentique las solicitudes de Authagonal.
Pruebas
Haz clic en Probar junto a cualquier aplicación de aprovisionamiento para enviar una solicitud de prueba a tu URL de callback. Los resultados de la prueba muestran el código de estado HTTP y el cuerpo de la respuesta, ayudándote a verificar que tu aplicación está recibiendo y procesando webhooks correctamente.


Prueba las aplicaciones de aprovisionamiento para verificar la entrega y manejo de respuestas del webhook
Límites del plan
El número máximo de aplicaciones de aprovisionamiento es configurable por inquilino, con un límite predeterminado de 6. Este límite puede ser ajustado por un administrador si tu flujo de trabajo requiere objetivos de aprovisionamiento adicionales.
Autenticación con clave API
Equipo
La página de Equipo gestiona los administradores del portal — las personas que pueden acceder y configurar tu inquilino a través del portal de gestión. Todos los miembros del equipo tienen acceso administrativo completo a todos los aspectos de la configuración de tu inquilino.
Lista de administradores
La lista de administradores muestra el nombre, dirección de correo electrónico y la fecha en que fue añadido cada miembro del equipo. Un indicador "Tú" se muestra junto a la fila del usuario actual para que puedas identificar fácilmente tu propia cuenta.
Invitar administradores
Para invitar a un nuevo miembro del equipo, proporciona su dirección de correo electrónico, nombre y una contraseña temporal (mínimo 8 caracteres). El usuario invitado inicia sesión con la contraseña temporal y debe cambiarla en el primer inicio de sesión.
Campos de invitación
Las invitaciones de administrador crean un usuario totalmente aprovisionado — sin viaje de ida y vuelta por correo.
| Campo | Descripción |
|---|---|
email | Dirección de correo del nuevo admin. Debe ser única en el inquilino. |
name | Nombre mostrado en la lista de administradores. |
tempPassword | Contraseña temporal que el invitado usa en el primer inicio de sesión. Se le pedirá cambiarla. Déjalo vacío para generar automáticamente y enviar por correo. |
Eliminar administradores
Haz clic en Eliminar junto a cualquier miembro del equipo para revocar su acceso. Se muestra un diálogo de confirmación antes de que la eliminación se finalice. No puedes eliminarte a ti mismo — siempre debe haber al menos un administrador en el equipo.


Gestiona los administradores del portal desde la página de Equipo
Sin rol de propietario
Soporte
Abre un ticket de soporte con el equipo de Authagonal sin salir del portal. Cada ticket es una conversación con hilo, así que tú y nuestro equipo estáis siempre alineados, desde el primer reporte hasta la resolución.
Tus tickets
La página de soporte lista todos los tickets que has abierto, con la actividad más reciente primero. Usa la insignia de estado para ver de un vistazo qué está esperando por ti y qué está esperando por nosotros.


Tus tickets de soporte con asunto, estado, prioridad y última actividad
- Cada fila muestra el asunto, el estado actual (abierto, pendiente, resuelto o cerrado), la prioridad y la hora de la última actividad.
- Haz clic en Nuevo ticket para abrir uno y dale un asunto, una prioridad y tu primer mensaje.
- Las insignias de estado con código de color facilitan revisar la lista en busca de tickets que necesitan tu atención.
El hilo de un ticket
Al abrir un ticket se muestra la conversación completa. Las respuestas se publican en orden y los nuevos mensajes de nuestro equipo aparecen sin recargar la página.


El hilo de un ticket entre tú y el equipo de Authagonal
- Los mensajes con hilo entre tú y el equipo de Authagonal se muestran en orden cronológico.
- Responde en línea y adjunta archivos para compartir registros, capturas de pantalla o configuración.
- El hilo se actualiza en vivo, así que una respuesta de nuestro equipo aparece en cuanto se envía.
- Si en su lugar respondes al correo de notificación, tu mensaje se añade al hilo automáticamente.
Cómo te llegan las respuestas
Mesa de soporte para tus usuarios
Aparte del soporte que recibes de nosotros, Authagonal puede gestionar una mesa de soporte para tus usuarios finales. Ellos abren tickets desde las páginas de su cuenta en el host con la marca de tu propio inquilino, y tu equipo los responde desde el portal.
Existe porque las personas que no pueden iniciar sesión son justo las que no pueden llegar a una herramienta de soporte que exige iniciar sesión. La mesa está junto a las pantallas de inicio de sesión, así que un usuario bloqueado sigue teniendo una vía, y cada ticket llega ya vinculado a una cuenta real de tu directorio y no a la dirección que alguien haya escrito.
Cómo activarla
Abre Configuración en el portal y habilita el portal de soporte. Tus usuarios no ven nada hasta que lo hagas.
| Configuración | Qué hace |
|---|---|
| Portal de soporte | El interruptor principal. Desactivado, tanto las páginas del usuario final como tu bandeja de entrada de operador quedan ocultas y sus API responden 404. |
| Permitir tickets anónimos | Permite que un visitante sin sesión iniciada abra un ticket, que es el caso del usuario bloqueado. Está protegido por una comprobación anti-bots, y el intercambio continúa por correo electrónico más un enlace privado, ya que no hay ninguna cuenta con la que iniciar sesión. |
| Notificaciones | Direcciones de correo a las que avisar cuando llega un ticket o responde un usuario, para que nadie tenga que quedarse vigilando la bandeja de entrada. |
| Idioma predeterminado del usuario final | Se usa cuando un mensaje es demasiado corto para detectar el idioma. Recurre al inglés. |
| Webhook de soporte | Una URL a la que enviar por POST los eventos de tickets, para llevarlos a tus propias herramientas. |
No disponible en el plan Gratis
Qué ven tus usuarios
Los usuarios con sesión iniciada tienen un área de soporte en las páginas de su cuenta en el host de tu inquilino, con tu marca. Pueden abrir un ticket, ver todo lo que han abierto y responder en un hilo. Las respuestas de tu equipo también llegan por correo electrónico, así que el usuario no tiene que estar comprobándolo.
Con los tickets anónimos habilitados, alguien que no puede iniciar sesión todavía puede abrir uno. Indica una dirección de correo y su mensaje, y recibe a cambio un enlace privado a la conversación. Ese enlace es la única vía de entrada, así que trátalo como una credencial: es imposible de adivinar, y cualquiera que lo tenga puede leer ese hilo concreto y responder en él.
La bandeja de entrada del operador
Tu equipo responde desde Bandeja de soporte en el portal. Es un lugar distinto de tus propios tickets con nosotros, y está disponible para el rol tenant:support y superiores, así que puedes dar a un agente acceso a la mesa sin darle el resto del portal.
| Acción | Qué hace |
|---|---|
| Responder | Publica en el hilo. Se envía un correo al usuario, que además lo ve en vivo si tiene la página abierta. |
| Asignar | Entrega un ticket a un miembro concreto de tu equipo, para que dos personas no respondan al mismo. |
| Estado y prioridad | Mueve un ticket por los estados abierto, pendiente, resuelto y cerrado, y marca lo urgente que es. Los tickets cerrados se eliminan tras un periodo de retención en lugar de guardarse para siempre. |
| Notas internas | Notas visibles solo para tu equipo, nunca para el usuario. Las ediciones y las eliminaciones quedan registradas en el registro de auditoría. |
| Abrir en nombre de un usuario | Inicia un hilo con uno de tus usuarios eligiéndolo de tu directorio, para cuando la conversación empezó en otro sitio. |
| Escalar a Authagonal | Si resulta que un ticket trata sobre Authagonal y no sobre tu producto, escálalo. Eso abre un ticket enlazado con nuestro equipo, que opcionalmente lleva el hilo hasta ese momento, y enlaza los dos para que puedas seguir ambos. Un ticket solo se puede escalar una vez. |
Los usuarios escriben en su propio idioma
Un ticket se almacena en el idioma en que lo escribió el usuario, y cada persona del hilo lo lee en el suyo. Tu agente ve el mensaje traducido al idioma de su portal, el usuario ve tu respuesta traducida al suyo, y el texto original se conserva siempre al lado. El idioma se detecta a partir del primer mensaje y queda fijado al ticket. Las traducciones se calculan una vez por idioma y se reutilizan, así que un hilo largo no se vuelve a traducir entero.
Zonas horarias
Un ticket registra la zona horaria desde la que lo abrió el usuario. Cada mensaje muestra entonces su hora local junto a la tuya, de modo que una respuesta a las 14:32 se lee como las 02:32 que en realidad eran para la persona que la esperaba. No se muestra nada cuando la zona es desconocida, por ejemplo en un ticket que llegó por correo, o cuando coincide con la tuya.
Webhooks
Configura una URL de webhook de soporte para recibir los eventos de tickets en el momento en que ocurren, para lanzar una alerta o replicar los tickets en tu propio sistema. Las cargas van firmadas para que puedas verificar que vienen de nosotros.
| Evento | Qué hace |
|---|---|
support.ticket.created | Un usuario abrió un ticket. |
support.ticket.message | Un usuario respondió a un hilo. |
support.ticket.replied | Respondió uno de tus operadores. |
support.ticket.assigned | Se asignó un ticket a un miembro del equipo. |
support.ticket.escalated | Se escaló un ticket a Authagonal. |
Importar y migrar
Migra un sistema de identidad existente a tu inquilino de Authagonal. Se admiten dos fuentes — Duende IdentityServer (una base de datos SQL Server) y Auth0 (la Management API). Cada una ejecuta una vista previa de solo lectura para que revises exactamente qué se copiará antes de confirmar.
Importación desde Duende IdentityServer
Migra clientes, ámbitos, usuarios y roles desde una base de datos SQL Server de Duende IdentityServer existente a tu inquilino de Authagonal. La importación se ejecuta en dos fases — vista previa y commit — para que puedas revisar lo que se copiará antes de realizar cualquier cambio.
Qué se importa
El importador lee de la ConfigurationDb de Duende y de las tablas de ASP.NET Identity y escribe las filas mapeadas en tu inquilino. Se omiten artefactos de corta duración como persisted grants, device codes y claves de firma.
| Entidad | Tablas de origen | Notas |
|---|---|---|
| Clientes | Clients, ClientSecrets, ClientGrantTypes, ClientScopes, ClientRedirectUris | Los clientes deshabilitados se importan deshabilitados. Los secrets expirados se omiten. |
| Ámbitos | ApiScopes, ApiResources, IdentityResources | Se conservan las asignaciones de claims de usuario reconocidas. |
| Usuarios | AspNetUsers, AspNetUserClaims | Los hashes de contraseña (ASP.NET Identity V3) se copian tal cual y se rehashan en el primer inicio de sesión. |
| Roles | AspNetRoles, AspNetUserRoles | Se preservan las asignaciones de roles. |
| Inicios de sesión externos | AspNetUserLogins | Se guardan como referencia; reconecta los IdP de origen mediante SSO tras la importación. |
Vista previa antes del commit
Pega tu cadena de conexión a ConfigurationDb / IdentityDb de Duende y haz clic en Ejecutar vista previa. La vista previa abre una conexión de solo lectura y cuenta cada fila que se importaría — no se escribe nada.
- Recuentos por entidad de clientes, ámbitos, usuarios, roles y asignaciones de roles.
- Avisos de sobrescritura cuando el inquilino de destino ya tiene clientes, roles o ámbitos coincidentes.
- Avisos de tablas desconocidas y columnas no mapeadas para que sepas qué se descartará.


Panel de vista previa con recuentos y avisos
Hashes de contraseña
Duende almacena contraseñas con ASP.NET Identity V3 (PBKDF2). El PasswordHasher de Authagonal verifica ese formato directamente y rehashea al formato nativo en el primer inicio de sesión exitoso — los usuarios conservan su contraseña sin flujo de restablecimiento.
Reconciliación de ID de usuario
Si un usuario que ya está en este inquilino tiene el mismo correo que un registro entrante, la importación rota el userId de esa cuenta al sub de origen antes de importar, de modo que los roles, inicios de sesión y reclamaciones importados se vinculan a la cuenta existente y las apps que ya referencian al usuario por su sub de origen siguen resolviéndose tras la migración. La contraseña y el perfil existentes de la cuenta se conservan; los roles de origen se fusionan encima. La vista previa enumera cada cuenta que se reconciliará antes de confirmar.
Ejecutar la importación
Haz clic en Iniciar importación tras revisar la vista previa. La fase de commit escribe clientes, ámbitos, usuarios, roles y referencias de inicio de sesión externo en los stores del inquilino. Las filas duplicadas de clientId, scope name, email y role name se omiten — el importador es seguro de re-ejecutar.
Qué no se importa
- Persisted grants, device codes, server-side sessions — de corta duración, se regeneran automáticamente.
- Claves de firma — Authagonal emite sus propias claves por tenant.
- Columnas y tablas personalizadas — cualquier cosa fuera del esquema estándar de Duende se emite como aviso para que sepas que los datos se descartaron.
- Clientes deshabilitados — se importan deshabilitados; reactívalos desde la página Clientes cuando estés listo.
No disponible en sandbox
Importar desde Auth0
Conecta Authagonal con la Management API de tu inquilino de Auth0 y trae tus aplicaciones, APIs, roles, usuarios y conexiones empresariales. Los IDs de usuario y aplicación importados se conservan, de modo que las referencias existentes a sub y client_id siguen resolviéndose tras el cambio.
Qué necesitarás
Crea una aplicación Machine-to-Machine en Auth0 autorizada para la Management API, con estos ámbitos de lectura: read:users, read:clients, read:resource_servers, read:roles, read:connections, read:client_grants. Pega su dominio, client ID y client secret en el formulario de importación — solo se usan para la importación.
Qué se importa
| Entidad | Tablas de origen | Notas |
|---|---|---|
| Aplicaciones | clients, client-grants | Public vs. confidential se detecta automáticamente. Los client secrets se rehashan para que sigan funcionando. |
| APIs y ámbitos | resource-servers | Las audiences y los ámbitos se asignan a cada cliente a partir de sus concesiones. |
| Roles | roles + asignaciones | Se conservan las asignaciones de roles por usuario. |
| Usuarios | users + identities | Los perfiles y metadatos se transfieren; las identidades sociales/empresariales pasan a ser inicios de sesión vinculados. |
| Conexiones | connections (OIDC) | Las conexiones OIDC empresariales se convierten en proveedores federados. Las conexiones SAML, sociales y de base de datos se omiten con una advertencia. |
Contraseñas
La Management API de Auth0 nunca devuelve los hashes de contraseña. Si dispones de la exportación masiva de contraseñas asistida por soporte de Auth0 (NDJSON), proporciónala — los hashes bcrypt se importan tal cual y tus usuarios conservan sus contraseñas sin restablecimiento. Ese archivo también incluye el conjunto completo de usuarios, eliminando el límite de 1.000 usuarios del listado de la API de Auth0. Sin él, los usuarios se importan como perfiles y establecen una nueva contraseña en el primer inicio de sesión.
Misma vista previa, rotación y límites
Referencia de API
Cada inquilino expone un servidor OIDC compatible con estándares en https://{slug}.authagonal.io. Todos los endpoints siguen las especificaciones OAuth 2.0 y OpenID Connect. Esta referencia cubre todos los endpoints con los que tu aplicación puede necesitar interactuar.
Flujo de código de autorización con PKCE
Descubrimiento OIDC y JWKS
El documento de descubrimiento permite que las bibliotecas de cliente OIDC se configuren automáticamente. No se requiere autenticación para ninguno de los endpoints.
GET /.well-known/openid-configuration
Devuelve el documento de configuración del proveedor OpenID. La respuesta incluye todos los metadatos que tu cliente necesita para interactuar con este inquilino.
| Campo | Descripción |
|---|---|
| issuer | La URL del emisor del inquilino |
| authorization_endpoint | URL para solicitudes de autorización |
| token_endpoint | URL para intercambio de tokens |
| userinfo_endpoint | URL para obtener reclamaciones del usuario |
| jwks_uri | URL del JSON Web Key Set |
| revocation_endpoint | URL para revocación de tokens |
| introspection_endpoint | URL para introspección de tokens |
| end_session_endpoint | URL para cierre de sesión / end-session |
| device_authorization_endpoint | URL para solicitudes de autorización de dispositivo |
| pushed_authorization_request_endpoint | URL del endpoint de Pushed Authorization Request (RFC 9126). |
| require_pushed_authorization_requests | Si el inquilino exige PAR globalmente. Incluso cuando está en false, los clientes individuales pueden establecer RequirePushedAuthorizationRequests = true. |
| scopes_supported | Lista de alcances soportados |
| response_types_supported | Tipos de respuesta soportados |
| grant_types_supported | Tipos de concesión soportados |
| code_challenge_methods_supported | Métodos PKCE soportados (S256) |
| backchannel_logout_supported | Si el cierre de sesión por canal trasero está soportado |
GET /.well-known/openid-configuration/jwks
Devuelve el JSON Web Key Set utilizado para verificar las firmas de tokens. La respuesta contiene un array keys con claves públicas RSA, cada una incluyendo los campos kty, use, kid, alg, n y e.
curl https://acme.authagonal.io/.well-known/openid-configuration
Endpoint de autorización
GET /connect/authorize
Inicia un flujo de código de autorización. El usuario debe tener una sesión activa o será redirigido a la página de inicio de sesión. En caso de éxito, el usuario es redirigido de vuelta a tu aplicación con un código de autorización.
| Parámetro | Requerido | Descripción |
|---|---|---|
response_type | Sí | Debe ser "code" |
client_id | Sí | Tu identificador de cliente registrado |
redirect_uri | Sí | Debe coincidir exactamente con una URI de redirección registrada |
scope | Sí | Lista de alcances separados por espacio (por ejemplo, "openid profile email") |
state | Recomendado | Valor opaco para protección CSRF, devuelto sin cambios en la redirección |
code_challenge | Requerido si PKCE | Hash SHA-256 codificado en base64url del code_verifier |
code_challenge_method | Requerido si PKCE | Debe ser "S256" |
nonce | Opcional | Valor vinculado al token de ID para protección contra reproducción |
login_hint | Opcional | Rellenar previamente el campo de correo electrónico en la página de inicio de sesión |
Respuesta exitosa: Redirección 302 a redirect_uri con los parámetros de consulta code y state.
Respuesta de error: Redirección 302 con los parámetros de consulta error, error_description y state.
PKCE requerido
code_verifier (una cadena aleatoria de 43 o más caracteres), hashéalo con SHA-256 y codifica el resultado en base64url para crear el code_challenge.Pushed Authorization Requests (PAR)
RFC 9126. En lugar de poner cada parámetro de autorización en la URL, tu cliente los envía por POST a /connect/par con autenticación normal y recibe una request_uri opaca y de corta duración. El navegador visita luego /connect/authorize?client_id=...&request_uri=... — nada más queda en el historial del navegador, los logs del servidor ni los encabezados Referer, y el servidor ya ha verificado la integridad de los parámetros bajo autenticación de cliente.
POST /connect/par
La autenticación de cliente es la misma que en /connect/token: HTTP Basic con client_id/client_secret o credenciales codificadas en el formulario. Los clientes públicos publican sin secreto. El cuerpo lleva los mismos parámetros que enviarías normalmente a /connect/authorize; request_uri en sí es rechazado (encadenar un PAR está prohibido por §2.1 de la especificación). Devuelve 201 Created.
| Parámetro | Requerido | Descripción |
|---|---|---|
client_id | Sí | Tu ID de cliente. Debe coincidir con el cliente autenticado. |
client_secret | Clientes confidenciales | Tu secreto de cliente. Requerido para clientes confidenciales. |
response_type | Sí | Debe ser "code" |
redirect_uri | Sí | Debe coincidir exactamente con una URI de redirección registrada |
scope | Sí | Lista de alcances separados por espacio (por ejemplo, "openid profile email") |
code_challenge | Requerido si PKCE | Hash SHA-256 codificado en base64url del code_verifier |
code_challenge_method | Requerido si PKCE | Debe ser "S256" |
state | Recomendado | Valor opaco para protección CSRF, devuelto sin cambios en la redirección |
nonce | Opcional | Valor vinculado al token de ID para protección contra reproducción |
Respuesta
| Campo | Descripción |
|---|---|
request_uri | Referencia opaca de un solo uso, p. ej. <code>urn:ietf:params:oauth:request_uri:abc123…</code>. Pásala a <code>/connect/authorize</code> como <code>request_uri</code>. |
expires_in | Vida útil de la <code>request_uri</code> en segundos. Por defecto es 90 — valor típico de un IdP de referencia. |
En la llamada posterior GET /connect/authorize?client_id=…&request_uri=…, todos los demás parámetros se toman de la carga útil enviada y cualquier parámetro de consulta extra se ignora. El client_id en la llamada de autorización debe coincidir con el cliente que envió la solicitud. Una vez consumida (o cuando transcurre expires_in), la request_uri se elimina del almacén.
Forzar PAR por cliente
/connect/authorize. La postura recomendada para clientes de alto riesgo combina RequirePushedAuthorizationRequests = true con PKCE — eso elimina por completo la barra de direcciones como superficie de ataque.# 1. Push parameters (server returns request_uri + expires_in) curl -X POST https://acme.authagonal.io/connect/par \ -u "my-app:CLIENT_SECRET" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "response_type=code" \ -d "redirect_uri=https://app.example.com/callback" \ -d "scope=openid profile email" \ -d "state=$(openssl rand -hex 16)" \ -d "code_challenge=YOUR_CODE_CHALLENGE" \ -d "code_challenge_method=S256" # 2. Send the user to /authorize with only client_id + request_uri # https://acme.authagonal.io/connect/authorize?client_id=my-app&request_uri=urn:ietf:params:oauth:request_uri:abc123...
Endpoint de token
POST /connect/token
Intercambia credenciales por tokens. Las solicitudes deben usar Content-Type: application/x-www-form-urlencoded. La autenticación del cliente puede proporcionarse a través de HTTP Basic auth (Authorization: Basic base64(client_id:client_secret)) o como parámetros del cuerpo del formulario (client_id + client_secret).
Concesión de código de autorización
| Parámetro | Requerido | Descripción |
|---|---|---|
grant_type | Sí | "authorization_code" |
code | Sí | El código de autorización de la redirección |
redirect_uri | Sí | Debe coincidir con la URI utilizada en la solicitud de autorización |
code_verifier | Requerido si PKCE | La cadena aleatoria original utilizada para generar el code_challenge |
client_id | Sí | Tu identificador de cliente (si no usas autenticación Basic) |
client_secret | Clientes confidenciales | Tu secreto de cliente (si no usas autenticación Basic) |
Concesión de token de actualización
| Parámetro | Requerido | Descripción |
|---|---|---|
grant_type | Sí | "refresh_token" |
refresh_token | Sí | El token de actualización a intercambiar |
client_id | Sí | Tu identificador de cliente |
client_secret | Clientes confidenciales | Tu secreto de cliente |
Concesión de credenciales de cliente
| Parámetro | Requerido | Descripción |
|---|---|---|
grant_type | Sí | "client_credentials" |
client_id | Sí | Tu identificador de cliente |
client_secret | Sí | Tu secreto de cliente |
scope | Opcional | Alcances separados por espacio a solicitar |
Concesión de código de dispositivo
| Parámetro | Requerido | Descripción |
|---|---|---|
grant_type | Sí | "urn:ietf:params:oauth:grant-type:device_code" |
device_code | Sí | El código de dispositivo de la respuesta de autorización de dispositivo |
client_id | Sí | Tu identificador de cliente |
client_secret | Clientes confidenciales | Tu secreto de cliente |
Respuesta del token:
| Campo | Descripción |
|---|---|
access_token | El token de acceso para llamadas a la API |
token_type | "Bearer" |
expires_in | Duración del token en segundos |
id_token | Token de ID de OpenID Connect (cuando se solicita el alcance openid) |
refresh_token | Token de actualización (cuando se otorga el alcance offline_access) |
curl -X POST https://acme.authagonal.io/connect/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=AUTHORIZATION_CODE" \ -d "redirect_uri=https://app.example.com/callback" \ -d "client_id=my-app" \ -d "code_verifier=YOUR_CODE_VERIFIER"
Endpoint UserInfo
GET /connect/userinfo
Devuelve reclamaciones sobre el usuario autenticado. Requiere un token de acceso válido con el alcance openid.
| Campo | Tipo | Descripción |
|---|---|---|
sub | string | Identificador único del usuario |
email | string | Dirección de correo electrónico del usuario |
email_verified | boolean | Si el correo electrónico ha sido verificado |
given_name | string | Nombre |
family_name | string | Apellido |
name | string | Nombre completo para mostrar |
phone_number | string | Número de teléfono (si se proporcionó) |
org_id | string | La organización a la que pertenece el usuario. La asigna tu propia aplicación de aprovisionamiento (ver Aplicaciones de aprovisionamiento) o se establece con PUT /api/v1/users/{userId}; Authagonal nunca la deriva. Se publica bajo el scope profile y no aparece cuando el usuario no tiene ninguna. |
roles | string[] | Array de roles asignados |
groups | object[] | Array de membresías de grupo, cada una con id y name |
curl https://acme.authagonal.io/connect/userinfo \ -H "Authorization: Bearer ACCESS_TOKEN"
Introspección de token (RFC 7662)
POST /connect/introspect
Valida un token y devuelve sus metadatos. Requiere credenciales de cliente (autenticación Basic o parámetros del cuerpo del formulario).
| Parámetro | Requerido | Descripción |
|---|---|---|
token | Sí | El token a inspeccionar |
token_type_hint | Opcional | Pista sobre el tipo de token (por ejemplo, "refresh_token") |
Respuesta de token activo:
| Campo | Descripción |
|---|---|
active | true |
sub | Sujeto (ID de usuario) |
client_id | Cliente al que se emitió el token |
scope | Alcances otorgados separados por espacio |
iss | Emisor |
exp | Tiempo de expiración (marca de tiempo Unix) |
iat | Tiempo de emisión (marca de tiempo Unix) |
aud | Audiencia |
token_type | Tipo de token (por ejemplo, "Bearer") |
Respuesta de token inactivo: { "active": false }
Siempre 200 OK
active: false.curl -X POST https://acme.authagonal.io/connect/introspect \ -u "my-app:CLIENT_SECRET" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "token=ACCESS_OR_REFRESH_TOKEN"
Revocación de token (RFC 7009)
POST /connect/revocation
Revoca un token emitido previamente. Requiere credenciales de cliente.
| Parámetro | Requerido | Descripción |
|---|---|---|
token | Sí | El token a revocar |
token_type_hint | Opcional | Pista sobre el tipo de token (por ejemplo, "refresh_token") |
El endpoint siempre devuelve 200 OK, incluso para tokens inválidos o ya revocados, según la especificación RFC 7009.
Solo tokens de actualización
Autorización de dispositivo (RFC 8628)
POST /connect/deviceauthorization
Inicia el flujo de autorización de dispositivo para dispositivos con restricciones de entrada (CLIs, smart TVs, dispositivos IoT). El dispositivo muestra un código al usuario, quien luego aprueba la solicitud en un dispositivo separado con navegador.
| Parámetro | Requerido | Descripción |
|---|---|---|
client_id | Sí | Tu identificador de cliente |
client_secret | Clientes confidenciales | Tu secreto de cliente |
scope | Opcional | Alcances separados por espacio (predeterminado: "openid") |
Respuesta:
| Campo | Descripción |
|---|---|
device_code | Código de verificación del dispositivo (utilizado para consultas periódicas) |
user_code | Código visible para el usuario en formato XXXX-XXXX |
verification_uri | URL que el usuario visita para ingresar el código |
verification_uri_complete | URL con el user_code pre-completado |
expires_in | 600 (segundos — el código es válido por 10 minutos) |
interval | 5 (segundos — intervalo mínimo de consulta) |
Flujo de aprobación: El usuario visita la verification_uri, ingresa el user_code y aprueba la solicitud. Mientras tanto, el dispositivo consulta periódicamente el endpoint de token con el device_code.
Códigos de error de consulta periódica:
| Error | Significado |
|---|---|
authorization_pending | El usuario aún no ha aprobado — continuar consultando |
expired_token | El código de dispositivo ha expirado — reiniciar el flujo |
access_denied | El usuario denegó la solicitud de autorización |
curl -X POST https://acme.authagonal.io/connect/deviceauthorization \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=my-cli" \ -d "scope=openid profile email"
Cierre de sesión / Logout
GET POST /connect/endsession
Cierra la sesión del usuario actual, activa el cierre de sesión por canal trasero a todos los clientes con un BackChannelLogoutUri registrado, y revoca todas las concesiones.
| Parámetro | Requerido | Descripción |
|---|---|---|
id_token_hint | Opcional | El token de ID — utilizado para validar el post_logout_redirect_uri |
post_logout_redirect_uri | Opcional | A dónde redirigir después del cierre de sesión (debe estar registrado) |
state | Opcional | Valor opaco devuelto en la redirección |
Si se proporciona un post_logout_redirect_uri válido que coincida con una URI registrada, el usuario recibe una redirección 302. De lo contrario, una respuesta JSON confirma que la sesión ha sido finalizada.
Cierre de sesión por canal trasero
BackChannelLogoutUri de cada cliente. El JWT contiene sub, aud, iss y la reclamación de evento http://schemas.openid.net/event/backchannel-logout. Tu aplicación debe invalidar la sesión local del usuario cuando reciba esta notificación.Referencia de API SCIM 2.0
Authagonal soporta el protocolo SCIM 2.0 para el aprovisionamiento automatizado de usuarios y grupos. Los proveedores de identidad como Okta, Azure AD y OneLogin pueden usar esta API para mantener tu inquilino de Authagonal sincronizado con tu directorio corporativo.
URL base: https://{slug}.authagonal.io/scim/v2
Autenticación: Todas las solicitudes requieren un token Bearer. Genera un token SCIM en el portal bajo Settings > SCIM Provisioning.
Encabezados comunes:
| Encabezado | Valor |
|---|---|
Authorization | Bearer SCIM_TOKEN |
Content-Type | application/scim+json |
Los endpoints de lista soportan paginación a través de los parámetros de consulta startIndex (basado en 1) y count (máx. 200), y filtrado a través del parámetro filter (por ejemplo, userName eq "[email protected]").
Usuarios
GET /scim/v2/Users — Lista usuarios con paginación y filtrado opcionales.
| Parámetro de consulta | Descripción |
|---|---|
startIndex | Índice basado en 1 del primer resultado (predeterminado: 1) |
count | Número máximo de resultados por página (máx.: 200) |
filter | Expresión de filtro SCIM (por ejemplo, userName eq "[email protected]") |
GET /scim/v2/Users/{id} — Obtiene un usuario individual por su ID de usuario de Authagonal.
POST /scim/v2/Users — Crea un nuevo usuario. Devuelve 201 Created.
| Campo | Requerido | Descripción |
|---|---|---|
userName | Sí | Dirección de correo electrónico (debe ser única dentro del inquilino) |
name.givenName | No | Nombre |
name.familyName | No | Apellido |
displayName | No | Nombre completo para mostrar |
active | No | Si el usuario está activo (predeterminado: true) |
externalId | No | Identificador del proveedor de identidad ascendente |
PUT /scim/v2/Users/{id} — Reemplazo completo de un recurso de usuario. Todos los campos deben proporcionarse.
PATCH /scim/v2/Users/{id} — Actualización parcial usando SCIM PatchOp.
| Operación | Rutas soportadas | Valor de ejemplo |
|---|---|---|
replace | active, name.givenName, name.familyName, externalId | true / false, o un valor de cadena |
add | name.givenName, name.familyName, externalId | Un valor de cadena |
remove | externalId | (no se necesita valor) |
DELETE /scim/v2/Users/{id} — Eliminación suave del usuario (desactiva la cuenta y revoca todos los tokens). Devuelve 204 No Content.
curl -X POST https://acme.authagonal.io/scim/v2/Users \
-H "Authorization: Bearer SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": {
"givenName": "Jane",
"familyName": "Smith"
},
"displayName": "Jane Smith",
"active": true,
"externalId": "ext-12345"
}'Grupos
GET /scim/v2/Groups — Lista todos los grupos con paginación y filtrado opcionales.
GET /scim/v2/Groups/{id} — Obtiene un grupo individual por ID, incluyendo su lista de miembros.
POST /scim/v2/Groups — Crea un nuevo grupo. Devuelve 201 Created.
| Campo | Requerido | Descripción |
|---|---|---|
displayName | Sí | Nombre para mostrar del grupo |
members | No | Array de objetos de miembros, cada uno con un campo value que contiene el ID de usuario |
externalId | No | Identificador del proveedor de identidad ascendente |
PUT /scim/v2/Groups/{id} — Reemplazo completo de un recurso de grupo (incluyendo su lista de miembros).
PATCH /scim/v2/Groups/{id} — Actualización parcial para añadir o eliminar miembros del grupo.
DELETE /scim/v2/Groups/{id} — Eliminación permanente del grupo. Devuelve 204 No Content.
curl -X PATCH https://acme.authagonal.io/scim/v2/Groups/GROUP_ID \
-H "Authorization: Bearer SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "add",
"path": "members",
"value": [
{ "value": "USER_ID_1" },
{ "value": "USER_ID_2" }
]
}
]
}'Respuestas de error SCIM
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "400", "detail": "..." }. Los códigos de estado comunes incluyen 400 (solicitud incorrecta), 404 (recurso no encontrado), 409 (conflicto / duplicado) y 429 (límite de velocidad alcanzado).API del portal (automatización)
La API del portal permite que tu propio backend automatice todo lo que puedes hacer en el portal — gestionar usuarios, clientes, grupos, roles, ámbitos, conexiones SSO y configuración — usando una credencial de máquina a máquina. Es la misma API que llama la interfaz del portal.
URL base: https://portal-api.<your-domain>/api/v1. Las solicitudes se autentican con un token de acceso Bearer; el inquilino se toma del token, no de la URL.
Crear una credencial de API
En el portal, abre Clients → Create API credential, elige un nivel de acceso y dale un nombre. Authagonal genera un cliente OAuth client_credentials configurado para la API del portal y devuelve un ID de cliente y un secreto.
Copia el secreto de inmediato
Niveles de acceso
| Ámbito | Concede |
|---|---|
tenant:owner | Acceso completo, incluidas las acciones destructivas exclusivas del propietario, como eliminar el inquilino completo. |
tenant:admin | Gestionar todo excepto las acciones exclusivas del propietario — usuarios, clientes, SSO, grupos, roles, marca y configuración. |
tenant:developer | Gestionar clientes, ámbitos y aplicaciones de aprovisionamiento. |
tenant:support | Leer y gestionar usuarios para tareas de soporte. |
Solo puedes conceder lo que tú posees
Obtener un token
Intercambia la credencial por un token de acceso en el endpoint de token de tu inquilino de administración — https://<your-tenant>.<your-domain>/connect/token — y luego envía el token como un encabezado Bearer a la API del portal. Los tokens son válidos durante una hora.
# 1. Exchange the credential for an access token (your tenant's token endpoint)
curl -X POST https://acme.authagonal.io/connect/token \
-d grant_type=client_credentials \
-d client_id=api-3f2a... \
-d client_secret=YOUR_CLIENT_SECRET \
-d scope=tenant:admin
# Response: { "access_token": "ey...", "token_type": "Bearer", "expires_in": 3600 }
# 2. Call the Portal API with the access token
curl https://portal-api.authagonal.io/api/v1/users \
-H "Authorization: Bearer $ACCESS_TOKEN"Endpoints
Todas las rutas son relativas a la URL base y requieren un token de acceso Bearer. El ámbito junto a cada grupo es el nivel de acceso mínimo que necesitan las credenciales. Los endpoints de listado aceptan los parámetros de consulta startIndex y count.
tenant:developerGET/api/v1/clients— Listar clientes OAuth.
GET/api/v1/clients/{id}— Obtener un cliente por su ID.
POST/api/v1/clients— Crear un cliente. Devuelve el ID del cliente y, para clientes confidenciales, un secreto de un solo uso.
PUT/api/v1/clients/{id}— Actualizar un cliente (URIs de redirección, tipos de concesión, duración de tokens, requisitos PKCE/PAR).
DELETE/api/v1/clients/{id}— Eliminar un cliente.
POST/api/v1/clients/api-credential— Generar una credencial de API del Portal de máquina a máquina.
tenant:supportGET/api/v1/users— Listar usuarios. Admite count, search (prefijo de correo o nombre), organizationId para filtrar por una organización y after para paginación por cursor.
GET/api/v1/users/count— Número total de usuarios del inquilino.
GET/api/v1/users/stats/mfa— Estadísticas de inscripción en MFA.
GET/api/v1/users/{id}— Obtener un usuario.
POST/api/v1/users— Crear un usuario con correo y contraseña.
PUT/api/v1/users/{id}— Actualizar un usuario (perfil, correo, estado activado/bloqueado, organizationId).
DELETE/api/v1/users/{id}— Eliminar un usuario.
GET/api/v1/users/{id}/mfa— Get a user's enrolled MFA methods.
DELETE/api/v1/users/{id}/mfa— Reset a user's MFA enrollment.
tenant:adminGET/api/v1/roles— Listar roles.
POST/api/v1/roles— Crear un rol.
DELETE/api/v1/roles/{id}— Eliminar un rol.
POST/api/v1/roles/assign— Asignar un rol a un usuario.
POST/api/v1/roles/unassign— Quitar un rol de un usuario.
tenant:adminGET/api/v1/groups— Listar grupos.
GET/api/v1/groups/{id}— Obtener un grupo con sus miembros.
POST/api/v1/groups— Crear un grupo.
POST/api/v1/groups/{id}/members— Agregar miembros a un grupo.
DELETE/api/v1/groups/{groupId}/members/{userId}— Eliminar un miembro de un grupo.
DELETE/api/v1/groups/{id}— Eliminar un grupo.
GET/api/v1/group-role-mappings— Listar las asignaciones de grupo a rol (roles concedidos al emitir el token según la pertenencia al grupo).
tenant:developerGET/api/v1/scopes— Listar ámbitos de API.
POST/api/v1/scopes— Crear un ámbito.
DELETE/api/v1/scopes/{name}— Eliminar un ámbito.
tenant:adminGET/api/v1/saml/connections— Listar conexiones SAML.
POST/api/v1/saml/connections— Crear una conexión SAML.
DELETE/api/v1/saml/connections/{id}— Eliminar una conexión SAML.
GET/api/v1/oidc/connections— Listar conexiones OIDC.
POST/api/v1/oidc/connections— Crear una conexión OIDC.
DELETE/api/v1/oidc/connections/{id}— Eliminar una conexión OIDC.
GET/api/v1/sso/domains— Listar los dominios enrutados a conexiones SSO (descubrimiento de dominio de origen).
tenant:adminGET/api/v1/branding— Obtener la personalización del inquilino (colores, logotipo, idiomas admitidos).
PUT/api/v1/branding— Actualizar la personalización del inquilino.
tenant:adminGET/api/v1/settings— Obtener la configuración del inquilino (webhooks, registro público, política de tokens).
PUT/api/v1/settings— Actualizar la configuración del inquilino.
POST/api/v1/settings/webhook-secret/regenerate— Rotar el secreto de firma del webhook.
POST/api/v1/settings/test-email— Enviar un correo de prueba con la configuración de correo actual.
tenant:adminGET/api/v1/custom-domains— Listar los dominios de inicio de sesión personalizados y su estado de verificación.
POST/api/v1/custom-domains— Agregar un dominio personalizado.
POST/api/v1/custom-domains/{domain}/verify— Iniciar la verificación DNS de un dominio personalizado.
DELETE/api/v1/custom-domains/{domain}— Eliminar un dominio personalizado.
GET/api/v1/email/domains— Listar los dominios de correo del remitente.
tenant:adminGET/api/v1/audit— Consultar el registro de auditoría del inquilino.
Aprovisionamiento de usuarios mediante SCIM
Ejemplo: crear un usuario
curl -X POST https://portal-api.authagonal.io/api/v1/users \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "S3cure-temp-passw0rd",
"firstName": "Ada",
"lastName": "Lovelace"
}'
# 200 OK
# { "userId": "8f3a...", "email": "[email protected]" }Todo lo que la interfaz puede hacer
Pantallas de inicio de sesión
Estas son las pantallas alojadas que tus usuarios finales ven en el servidor de autenticación de tu inquilino. Authagonal incluye todas las pantallas listas para usar, así que obtienes una experiencia de inicio de sesión completa y segura sin construir ninguna interfaz. Esta página recorre cada pantalla y muestra qué ajustes del portal la controlan.
Marca blanca completa
prefers-color-scheme, por lo que cambian entre claro y oscuro para coincidir con el dispositivo del usuario.Inicio de sesión


- Flujo de dos pasos, con el correo primero: el usuario introduce su correo y hace clic en Continuar, y entonces aparece el campo de contraseña.
- Los botones de inicio de sesión único «Continuar con {provider}» aparecen automáticamente cuando existen conexiones SSO.
- Enlaces de olvidé mi contraseña y crear cuenta, cada uno de los cuales se puede mostrar u ocultar.
- Captcha opcional de Cloudflare Turnstile para disuadir intentos de inicio de sesión automatizados.
Controlado en la administración del portal
- Marca define el logotipo, el color, el nombre de la aplicación, el correo de soporte y el CSS personalizado.
- Muestra u oculta los enlaces de olvidé mi contraseña y registro (Marca).
- Las conexiones SSO añaden los botones de inicio de sesión social (página SSO).
- Duración de la sesión y umbrales de bloqueo (Configuración → Seguridad).
Registro


- Recopila nombre y apellido (opcional), correo electrónico y una contraseña.
- Una lista de verificación de la política de contraseñas en vivo se actualiza a medida que el usuario escribe, así los requisitos quedan claros antes de enviar.
- Captcha opcional de Cloudflare Turnstile.
- Un enlace de «Iniciar sesión» para usuarios que ya tienen una cuenta.
Controlado en la administración del portal
- Muestra u oculta el enlace de registro (Marca).
- La política de contraseñas de tu inquilino controla la lista de verificación.
- Marca da estilo a toda la pantalla.
Olvidé mi contraseña


- El usuario introduce su correo y luego ve una confirmación neutral de «revisa tu correo».
- La pantalla nunca revela si una cuenta existe, lo que frustra los sondeos de enumeración de cuentas.
- Un enlace de «Volver al inicio de sesión» devuelve al usuario a la pantalla de inicio de sesión.
Controlado en la administración del portal
- Muestra u oculta el enlace de olvidé mi contraseña (Marca).
- La entrega de correo de tu inquilino envía el mensaje de restablecimiento.
- Marca da estilo a toda la pantalla.
Restablecer contraseña


- Campos de nueva contraseña y confirmar contraseña con una lista de verificación de requisitos por regla en vivo.
- Un estado claro de enlace no válido o caducado cuando el token de restablecimiento ya no es válido.
- Un estado de éxito que confirma que la contraseña se ha cambiado.
Controlado en la administración del portal
- La política de contraseñas de tu inquilino controla la lista de verificación.
- Marca da estilo a toda la pantalla.
Desafío MFA


- Un selector de método entre aplicación autenticadora, passkey y código de recuperación.
- Un campo TOTP de 6 dígitos que se envía automáticamente una vez introducidos todos los dígitos.
- Entrada de código de recuperación para usuarios que han perdido el acceso a su autenticador.
- Un botón de passkey para verificación respaldada por hardware.
Controlado en la administración del portal
- La política de MFA se configura por aplicación (Clientes → Seguridad).
- A cualquier usuario con un factor registrado siempre se le exige el desafío, independientemente de la política.
Configuración de MFA


- Muestra el estado de los métodos registrados para que el usuario sepa qué ya está configurado.
- Configuración del autenticador mediante código QR, una clave manual de respaldo y un paso de confirmación.
- Registro de passkey para autenticación respaldada por hardware.
- Generación de códigos de recuperación para recuperar la cuenta.
- Una opción de omitir cuando el MFA es de autoservicio en lugar de obligatorio.
Controlado en la administración del portal
- La política de MFA se configura por aplicación; Obligatorio fuerza la configuración al iniciar sesión (Clientes → Seguridad).
- Marca da estilo a toda la pantalla.
Autorización de dispositivo


- Un campo centrado de entrada del código de usuario para el código mostrado en el dispositivo.
- Un paso de aprobación para autorizar el dispositivo.
- Un interstitial de inicio de sesión cuando el usuario aún no está autenticado.
- Una confirmación de aprobación una vez que el dispositivo está autorizado.
Controlado en la administración del portal
- Habilita la concesión de código de dispositivo en la aplicación (Clientes → Tipos de concesión).
- Establece la duración del código de dispositivo (Clientes → Tokens).
Consentimiento


- Muestra el logotipo y nombre del cliente que hace la solicitud.
- Una lista por scope con etiquetas claras y legibles para cada permiso.
- Botones de Permitir y Denegar para conceder o rechazar el acceso.
- Un pie con una nota de consentimiento que explica lo que significa la decisión.
Controlado en la administración del portal
- Activa Requerir consentimiento por aplicación (Clientes → Seguridad).
- El logotipo, el nombre y la URL provienen de los propios metadatos de la aplicación.
- Marca pinta la tarjeta de consentimiento.
Aplicaciones conectadas (concesiones)


- Lista todas las apps que el usuario ha autorizado, con su nombre, ámbitos y fecha de concesión.
- Revoca el acceso a una app, con un paso de confirmación antes de que surta efecto.
- Un estado vacío amigable cuando el usuario no ha autorizado ninguna app.
Controlado en la administración del portal
- La lista se llena con las aplicaciones que requieren consentimiento.
- Marca da estilo a toda la pantalla.
Cuenta
Una página de cuenta de autoservicio alojada en /login/account donde los usuarios que han iniciado sesión gestionan su propio perfil e idioma preferido, sin necesidad de acceso al portal.


- Editar nombre y apellidos, empresa y teléfono; la dirección de correo se muestra en solo lectura.
- Elegir un idioma preferido entre los idiomas soportados; la interfaz previsualiza la elección al instante y la conserva al guardar.
- El idioma guardado controla la interfaz alojada del usuario y el idioma de los correos transaccionales que recibe.
Controlado en la administración del portal
- Branding da estilo a toda la pantalla.
- El mismo idioma preferido puede ser editado por un administrador en la página de Usuarios del portal.
Flujos de autenticación
Los flujos de autenticación cubren cómo los usuarios finales interactúan con tu inquilino de Authagonal — iniciar sesión, registrarse, restablecer contraseñas y configurar MFA. Estos endpoints son utilizados por la página de inicio de sesión alojada y pueden llamarse directamente si estás construyendo una interfaz de inicio de sesión personalizada.
Inicio de sesión
POST /api/auth/login
Autentica a un usuario con correo electrónico y contraseña. En caso de éxito, firma una cookie de sesión y devuelve el perfil del usuario. Si MFA está configurado, la respuesta indica que se requiere un segundo factor antes de que la sesión esté completamente establecida.
Cuerpo de la solicitud:
{
"email": "[email protected]",
"password": "correct-horse-battery-staple"
}Respuesta exitosa:
| Campo | Tipo | Descripción |
|---|---|---|
userId | string | Identificador único del usuario |
email | string | Dirección de correo electrónico del usuario |
name | string | Nombre completo para mostrar |
mfaAvailable | boolean | Si el usuario tiene métodos MFA inscritos |
Respuesta de MFA requerido: Cuando el usuario tiene MFA inscrito, la respuesta incluye mfaRequired: true junto con un challengeId y un array methods que lista los métodos MFA disponibles.
Respuesta de configuración de MFA requerida: Cuando el inquilino requiere MFA pero el usuario aún no se ha inscrito, la respuesta incluye mfaSetupRequired: true con un setupToken para el flujo de inscripción.
Respuestas de error:
| Código de error | Estado HTTP | Descripción |
|---|---|---|
invalid_credentials | 401 | El correo electrónico o la contraseña son incorrectos |
account_disabled | 403 | La cuenta ha sido desactivada por un administrador |
email_not_confirmed | 403 | El usuario no ha verificado su dirección de correo electrónico |
locked_out | 423 | La cuenta está temporalmente bloqueada (incluye retryAfter en segundos) |
sso_required | 409 | El dominio de correo electrónico tiene SSO configurado (incluye redirectUrl) |
Verificación SSO: Si el dominio de correo electrónico del usuario tiene una conexión SSO configurada, el endpoint de inicio de sesión devuelve sso_required con un redirectUrl. El cliente debe redirigir al usuario al proveedor SSO.
Bloqueo de cuenta: Después de maxFailedAttempts intentos consecutivos de inicio de sesión fallidos, la cuenta se bloquea durante lockoutDurationMinutes. Ambos valores son configurables en la configuración del inquilino.
Página de inicio de sesión alojada
Registro
POST /api/auth/register
Crea una nueva cuenta de usuario. Se envía un correo electrónico de verificación automáticamente — el usuario debe verificar su correo electrónico antes de poder iniciar sesión.
Cuerpo de la solicitud:
{
"email": "[email protected]",
"password": "a-strong-password-here",
"firstName": "Jane",
"lastName": "Smith"
}| Campo | Requerido | Descripción |
|---|---|---|
email | Sí | Dirección de correo electrónico (debe ser única) |
password | Sí | Debe cumplir con la política de contraseñas del inquilino |
firstName | No | Nombre |
lastName | No | Apellido |
Éxito: 201 Created con el userId de la nueva cuenta. Registrarse con un correo que ya existe también devuelve 201: nunca revelamos si un correo está registrado (para evitar la enumeración de cuentas) y, en su lugar, avisamos por correo al titular real de la cuenta.
Respuestas de error:
| Código de error | Estado HTTP | Descripción |
|---|---|---|
weak_password | 400 | La contraseña no cumple con la política de contraseñas del inquilino |
rate_limited | 429 | Demasiados intentos de registro |
provisioning_rejected | 422 | Un webhook de aprovisionamiento rechazó el registro |
Política de contraseñas
/api/auth/password-policy. Esto devuelve la longitud mínima, las clases de caracteres requeridas y si la verificación de contraseñas comprometidas está habilitada.Restablecimiento de contraseña
POST /api/auth/forgot-password
Solicita un correo electrónico de restablecimiento de contraseña. El endpoint siempre devuelve una respuesta exitosa independientemente de si el correo electrónico existe, para prevenir la enumeración de correos electrónicos.
{
"email": "[email protected]"
}POST /api/auth/reset-password
Restablece la contraseña del usuario usando el token del enlace del correo electrónico.
{
"token": "RESET_TOKEN_FROM_EMAIL",
"newPassword": "new-strong-password"
}Efectos secundarios de un restablecimiento de contraseña exitoso:
- El contador de intentos de inicio de sesión fallidos se reinicia a cero
- Todos los tokens de actualización existentes son revocados
- Se genera un nuevo sello de seguridad (invalidando todas las sesiones existentes)
Configuración y verificación de MFA
Authagonal soporta tres métodos MFA: TOTP (aplicaciones autenticadoras), WebAuthn (llaves de seguridad y biometría) y códigos de recuperación de un solo uso.
Configuración TOTP
POST /api/auth/mfa/totp/setup — Devuelve un URI de datos de código QR y una clave de entrada manual. El usuario escanea el código QR con su aplicación autenticadora (Google Authenticator, Authy, 1Password, etc.) y luego confirma la inscripción.
POST /api/auth/mfa/totp/confirm — Confirma la inscripción TOTP validando un código de 6 dígitos de la aplicación autenticadora.
{
"code": "123456"
}Configuración WebAuthn
POST /api/auth/mfa/webauthn/setup — Devuelve opciones de creación de credenciales para la API WebAuthn. El navegador llama a navigator.credentials.create() con estas opciones.
POST /api/auth/mfa/webauthn/confirm — Confirma la inscripción WebAuthn enviando la respuesta de atestación del navegador.
Códigos de recuperación
POST /api/auth/mfa/recovery/generate — Genera 10 códigos de recuperación de un solo uso de 8 caracteres. Cada código puede usarse exactamente una vez para omitir MFA.
Los códigos de recuperación se muestran solo una vez
Verificación MFA
POST /api/auth/mfa/verify — Completa el desafío MFA después de un inicio de sesión exitoso con contraseña.
| Campo | Requerido | Descripción |
|---|---|---|
challengeId | Sí | El ID del desafío de la respuesta de inicio de sesión |
method | Sí | "totp", "recovery" o "webauthn" |
code | TOTP / Recuperación | Código TOTP de 6 dígitos o código de recuperación de 8 caracteres |
assertion | WebAuthn | La respuesta de aserción de navigator.credentials.get() |
Estado de MFA
GET /api/auth/mfa/status — Devuelve los métodos MFA actualmente inscritos del usuario.
Flujo de inicio de sesión SSO
Authagonal soporta tanto conexiones SSO basadas en SAML 2.0 como en OIDC. El enrutamiento basado en dominio detecta automáticamente qué proveedor SSO usar según la dirección de correo electrónico del usuario.
Verificación SSO
GET /api/auth/[email protected]
| Campo | Tipo | Descripción |
|---|---|---|
ssoRequired | boolean | Si el dominio de correo electrónico requiere SSO |
providerType | string | "saml" o "oidc" |
connectionId | string | El identificador de la conexión SSO |
redirectUrl | string | La URL a la que redirigir al usuario para el inicio de sesión SSO |
Flujo SAML
El usuario es redirigido a GET /saml/{connectionId}/login que envía una AuthnRequest SAML al proveedor de identidad. El IdP autentica al usuario y publica una respuesta SAML de vuelta al endpoint del Assertion Consumer Service (ACS). Authagonal valida la aserción, crea o actualiza al usuario y firma una cookie de sesión.
Los metadatos SAML para configurar tu IdP están disponibles en GET /saml/{connectionId}/metadata.
Flujo OIDC
El usuario es redirigido a GET /oidc/{connectionId}/login que redirige al proveedor de identidad ascendente con PKCE. Después de que el usuario se autentica, el callback en /oidc/callback intercambia el código de autorización, valida el token de ID y crea o actualiza al usuario.
Aprovisionamiento JIT: Tanto los flujos SAML como OIDC soportan aprovisionamiento just-in-time. Si el usuario no existe ya en el inquilino, se crea automáticamente a partir de las reclamaciones del proveedor de identidad. Si ya existe, sus atributos de perfil se actualizan para coincidir con los valores más recientes del proveedor.
Enrutamiento basado en dominio
Backend-for-Frontend (BFF)
Un BFF mantiene los tokens de OAuth completamente fuera del navegador. Tu aplicación de página única no guarda más que una cookie de sesión httpOnly, y un cliente confidencial en tu propio backend ejecuta el flujo de OpenID Connect y guarda los tokens en el servidor.
Todo lo que una aplicación de página única puede leer, el cross-site scripting lo puede robar, y eso incluye un token de acceso en memoria y un token de actualización en localStorage. Guardar tokens en el navegador también limita su duración, porque un token de actualización de larga vida al alcance de los scripts es un riesgo permanente. La mejor práctica actual del IETF OAuth 2.0 for Browser-Based Apps recomienda este patrón exactamente por esa razón.
A cambio obtienes una sesión que sobrevive a una recarga de página sin un solo token a la vista, la renovación resuelta por ti en el servidor, revocación inmediata mediante el cierre de sesión back-channel, y un proxy autenticado para que tu API nunca tenga que analizar un token que el navegador podría haber manipulado.
Crear el cliente
En el portal, abre Clientes y elige Crear app BFF. Indica la URL base desde la que se sirve tu aplicación, por ejemplo https://app.acme.com, y Authagonal registra por ti un cliente confidencial correctamente configurado en lugar de dejarte armarlo a mano:
| Configuración | Valor |
|---|---|
| URI de redirección | {appBaseUrl}/bff/callback |
| URI de redirección tras el cierre de sesión | {appBaseUrl}/ |
| URI de cierre de sesión back-channel | {appBaseUrl}/bff/backchannel-logout |
| Tipos de concesión | authorization_code, refresh_token |
| Ámbitos | openid, profile, email, offline_access |
| PKCE y secreto de cliente | Ambos obligatorios |
El secreto se muestra una sola vez
clientId, clientSecret y authority, y después el secreto ya no se puede recuperar porque solo se almacena su hash. Guárdalo directamente en la configuración o en el almacén de secretos de tu backend. Si lo pierdes, crea otro cliente en lugar de intentar recuperar este.Conéctalo a tu backend
Hay dos entornos de ejecución compatibles y se comportan igual: Authagonal.Bff para .NET y @authagonal/bff para Node, este último con adaptadores para Express y Next.js. Apunta cualquiera de los dos a los valores que el portal acaba de darte.
// dotnet add package Authagonal.Bff
builder.Services.AddAuthagonalBff(o =>
{
o.Authority = "https://acme.authagonal.io"; // your tenant auth host
o.ClientId = builder.Configuration["Bff:ClientId"]!;
o.ClientSecret = builder.Configuration["Bff:ClientSecret"]!;
o.Scope = ["openid", "profile", "email", "offline_access"];
o.PostLogoutRedirectUri = "https://app.acme.com/";
});
var app = builder.Build();
app.UseForwardedHeaders(); // required behind a proxy or ingress, see the note below
app.MapAuthagonalBff();
app.MapFallbackToFile("index.html"); // your SPA
app.Run();// npm install @authagonal/bff
import express from 'express';
import { authagonalBff } from '@authagonal/bff/express';
const app = express();
app.use(authagonalBff({
authority: 'https://acme.authagonal.io',
clientId: process.env.BFF_CLIENT_ID,
clientSecret: process.env.BFF_CLIENT_SECRET,
scope: ['openid', 'profile', 'email', 'offline_access'],
postLogoutRedirectUri: 'https://app.acme.com/',
}));
app.listen(8080);Detrás de un proxy, confía en las cabeceras reenviadas
__Host- sin el atributo Secure, que los navegadores descartan entonces en silencio. El síntoma es un inicio de sesión que se completa sin errores y una sesión que nunca aparece. En .NET, llama a app.UseForwardedHeaders() antes de MapAuthagonalBff(); en Node, activa la opción trust-proxy de tu framework.Endpoints
Se montan bajo /bff de forma predeterminada. Deben servirse desde el mismo origen que tu SPA, porque la cookie de sesión es httpOnly y de mismo origen: ponlos detrás del mismo nombre de host y no en un dominio de API aparte.
| Ruta | Propósito |
|---|---|
GET /bff/login?returnUrl=/ | Arranca el inicio de sesión y redirige a Authagonal. Después devuelve al usuario a returnUrl. |
GET /bff/callback | La URI de redirección de OIDC. Se gestiona por ti; nunca tienes que escribirla. |
GET /bff/user | Devuelve isAuthenticated, las reclamaciones de la sesión y sessionExpiresAt. Requiere la cabecera anti-falsificación. |
GET|POST /bff/logout | Cierra la sesión localmente y en Authagonal. |
POST /bff/backchannel-logout | Recibe las notificaciones de cierre de sesión de Authagonal, de modo que un cierre de sesión en otro sitio también termina esta sesión. |
Desde el navegador
Toda solicitud que no sea de navegación debe llevar una cabecera anti-falsificación estática. Protege frente a la falsificación de solicitudes entre sitios junto con el atributo SameSite de la cookie: el envío de un formulario entre sitios no puede establecer una cabecera personalizada, así que una solicitud que no la lleve se rechaza.
const me = await fetch('/bff/user', {
headers: { 'X-Authagonal-Bff': '1' },
}).then(r => r.json());
if (!me.isAuthenticated) {
// Navigate, do not fetch: this is a redirect to your identity provider.
window.location.href = '/bff/login?returnUrl=' + encodeURIComponent(location.pathname);
}Inicia y cierra sesión navegando, no con fetch: location.href = '/bff/login'. Esas rutas responden con una redirección a tu proveedor de identidad, y una cadena de redirecciones no es algo que fetch pueda seguir de forma útil.
Llamar a tu API
El BFF puede reenviar tu API bajo su propia ruta base y adjuntar el token de acceso de la sesión al pasar. El navegador envía una cookie, tu API recibe un token Bearer que valida de la forma habitual, y nada de ese token es visible para la página ni falsificable por ella. Registra un upstream y las solicitudes a /bff/api/** llegan a él autenticadas. Deja la lista vacía y el proxy queda deshabilitado por completo.
o.Upstreams.Add(new BffUpstream
{
Prefix = "/orders", // matches /bff/api/orders/**
TargetBaseUrl = "https://api.internal.acme.com",
StripPrefix = false, // keep /orders in the forwarded path
});| Opción | Predeterminado | Qué hace |
|---|---|---|
Upstreams | [] | Las API a las que reenvía el proxy. Vacío deshabilita el endpoint del proxy. |
Prefix | / | Prefijo de ruta después de /bff/api que gestiona este upstream, por ejemplo /orders. |
TargetBaseUrl | - | URL base a la que se reenvían las solicitudes. |
StripPrefix | false | Elimina el prefijo coincidente antes de reenviar. Te permite usar un prefijo de enrutamiento sintético para repartir un mismo BFF entre varios backends que comparten un espacio de nombres de rutas. |
AllowAnonymousProxyRequests | false | Reenvía sin cabecera Authorization una solicitud que no tenga una sesión utilizable, en lugar de rechazarla. Para una API que atiende tanto a llamantes con sesión iniciada como anónimos. |
RequiredAuthority | [] | Un control de autoridad expresado como pares type:action, por ejemplo email:send. Cuando se establece, el proxy comprueba los authorization details del RFC 9396 del token saliente antes de reenviar. |
AuthorityLocation | - | La raíz de locations del RFC 9396 por la que se conoce a este upstream, cuando la autoridad se concede sobre un identificador de recurso público distinto de la dirección interna a la que llama el proxy. |
StrictAuthority | false | Rechaza una llamada que lleve una restricción de concesión que el proxy no puede evaluar, en lugar de reenviarla. El proxy reenvía a ciegas y no deriva ningún contexto de restricción, así que está desactivado de forma predeterminada. |
ExchangeRoutes | [] | Rutas del proxy cuyas llamadas al upstream viajan con un token intercambiado y vinculado a un contexto, en lugar del token de acceso principal de la sesión. Gana el primer patrón que coincida. |
WebSockets
Un handshake de WebSocket no puede llevar una cabecera personalizada ni un token Bearer, así que aquí no sirven ni la cabecera anti-falsificación ni el proxy. Habilita los tickets y la SPA podrá llamar a GET /bff/ws-ticket, poner en la URL de conexión el ticket de un solo uso y corta duración, y hacer que tu API lo canjee. Genera uno justo antes de cada conexión: se elimina en el primer uso y expira en segundos.
| Opción | Predeterminado | Qué hace |
|---|---|---|
WsTicketsEnabled | false | Habilita el endpoint ws-ticket. Desactivado de forma predeterminada. |
WsTicketLifetime | 30s | Cuánto tiempo es válido un ticket. Se mantiene corto a propósito, ya que viaja en una URL. |
TicketExchangeParams | [] | Parámetros de consulta que una solicitud de ticket puede reenviar a un intercambio de tokens, de modo que el ticket queda vinculado a ese contexto en lugar de ser válido para todo. |
Entregar un token al navegador, a propósito
Todo el sentido de un BFF es que el navegador no guarda ningún token, así que esto es opcional y de alcance limitado. Existe para el único caso al que el modelo de cookie no llega: un servidor de recursos en otro origen, como una aplicación que incrustas en un iframe, al que hay que llamar con un token Bearer. Habilitado, GET /bff/token?resource=… devuelve un token intercambiado: el token de la sesión reducido a un único recurso de la lista de permitidos y vinculado a cualquier parámetro de contexto también permitido. El navegador nunca ve el token propio de la sesión, y lo que sí recibe es de corta duración y para una sola audiencia. Se rechaza toda solicitud que nombre un recurso fuera de la lista de permitidos, que es lo que impide que esto sea una fábrica de tokens de uso general.
| Opción | Predeterminado | Qué hace |
|---|---|---|
TokenEndpointEnabled | false | Habilita el endpoint de token. Desactivado de forma predeterminada. |
TokenEndpointResources | [] | Los valores de resource a los que puede dirigirse un token. Cualquier otro se rechaza. |
TokenEndpointExchangeParams | [] | Parámetros de consulta que se reenvían al intercambio como vínculos de contexto, por ejemplo project_id. |
Servir a varios inquilinos desde un solo BFF
Establece un parámetro de consulta de inquilino y un solo despliegue atiende a muchos inquilinos: /bff/login?slug=acme selecciona el inquilino, un resolutor aporta la authority y las credenciales de cliente de ese inquilino, la clave viaja en la cookie de correlación hasta la sesión, y el cierre de sesión back-channel resuelve el inquilino a partir del emisor del token. El resolutor predeterminado mantiene el comportamiento de inquilino único idéntico byte a byte, así que esto no te cuesta nada mientras no lo uses.
Opciones que conviene conocer
El conjunto completo. El paquete de Node los refleja en camelCase, así que BasePath es basePath y así sucesivamente.
| Opción | Predeterminado | Qué hace |
|---|---|---|
Authority | - | El host de autenticación de tu inquilino. De él se descubren los metadatos OIDC. Obligatorio salvo que trabajes en modo multiinquilino, donde lo aporta el resolutor. |
ClientId | - | El id del cliente confidencial registrado para este BFF. |
ClientSecret | - | El secreto de cliente. Un BFF es un cliente confidencial, así que es obligatorio. |
Scope | openid profile offline_access | Ámbitos solicitados. Incluye offline_access o no habrá token de actualización y las sesiones terminarán cuando lo haga el token de acceso. |
BasePath | /bff | Dónde se montan las rutas del BFF. |
CallbackPath | /bff/callback | La ruta de la URI de redirección de OIDC. Debe coincidir con la que tiene registrada el cliente. |
CookieName | __Host-agbff | Nombre de la cookie de sesión. El prefijo __Host- exige HTTPS, así que el desarrollo local sobre HTTP plano necesita otro nombre. |
SessionLifetime | 8h | Cuánto puede durar una sesión. Ajústalo para que coincida con la duración absoluta de tu token de actualización, o un usuario inactivo quedará desconectado mientras conserva una credencial que aún era válida. |
PersistentCookie | false | Si la cookie sobrevive al cierre del navegador. El token de actualización permanece en el servidor en cualquier caso. |
CorrelationLifetime | 30m | Cuánto puede tardar un inicio de sesión entre que comienza y llega el callback. Acota la cookie que lleva el state, el nonce y el verificador PKCE, así que el caso que tiene que soportar es el de un usuario que deja abierta la pantalla de inicio de sesión y vuelve más tarde. |
RefreshThresholdSeconds | 60 | Cuántos segundos antes de su expiración se renueva el token de acceso. |
AntiForgeryHeader | X-Authagonal-Bff | El nombre de la cabecera que el navegador debe enviar en las solicitudes que no son de navegación. |
PostLogoutRedirectUri | - | Dónde aterriza el navegador cuando se completa el cierre de sesión. |
ReturnUrlAllowlist | [] | Orígenes absolutos a los que puede apuntar un returnUrl no relativo. Las rutas relativas se permiten siempre y todo lo demás se fuerza a /, de modo que no se puede llegar a una redirección abierta por la ruta de inicio de sesión. |
LoginPassthroughParams | [] | Parámetros de consulta que se reenvían desde /bff/login a la solicitud de autorización, por ejemplo prompt, para que un enlace de bienvenida lleve al registro en lugar de al inicio de sesión. |
TenantQueryParam | - | Establécelo para servir a varios inquilinos desde un solo BFF. Ver más arriba. |
Ambos entornos de ejecución se comportan igual
Todo es reemplazable
IBffSessionStore para dónde viven las sesiones, ICookieProtector para el cifrado de la cookie (ASP.NET Data Protection de forma predeterminada) y ITokenClient para hablar con los endpoints de token y de revocación. Un mismo BFF también puede servir a varios inquilinos mediante IBffTenantResolver, seleccionando el inquilino a partir de un parámetro de consulta en el inicio de sesión y resolviéndolo a partir del emisor del token en el cierre de sesión back-channel.Gestiona tu portal desde un asistente de IA
Conecta un asistente de IA a tu inquilino y pídele que haga lo que de otro modo harías a base de clics: encontrar a un usuario que no puede iniciar sesión, comprobar si todavía tiene un segundo factor, invitar a alguien, ver quién tiene un rol de administrador.
Es una conexión OAuth corriente, no una clave API. Cada persona inicia sesión como ella misma y aprueba el acceso, así que un asistente puede hacer exactamente lo que esa persona puede hacer en el portal y nada más. No se crea nada nuevo que pueda filtrarse, y revocar un asistente deja intactos a todos los demás.
Cómo activarlo
Abre Configuración y activa el acceso de asistentes de IA. Hasta que lo hagas está desactivado, y mientras está desactivado el endpoint no existe, en lugar de limitarse a rechazar. Una vez activado, el panel muestra la URL que hay que pegar en tu cliente de IA:
https://portal-api.authagonal.io/api/v1/mcp/{your-tenant}Cómo obtiene permiso un asistente
Qué puede hacer un asistente
Exactamente lo que puede hacer la persona que lo conectó, decidido en cada llamada contra su propio token. Un agente con tenant:support obtiene las herramientas de diagnóstico y del día a día; las herramientas de administrador no solo están ocultas para él, se rechazan si las nombra directamente. Todo lo que está restringido dentro del portal sigue restringido: cambiar la dirección de correo de un usuario exige allí el rol de administrador, y aquí lo exige también.
Como es una concesión normal, la gestionas de la forma normal. Revócala y el asistente deja de funcionar de inmediato, en lugar de al expirar el siguiente token. Todo lo que hace un asistente queda escrito en tu registro de auditoría a nombre de la persona por la que actuó, así que el rastro es el mismo que ya lees.
Las herramientas
Veinte en esta versión. Tu cliente de IA decide cuáles habilitar, así que puedes darle a un asistente solo las herramientas de lectura si es todo lo que quieres que haga.
| Herramienta | Rol | Qué hace |
|---|---|---|
find_user | Soporte | Buscar usuarios por correo, prefijo de nombre o id. El punto de partida para todo lo demás. |
get_user | Soporte | Un usuario completo, incluido si está activo, confirmado y bloqueado. |
get_user_mfa | Soporte | Qué segundos factores tiene inscritos alguien. |
get_user_sessions | Soporte | Dónde tiene sesión iniciada un usuario en este momento. |
search_audit | Soporte | Buscar en el registro de auditoría por actor, acción u objeto afectado. |
list_users | Soporte | Listar el directorio, opcionalmente filtrado a una organización. |
get_user_stats | Soporte | Cuántos usuarios tienes y cuántos usan un segundo factor. |
invite_user | Soporte | Invitar a alguien por correo. |
resend_invite | Soporte | Enviar de nuevo una invitación. |
send_verification_email | Soporte | Enviar de nuevo el mensaje de verificación de correo. |
update_user | Soporte | Actualizar un perfil. El correo, el estado de confirmación y la organización siguen requiriendo el rol de administrador. |
revoke_user_sessions | Soporte | Cerrar la sesión de un usuario en todas partes. |
list_roles | Administrador | Los roles definidos en tu inquilino. |
list_role_members | Administrador | Quién tiene un rol determinado. |
assign_role | Administrador | Dar un rol a un usuario. |
unassign_role | Administrador | Quitar un rol. |
reset_user_mfa | Administrador | Eliminar todos los segundos factores, para alguien que ha perdido su autenticador. |
get_settings | Administrador | La configuración de tu inquilino. |
list_sso_connections | Administrador | Tus conexiones SSO y los dominios que cubren. |
list_clients | Desarrollador | Los clientes OAuth registrados en tu inquilino. |
Lectura y escritura vienen marcadas
Qué no está incluido todavía
Eliminar usuarios, crear o editar conexiones SSO, la facturación, las copias de seguridad y los secretos de cliente están todos ausentes de esta versión. Eliminar pertenece a tu cola de borrado y no a un sitio contiguo; una conexión SSO pesa lo suficiente como para que una edición equivocada deje fuera a toda una plantilla, así que por ahora son de solo lectura; y una herramienta que devolviera un secreto de cliente lo dejaría en la transcripción de un asistente. Dinos cuáles de estas quieres y en qué orden.
Autenticación de servidores MCP
Si expones un servidor Model Context Protocol, Authagonal puede ser el servidor de autorización que hay detrás. Un asistente de IA se conecta, la persona que está detrás inicia sesión y concede el acceso, y tu servidor recibe un token bearer normal que validas como el de cualquier otra API.
La alternativa es una clave API pegada en la configuración de un asistente: una credencial sin ningún usuario detrás, sin caducidad, sin paso de consentimiento y sin forma de revocar un conector sin rotarla para todo el mundo. Hacerlo con OAuth significa que la concesión pertenece a una persona con nombre, es visible en tu registro de auditoría y se puede revocar desde el portal sin tocar nada más.
Cómo se produce la conexión
Todo el intercambio se basa en el descubrimiento, así que un cliente conforme no necesita más configuración que la URL de tu servidor.
| Paso | Qué ocurre |
|---|---|
| 1 | El conector llama a tu servidor MCP sin token y recibe un 401 que indica dónde mirar. |
| 2 | Obtiene los metadatos de tu recurso protegido, que nombran a tu inquilino de Authagonal como servidor de autorización. |
| 3 | Obtiene los metadatos del servidor de autorización del inquilino y, al no haberse registrado nunca en ninguna parte, se registra a sí mismo. |
| 4 | Envía al usuario a iniciar sesión y aprobar el acceso, nombrando a tu servidor MCP como el recurso para el que quiere un token. |
| 5 | Vuelve a llamar a tu servidor con el token bearer resultante, que está acotado a tu servidor y a ese usuario. |
Nada de esa secuencia es específico de Authagonal: es la especificación de autorización de MCP, construida sobre RFC 9728 para los metadatos del recurso, RFC 8414 para descubrir el servidor de autorización, RFC 7591 para el registro y RFC 8707 para nombrar el recurso. Un conector que sigue la especificación funciona sin tratarnos como un caso especial.
Deja que los conectores se registren solos
Un conector que nunca has visto no puede usar un cliente que hayas creado a mano, así que registra uno en tiempo de ejecución. Eso está desactivado por defecto. Activa el registro dinámico de clientes en Configuración y el endpoint de registro aparecerá en tu documento de descubrimiento; déjalo desactivado y el endpoint no se anuncia y rechaza las solicitudes. Activarlo abre el registro solo para tu inquilino, nunca para el de nadie más.
| Protección | Qué ocurre |
|---|---|
| Tipos de concesión | Solo se pueden registrar los flujos authorization code y refresh. El autorregistro no puede crear un cliente de máquina a máquina que evitaría por completo a un usuario. |
| PKCE | Se impone a todo cliente registrado, sea lo que sea lo que haya pedido el registro. |
| Consentimiento | También se impone. Un conector registrado no puede obtener un token hasta que una persona haya visto qué está pidiendo y lo haya aprobado. |
| Ámbitos | Los ámbitos integrados de OIDC están siempre disponibles. Cualquier ámbito propio tiene que figurar en la lista de permitidos antes de que un cliente que se registra solo pueda pedirlo. |
| Límite de tasa | Diez registros por dirección IP y hora, para que un endpoint abierto no pueda usarse para llenar tu almacén de clientes. |
Se sirven ambas rutas de descubrimiento
/.well-known/oauth-authorization-server (RFC 8414), mientras que los clientes OIDC usan /.well-known/openid-configuration. Tu inquilino responde en ambas con los mismos metadatos, de modo que un conector que sigue la especificación MCP te encuentra sin que haya que decirle dónde buscar.Qué implementa tu servidor MCP
Dos cosas pequeñas, y a partir de ahí es un servidor de recursos corriente. Primero, publica metadatos de recurso protegido que nombren a tu inquilino como servidor de autorización. Sírvelos en la ruta well-known y, si tu endpoint MCP está en una subruta, también en la forma con el sufijo de ruta, ya que los clientes prueban ambas.
GET https://your-app.example/.well-known/oauth-protected-resource
{
"resource": "https://your-app.example/mcp",
"authorization_servers": ["https://acme.authagonal.io"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["mcp"]
}Segundo, cuando llegue una llamada sin un token válido, responde 401 con un encabezado WWW-Authenticate que apunte a esos metadatos. Ese encabezado es lo que convierte un rechazo en una conexión: sin él el cliente no tiene forma de descubrir dónde autenticarse, y simplemente falla.
// Validate the connector's token like any other resource server.
builder.Services.AddAuthentication().AddJwtBearer("McpBearer", o =>
{
o.Authority = "https://acme.authagonal.io"; // your tenant
o.TokenValidationParameters.ValidAudience = "https://your-app.example/mcp";
});
// Unauthenticated? Point the connector at the metadata rather than just refusing.
http.Response.Headers.WWWAuthenticate =
"Bearer resource_metadata=\"https://your-app.example/.well-known/oauth-protected-resource\"";
return Results.Unauthorized();Comprueba la audiencia, no solo la firma
Ámbitos, planes y revocación
Define un ámbito para tu superficie MCP, añádelo a los ámbitos de registro permitidos y aparecerá en la pantalla de consentimiento para que el usuario vea qué está aprobando. El token lleva los roles del usuario y los claims que hayas configurado, de modo que tu servidor puede decidir qué puede hacer esta persona concreta en lugar de tratar a todos los conectores por igual.
Como es una concesión de OAuth corriente, la revocación funciona de la forma corriente: busca al usuario, revoca sus sesiones o la concesión, y el conector deja de funcionar de inmediato en lugar de al expirar el siguiente token. El registro de auditoría deja constancia del registro, del consentimiento y de la emisión, así que puedes ver qué asistente pidió qué y cuándo.
| Ajuste | Qué ocurre |
|---|---|
Dynamic client registration | Ajuste del portal que permite a los conectores registrarse solos. Desactivado por defecto. |
Auth:DynamicClientRegistrationScopes | Ámbitos más allá de los integrados de OIDC que puede solicitar un cliente que se registra solo. |
resource | El parámetro que envía un conector para nombrar a tu servidor MCP, lo que reduce la audiencia del token a él. |
Crea una interfaz de inicio de sesión personalizada
Reemplaza las pantallas alojadas de inicio de sesión, registro, restablecimiento de contraseña y MFA de Authagonal por tu propia interfaz, mientras Authagonal sigue encargándose de la autenticación, MFA, SSO, sesiones y emisión de tokens. Dos vías: usar nuestra biblioteca de componentes de React, o llamar a la API de autenticación directamente desde cualquier framework. Es opcional — primero habilita Custom login UI en la configuración del inquilino.


Requisito previo: un dominio personalizado en tu raíz
La sesión de inicio de sesión es una cookie de origen propio (first-party), por lo que tu interfaz y el servidor de autenticación de Authagonal deben compartir un dominio registrable. Apunta un dominio de autenticación personalizado a Authagonal en la misma raíz donde se ejecuta tu app — p. ej. autenticación en login.acme.com, app en app.acme.com. La configuración Custom login UI permanece deshabilitada hasta que exista un dominio personalizado activo.
| Tu interfaz | Host de autenticación | ¿Funciona? |
|---|---|---|
| app.acme.com | login.acme.com | ✅ misma raíz |
| acme.com | auth.acme.com | ✅ misma raíz |
| app.acme.com | acme.authagonal.io | ❌ entre sitios |
| myapp.io | login.acme.com | ❌ entre sitios |
Por qué se requiere un dominio personalizado
Agrega también el origen de tu interfaz (p. ej. https://app.acme.com) a los Allowed CORS origins de tu cliente OAuth — la misma lista que configuras para el intercambio de tokens.
React: @authagonal/login
npm i @authagonal/login incluye la lógica de autenticación y la interfaz en un solo paquete — el mismo sobre el que está construido el inicio de sesión alojado de Authagonal. Elige tu nivel:
- App completa — incorpora
Appy aplícale tu tema mediante la marca. - Componer páginas — usa
LoginPage,MfaChallengePage,ResetPasswordPage… dentro de tu propio diseño. - Primitivas + lógica — crea tus propias pantallas con
AuthLayout/Button/Inputy el cliente de la API (login,mfaVerify,forgotPassword, …).
import { AuthLayout, Input, Button, login, ApiRequestError } from '@authagonal/login';
function MyLogin() {
async function onSubmit(email: string, password: string) {
try {
const res = await login({ email, password }); // POST /login (sets the session cookie)
if (res.mfaRequired) {/* render your MFA step → mfaVerify(...) */}
else window.location.href = res.returnUrl; // hand off to /connect/authorize
} catch (e) {
if (e instanceof ApiRequestError) {/* show e.message */}
}
}
return <AuthLayout>{/* your own markup + <Input/> <Button/> */}</AuthLayout>;
}Cualquier framework: llama a la API de autenticación
¿No usas React? Llama directamente a los endpoints del flujo de autenticación (bajo /api/auth) y luego entrega al flujo OIDC estándar /connect/authorize. Envía credentials: 'include' para que se almacene la cookie de sesión.
| Endpoint | Propósito |
|---|---|
POST /api/auth/login | Autenticar; devuelve mfaRequired o una URL de retorno |
POST /api/auth/register | Registro de autoservicio (cuando está habilitado) |
POST /api/auth/forgot-password | Iniciar un restablecimiento de contraseña |
POST /api/auth/reset-password | Completar un restablecimiento de contraseña |
GET /api/auth/password-policy | Política de contraseñas (para mostrar las reglas) |
POST /api/auth/mfa/* | Configuración y verificación de MFA (TOTP, WebAuthn, recuperación) |
Usa credentials: 'include'
# 1. Authenticate (browser fetch — credentials:'include' so the session cookie is stored)
curl -i -X POST https://login.acme.com/api/auth/login \
-H "Content-Type: application/json" \
-H "Origin: https://app.acme.com" \
--data '{"email":"[email protected]","password":"..."}'
# (handle {"mfaRequired":true} → POST /api/auth/mfa/verify, then continue)
# 2. Hand off to the OAuth flow — top-level navigation to the authorize endpoint with PKCE:
# https://login.acme.com/connect/authorize?client_id=my-app&redirect_uri=...&response_type=code
# &scope=openid%20profile%20email&code_challenge=...&code_challenge_method=S256
# The session cookie (same-site) authenticates the user; you get back a code → exchange at /connect/token.Planes y límites
Authagonal ofrece cuatro niveles de plan. Todos los planes incluyen todas las funcionalidades — la única diferencia es el límite de Usuarios Activos Mensuales (MAU) y el precio de excedentes.
Niveles de plan
| Plan | Límite MAU | Excedente | Costo de excedente/usuario |
|---|---|---|---|
| Starter | 1,000 | No | — |
| Pro | 5.000 | Sí | $0,04/usuario |
| Scale | 25.000 | Sí | $0,025/usuario |
| Enterprise | 100.000 | Sí | $0,015/usuario |
Usuarios Activos Mensuales (MAU)
Un Usuario Activo Mensual es cualquier usuario único que se autentica exitosamente al menos una vez durante un mes de facturación. Los usuarios aprovisionados a través de SCIM pero que no han iniciado sesión no cuentan para tu total de MAU.
Excedentes — Si tu plan admite excedentes, los usuarios más allá del límite de MAU se facturan a la tarifa por usuario mostrada en la tabla de planes anterior. Puedes establecer un tope de excedente para limitar tu gasto máximo durante el período de facturación.
Aplicación — Si tu plan no admite excedentes (Starter), los usuarios más allá del límite de MAU no pueden iniciar sesión hasta el próximo período de facturación o hasta que actualices a un plan que admita excedentes.
Conjunto completo de funcionalidades en todos los planes