Skip to Content

Configurar Webhooks

Los webhooks permiten que tu aplicación reciba notificaciones HTTP en tiempo real cuando ocurren eventos en Auris, como el registro de un usuario, un fallo de inicio de sesión, la asignación de un rol o la creación de una organización. En lugar de consultar la API periódicamente para detectar cambios, Auris envía los payloads de eventos a tu endpoint en el momento en que suceden.

Esta guía te muestra cómo crear un receptor de webhooks, registrarlo en la Consola de Auris, verificar firmas por seguridad y gestionar fallos de forma adecuada.

Por Qué Usar Webhooks

Sin webhooks, tu aplicación tendría que consultar las APIs de Auris repetidamente para detectar cambios. Esto es ineficiente, introduce latencia (solo detectas los cambios en el siguiente ciclo de consulta) y desperdicia recursos en ambos lados. Los webhooks invierten este modelo: Auris notifica a tu aplicación de inmediato cuando ocurre algo.

Casos de uso habituales:

  • Sincronizar datos de usuario en tu base de datos cuando se crea o actualiza un usuario
  • Activar flujos de incorporación cuando se registra un nuevo usuario
  • Revocar acceso en tu sistema cuando un usuario es deshabilitado o eliminado
  • Auditoría transmitiendo eventos a tu SIEM
  • Notificaciones en Slack/Teams cuando se detecta actividad de inicio de sesión sospechosa

Paso 1: Crear un Endpoint Webhook en Tu Aplicación

Tu endpoint webhook es un manejador HTTP POST estándar que recibe payloads JSON de Auris. A continuación se muestra un ejemplo completo con Express.js y verificación de firma:

import express from 'express' import crypto from 'crypto' const app = express() // IMPORTANTE: Usar el cuerpo sin procesar para la verificación de firma app.post( '/webhooks/auris', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-webhook-signature'] as string const timestamp = req.headers['x-webhook-timestamp'] as string const secret = process.env.AURIS_WEBHOOK_SECRET! // ej. whsec_abc123... // 1. Verificar la firma if (!verifyWebhookSignature(req.body, signature, timestamp, secret)) { console.error('Verificación de firma del webhook fallida') return res.status(401).json({ error: 'Firma inválida' }) } // 2. Parsear el evento const event = JSON.parse(req.body.toString()) console.log(`Evento recibido: ${event.type}`, event.data) // 3. Responder 200 inmediatamente — procesar de forma asíncrona res.status(200).json({ received: true }) // 4. Manejar el evento de forma asíncrona handleWebhookEvent(event).catch((err) => console.error('Error en el manejador de webhook:', err) ) } ) function verifyWebhookSignature( body: Buffer, signature: string, timestamp: string, secret: string ): boolean { // Rechazar si el timestamp tiene más de 5 minutos (protección contra repetición) const eventTime = parseInt(timestamp, 10) const now = Math.floor(Date.now() / 1000) if (Math.abs(now - eventTime) > 300) { return false } // Calcular la firma esperada: HMAC-SHA256(timestamp.body) const payload = `${timestamp}.${body.toString()}` const expected = crypto .createHmac('sha256', secret) .update(payload) .digest('hex') // Comparación en tiempo constante para prevenir ataques de temporización try { return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ) } catch { return false } } async function handleWebhookEvent(event: { type: string data: Record<string, unknown> }) { switch (event.type) { case 'user.created': // Sincronizar usuario en la base de datos local await syncUser(event.data) break case 'user.deleted': // Eliminar datos del usuario del sistema await removeUser(event.data) break case 'login.suspicious': // Alertar al equipo de seguridad await notifySecurityTeam(event.data) break default: console.log(`Tipo de evento no gestionado: ${event.type}`) } } app.listen(3000, () => console.log('Servidor de webhooks ejecutándose en el puerto 3000'))

Utiliza siempre el cuerpo de la solicitud sin procesar (no el objeto JSON parseado) al calcular la firma HMAC. Parsear y volver a serializar el JSON puede cambiar los espacios en blanco o el orden de las claves, lo que invalidaría la firma.

Paso 2: Registrar el Webhook en la Consola de Auris

  1. Abre la Consola de Auris y navega a Configuración y luego a Webhooks
  2. Haz clic en Crear Webhook
  3. Introduce la URL de tu endpoint (ej. https://api.yourapp.com/webhooks/auris)
  4. Selecciona los eventos que deseas recibir (o elige “Todos los eventos”)
  5. Haz clic en Crear

Auris genera un secreto de firma con el prefijo whsec_ (ej. whsec_k7Gm2x9pQ...). Copia este valor de inmediato y guárdalo de forma segura en tus variables de entorno. El secreto completo solo se muestra una vez.

También puedes registrar webhooks a través de la API:

curl -X POST https://auth.yourdomain.com/api/webhooks \ -H "Authorization: Bearer $AURIS_ACCESS_TOKEN" \ -H "x-tenant: your-tenant-id" \ -H "Content-Type: application/json" \ -d '{ "name": "Webhook de producción", "url": "https://api.yourapp.com/webhooks/auris", "events": ["user.created", "user.updated", "user.deleted", "login.failed"], "isActive": true }'

Respuesta:

{ "ok": true, "data": { "id": "whk_abc123", "name": "Webhook de producción", "url": "https://api.yourapp.com/webhooks/auris", "events": ["user.created", "user.updated", "user.deleted", "login.failed"], "signingSecret": "whsec_k7Gm2x9pQzR4vL8...", "isActive": true, "createdAt": "2026-01-15T10:00:00Z" } }

Paso 3: Verificar Firmas de Webhook

Cada entrega de webhook de Auris incluye dos cabeceras para la verificación:

CabeceraDescripción
X-Webhook-SignatureResumen hexadecimal HMAC-SHA256 del payload
X-Webhook-TimestampTimestamp Unix (segundos) en que se envió el evento

La firma se calcula como:

HMAC-SHA256(whsec_secret, "${timestamp}.${rawBody}")

Algoritmo de Verificación

  1. Extraer las cabeceras X-Webhook-Signature y X-Webhook-Timestamp de la solicitud
  2. Comprobar que el timestamp está dentro de los 5 minutos del tiempo actual (protección contra repetición)
  3. Concatenar el timestamp, un punto literal (.) y el cuerpo de la solicitud sin procesar
  4. Calcular el HMAC-SHA256 de esa cadena usando tu secreto de firma whsec_
  5. Comparar la firma calculada con la firma recibida usando una función de comparación en tiempo constante

A continuación se muestra una función de verificación independiente en TypeScript:

import crypto from 'crypto' export function verifyAurisWebhook( rawBody: string | Buffer, signature: string, timestamp: string, secret: string ): boolean { // Paso 1: Protección contra repetición — rechazar eventos con más de 5 minutos de antigüedad const ts = parseInt(timestamp, 10) if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > 300) { return false } // Paso 2: Calcular la firma esperada const body = typeof rawBody === 'string' ? rawBody : rawBody.toString('utf-8') const payload = `${timestamp}.${body}` const expected = crypto .createHmac('sha256', secret) .update(payload) .digest('hex') // Paso 3: Comparación en tiempo constante try { return crypto.timingSafeEqual( Buffer.from(signature, 'utf-8'), Buffer.from(expected, 'utf-8') ) } catch { return false } }

Usar el SDK de Auris para la Verificación

Si utilizas @auris/js, el SDK incluye una utilidad integrada de verificación de webhooks:

import { verifyWebhookSignature } from '@auris/js/webhooks' const isValid = await verifyWebhookSignature({ payload: rawBody, signature: req.headers['x-webhook-signature'], timestamp: req.headers['x-webhook-timestamp'], secret: process.env.AURIS_WEBHOOK_SECRET!, })

Nunca omitas la verificación de firma en producción. Sin ella, cualquier atacante que descubra la URL de tu endpoint puede enviar eventos falsificados a tu aplicación.

Catálogo de Eventos

Auris envía eventos organizados en las siguientes categorías. Cada payload de evento incluye un campo type (ej. user.created) y un objeto data con el recurso correspondiente.

Eventos de Usuario

EventoSe activa cuando
user.createdSe registra un nuevo usuario (registro, creación por administrador, aprovisionamiento SCIM o SSO JIT)
user.updatedSe modifican campos del perfil del usuario
user.deletedUn usuario es eliminado de forma suave
user.email_verifiedUn usuario verifica su dirección de correo electrónico
user.password_changedUn usuario cambia su contraseña
user.blockedUna cuenta de usuario es deshabilitada
user.unblockedUna cuenta de usuario es rehabilitada

Eventos de Inicio de Sesión

EventoSe activa cuando
login.succeededUn usuario se autentica correctamente
login.failedUn intento de inicio de sesión falla (credenciales incorrectas, cuenta bloqueada, etc.)
login.mfa_requiredSe activa el paso de MFA durante el inicio de sesión
login.suspiciousUn inicio de sesión es marcado por la detección de actividad sospechosa

Eventos de Roles y Permisos

EventoSe activa cuando
role.createdSe crea un nuevo rol
role.updatedSe modifican el nombre, la descripción o los permisos de un rol
role.deletedSe elimina un rol
role.assignedSe asigna un rol a un usuario
role.unassignedSe elimina un rol de un usuario

Eventos de Organización

EventoSe activa cuando
organization.createdSe crea una nueva organización
organization.updatedSe modifican los detalles de una organización
organization.deletedSe elimina una organización
organization.member_addedUn usuario se une a una organización
organization.member_removedUn usuario es eliminado de una organización
organization.invitation_sentSe envía una invitación
organization.invitation_acceptedSe acepta una invitación

Eventos de Aplicación

EventoSe activa cuando
application.createdSe registra una nueva aplicación
application.updatedSe modifica la configuración de una aplicación
application.secret_rotatedSe rota el secreto de cliente de una aplicación

Ejemplo de Payload

{ "id": "evt_abc123def456", "type": "user.created", "timestamp": "2026-01-15T10:30:00Z", "data": { "id": "usr_xyz789", "email": "[email protected]", "firstName": "Jane", "lastName": "Doe", "emailVerified": false, "roles": [], "createdAt": "2026-01-15T10:30:00Z" } }

Gestión de Fallos y Reintentos

Si tu endpoint devuelve un código de estado distinto a 2xx o no responde en 30 segundos, Auris considera que la entrega ha fallado y reintenta con retroceso exponencial:

IntentoRetraso tras el fallo
1er reintento1 minuto
2º reintento5 minutos
3er reintento30 minutos
4º reintento2 horas
5º reintento12 horas

Tras 5 reintentos fallidos (6 intentos en total), la entrega se marca como fallida permanentemente. Puedes ver las entregas fallidas y reintentarlas manualmente en la Consola en Configuración → Webhooks → selecciona un webhook → Entregas.

Si un endpoint webhook falla de forma continua, Auris deshabilita automáticamente el webhook tras 10 entregas consecutivas fallidas y envía una notificación a los administradores del tenant. Vuelve a habilitarlo desde la Consola tras resolver el problema subyacente.

Probar Webhooks

Botón de Prueba en la Consola

En la Consola de Auris, cada webhook dispone de un botón Probar que envía un evento sintético a tu endpoint. Es la forma más rápida de verificar que tu endpoint es accesible y que la verificación de firma funciona correctamente.

Desarrollo Local con ngrok

Durante el desarrollo, tu servidor local no es accesible públicamente. Usa una herramienta de tunelización como ngrok para exponerlo:

# Iniciar el servidor de webhooks local node server.js # o: npx ts-node server.ts # En otra terminal, iniciar ngrok ngrok http 3000

ngrok proporciona una URL pública como https://a1b2c3d4.ngrok-free.app. Usa esta URL al registrar el webhook en la Consola:

https://a1b2c3d4.ngrok-free.app/webhooks/auris

Tras registrarlo, usa el botón de prueba de la Consola o activa un evento real (ej. crear un usuario) para ver el payload llegar a tu servidor local.

Inspeccionar Entregas

La página de detalle de webhook en la Consola muestra un registro de entregas con:

  • Código de estado HTTP devuelto por tu endpoint
  • Cuerpo de la respuesta (primeros 1 KB)
  • Tiempo de respuesta en milisegundos
  • Número de reintentos realizados
  • Timestamp de cada intento de entrega

Buenas Prácticas

Responde 200 de inmediato. Tu endpoint debe devolver HTTP 200 lo antes posible y luego procesar el evento de forma asíncrona (ej. encolándolo). Si el manejador tarda demasiado, Auris puede agotar el tiempo de espera y reintentar, lo que puede provocar procesamiento duplicado.

Implementa idempotencia. Cada evento incluye un campo id único. Guarda los IDs de los eventos procesados y omite los duplicados. Los reintentos pueden entregar el mismo evento varias veces.

async function handleWebhookEvent(event: { id: string; type: string; data: unknown }) { // Comprobar si ya fue procesado const exists = await db.processedWebhookEvent.findUnique({ where: { eventId: event.id }, }) if (exists) { console.log(`Omitiendo evento duplicado: ${event.id}`) return } // Procesar el evento await processEvent(event) // Marcar como procesado await db.processedWebhookEvent.create({ data: { eventId: event.id, processedAt: new Date() }, }) }

Usa endpoints HTTPS. Auris solo envía payloads de webhook por HTTPS. Los endpoints HTTP son rechazados al registrar el webhook.

Rota los secretos periódicamente. Usa la Consola o la API para rotar tu secreto de firma del webhook. Auris admite la rotación de secretos con un período de gracia en el que se aceptan tanto el secreto antiguo como el nuevo.

curl -X POST https://auth.yourdomain.com/api/webhooks/whk_abc123/rotate-secret \ -H "Authorization: Bearer $AURIS_ACCESS_TOKEN" \ -H "x-tenant: your-tenant-id"

Monitoriza el estado de las entregas. Configura alertas sobre la tasa de errores de tu endpoint. Si observas un pico en las entregas fallidas, revisa los logs de tu servidor y el registro de entregas de la Consola.

Filtra eventos al registrar. Suscríbete solo a los eventos que necesita tu aplicación. Suscribirse a todos los eventos genera tráfico y carga de procesamiento innecesarios.

Guías Relacionadas