Skip to Content

Webhooks-API

Webhooks ermöglichen es deiner Anwendung, Echtzeit-HTTP-Callbacks zu empfangen, wenn Ereignisse in Auris auftreten. Wenn ein abonniertes Ereignis ausgelöst wird (z.B. ein Benutzer meldet sich an, eine Rolle wird zugewiesen, ein Konto wird gesperrt), sendet Auris eine POST-Anforderung an deine konfigurierte URL mit einem JSON-Payload, der das Ereignis beschreibt.

Jede Webhook-Zustellung wird mit HMAC-SHA256 unter Verwendung eines pro-Webhook-Signing-Secrets signiert. Dies ermöglicht es deinem Server zu verifizieren, dass der Payload von Auris stammt und während der Übertragung nicht manipuliert wurde.

Alle Webhook-Verwaltungsendpunkte erfordern die manage:webhooks-Berechtigung und den x-tenant-Header.

Webhook-CRUD

Webhooks auflisten

GET/api/webhooksRequires: manage:webhooks

Alle für den Tenant konfigurierten Webhook-Endpunkte auflisten. Gibt Webhook-Metadaten zurück, einschließlich der abonnierten Ereignisse, des aktiven Status und der Fehlerstatistiken. Das Signing-Secret wird in Listenantworten nie zurückgegeben.

Abfrageparameter

ParameterTypBeschreibung
pageintegerSeitennummer (Standard: 1)
limitintegerElemente pro Seite (Standard: 20)

Erfolgsantwort

{ "ok": true, "data": { "data": [ { "id": "whk_abc123", "name": "Produktions-Ereignishandler", "url": "https://api.ihreapp.de/webhooks/auris", "events": ["user.created", "user.updated", "login.success", "login.failed"], "isActive": true, "lastDeliveryAt": "2025-02-18T09:45:00Z", "failureCount": 0, "createdAt": "2025-01-15T10:00:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 3, "totalPages": 1 } } }

Webhook erstellen

POST/api/webhooksRequires: manage:webhooks

Einen neuen Webhook-Endpunkt erstellen. Ein Signing-Secret wird automatisch mit dem Präfix whsec_ generiert. Das Secret wird nur in der Erstellungsantwort zurückgegeben — speichere es sicher, da es später nicht abgerufen werden kann (nur rotiert).

Anforderungs-Body

{ "name": "Produktions-Ereignishandler", "url": "https://api.ihreapp.de/webhooks/auris", "events": ["user.created", "user.updated", "user.deleted", "login.success"] }
FeldTypErforderlichBeschreibung
namestringJaMenschenlesbarer Name für diesen Webhook
urlstringJaHTTPS-Endpunkt-URL, die POST-Anforderungen empfängt
eventsstring[]JaArray von Ereignistypen, die abonniert werden sollen (siehe Ereignistypen)

Webhook-URLs müssen HTTPS verwenden. HTTP-URLs werden abgelehnt, um zu verhindern, dass Secrets und Benutzerdaten im Klartext übertragen werden.

Erfolgsantwort

{ "ok": true, "data": { "id": "whk_def456", "name": "Produktions-Ereignishandler", "url": "https://api.ihreapp.de/webhooks/auris", "events": ["user.created", "user.updated", "user.deleted", "login.success"], "secret": "whsec_7f3a8b2c4d5e6f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f", "isActive": true, "createdAt": "2025-02-18T10:00:00Z" } }

Das secret-Feld wird nur in der Erstellungsantwort und nach der Secret-Rotation zurückgegeben. Kopiere und speichere es sofort an einem sicheren Ort (z.B. Umgebungsvariable oder Secrets-Manager). Es kann nicht erneut abgerufen werden.

Fehlercodes

CodeHTTPBeschreibung
VALIDATION_ERROR400Fehlende Pflichtfelder oder ungültige Ereignistypen
INVALID_URL400URL ist kein gültiger HTTPS-Endpunkt
INVALID_EVENTS400Eine oder mehrere Ereignistyp-Zeichenketten werden nicht erkannt

Webhook abrufen

GET/api/webhooks/[id]Requires: manage:webhooks

Einen einzelnen Webhook anhand seiner ID abrufen. Gibt vollständige Webhook-Details ohne das Signing-Secret zurück.

Erfolgsantwort

{ "ok": true, "data": { "id": "whk_abc123", "name": "Produktions-Ereignishandler", "url": "https://api.ihreapp.de/webhooks/auris", "events": ["user.created", "user.updated", "login.success", "login.failed"], "isActive": true, "failureCount": 0, "lastDeliveryAt": "2025-02-18T09:45:00Z", "createdAt": "2025-01-15T10:00:00Z", "updatedAt": "2025-02-10T14:00:00Z" } }

Webhook aktualisieren

PATCH/api/webhooks/[id]Requires: manage:webhooks

Den Namen, die URL, die abonnierten Ereignisse oder den aktiven Status eines Webhooks aktualisieren. Alle Felder sind optional — nur bereitgestellte Felder werden aktualisiert.

Anforderungs-Body

{ "name": "Produktions-Ereignishandler v2", "events": ["user.created", "user.updated", "user.deleted", "login.success", "login.failed", "role.assigned"], "isActive": true }

Erfolgsantwort

{ "ok": true, "data": { "id": "whk_abc123", "name": "Produktions-Ereignishandler v2", "url": "https://api.ihreapp.de/webhooks/auris", "events": ["user.created", "user.updated", "user.deleted", "login.success", "login.failed", "role.assigned"], "isActive": true, "updatedAt": "2025-02-18T11:00:00Z" } }

Webhook löschen

DELETE/api/webhooks/[id]Requires: manage:webhooks

Einen Webhook-Endpunkt löschen. Ausstehende Zustellungen für diesen Webhook werden abgebrochen. Der Zustellungsverlauf wird für Audit-Zwecke aufbewahrt.

Erfolgsantwort

{ "ok": true, "data": { "deleted": true } }

Secret-Rotation

POST/api/webhooks/[id]/rotate-secretRequires: manage:webhooks

Ein neues Signing-Secret für den Webhook generieren. Das alte Secret wird sofort ungültig. Das neue Secret wird in der Antwort zurückgegeben. Alle nachfolgenden Zustellungen werden mit dem neuen Secret signiert.

Anforderung: Kein Body erforderlich.

Erfolgsantwort

{ "ok": true, "data": { "secret": "whsec_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a" } }

Aktualisiere nach der Rotation eines Secrets deinen Webhook-Handler sofort, um das neue Secret zu verwenden. Zustellungen, die zum Zeitpunkt der Rotation unterwegs sind, können noch das alte Secret verwenden. Best Practice: Unterstütze die Verifizierung gegen beide Secrets (alt und neu) für eine kurze Übergangsperiode während der Rotation.

Testen

POST/api/webhooks/[id]/testRequires: manage:webhooks

Eine Testzustellung an die Webhook-URL senden. Auris sendet ein webhook.test-Ereignis mit einem Beispiel-Payload. Die Zustellung wird im Zustellungsprotokoll aufgezeichnet. Verwende dies, um zu überprüfen, ob dein Endpunkt erreichbar ist und Signaturen korrekt verifiziert.

Anforderung: Kein Body erforderlich.

Erfolgsantwort

{ "ok": true, "data": { "deliveryId": "del_xyz789", "statusCode": 200, "success": true, "responseTime": 142 } }

Test-Ereignis-Payload (was dein Endpunkt empfängt)

{ "event": "webhook.test", "timestamp": "2025-02-18T10:30:00Z", "tenant": "acme-gmbh", "data": { "message": "Dies ist eine Testzustellung von Auris.", "webhookId": "whk_abc123" } }

Fehlercodes

CodeHTTPBeschreibung
DELIVERY_FAILED502Der Webhook-Endpunkt gab einen Nicht-2xx-Statuscode zurück
ENDPOINT_UNREACHABLE502Verbindung zur Webhook-URL konnte nicht hergestellt werden (DNS-Fehler, Timeout, etc.)

Zustellungsprotokoll

Zustellungen auflisten

GET/api/webhooks/[id]/deliveriesRequires: manage:webhooks

Zustellversuche für einen Webhook auflisten, nach Zeitstempel absteigend geordnet. Jede Zustellung enthält den Ereignistyp, den HTTP-Statuscode, die Antwortzeit und ob die Zustellung erfolgreich war. Wiederholte Zustellungen sind separate Einträge, die mit demselben Ereignis verknüpft sind.

Abfrageparameter

ParameterTypBeschreibung
pageintegerSeitennummer (Standard: 1)
limitintegerElemente pro Seite (Standard: 20)

Erfolgsantwort

{ "ok": true, "data": { "data": [ { "id": "del_abc123", "event": "user.created", "statusCode": 200, "success": true, "responseTime": 89, "attempts": 1, "payload": { "event": "user.created", "timestamp": "2025-02-18T09:45:00Z", "tenant": "acme-gmbh", "data": { "userId": "usr_abc123", "email": "[email protected]" } }, "createdAt": "2025-02-18T09:45:00Z", "completedAt": "2025-02-18T09:45:01Z" }, { "id": "del_def456", "event": "login.failed", "statusCode": 500, "success": false, "responseTime": 2034, "attempts": 3, "error": "Server returned 500 Internal Server Error", "payload": { "event": "login.failed", "timestamp": "2025-02-18T09:30:00Z", "tenant": "acme-gmbh", "data": { "email": "[email protected]", "reason": "INVALID_CREDENTIALS", "ipAddress": "203.0.113.50" } }, "createdAt": "2025-02-18T09:30:00Z", "completedAt": "2025-02-18T09:35:12Z" } ], "pagination": { "page": 1, "limit": 20, "total": 156, "totalPages": 8 } } }

Zustellung wiederholen

POST/api/webhooks/[id]/deliveries/[deliveryId]/retryRequires: manage:webhooks

Eine fehlgeschlagene Zustellung manuell wiederholen. Der ursprüngliche Payload wird mit einer neuen Signatur erneut gesendet. Erstellt einen neuen Zustellungseintrag, der mit demselben Ereignis verknüpft ist.

Anforderung: Kein Body erforderlich.

Erfolgsantwort

{ "ok": true, "data": { "deliveryId": "del_ghi789", "statusCode": 200, "success": true, "responseTime": 95 } }

Fehlercodes

CodeHTTPBeschreibung
NOT_FOUND404Zustellung existiert nicht
ALREADY_SUCCESSFUL400Die Zustellung war bereits erfolgreich und muss nicht wiederholt werden

Ereignistypen

Auris sendet folgende Webhook-Ereignisse. Abonniere die für deinen Anwendungsfall relevanten Ereignisse.

Authentifizierungsereignisse

EreignisBeschreibung
login.successBenutzer hat sich erfolgreich authentifiziert (jede Methode)
login.failedAuthentifizierungsversuch fehlgeschlagen (falsche Anmeldedaten, gesperrtes Konto, etc.)
signup.completedNeues Benutzerkonto registriert
logout.completedBenutzer abgemeldet (Sitzung ungültig gemacht)
token.refreshedZugriffs-Token wurde erneuert
password.changedBenutzer hat sein Passwort geändert
password.reset_requestedPasswort-Reset-E-Mail wurde gesendet
magic_link.sentMagic-Link-E-Mail wurde gesendet
magic_link.verifiedMagic Link wurde zur Authentifizierung verwendet

Benutzerverwaltungsereignisse

EreignisBeschreibung
user.createdNeues Benutzerkonto erstellt (über Admin-API oder Registrierung)
user.updatedBenutzerprofilfelder wurden geändert
user.deletedBenutzerkonto wurde soft-gelöscht
user.enabledZuvor deaktivierter Benutzer wurde wieder aktiviert
user.disabledBenutzerkonto wurde deaktiviert
user.email_verifiedBenutzer hat seine E-Mail-Adresse verifiziert

Rollen- und Berechtigungsereignisse

EreignisBeschreibung
role.createdNeue Rolle erstellt
role.updatedRollenmetadaten oder -berechtigungen geändert
role.deletedRolle gelöscht
role.assignedRolle einem Benutzer zugewiesen
role.unassignedRolle von einem Benutzer entfernt

Sicherheitsereignisse

EreignisBeschreibung
mfa.enabledBenutzer hat eine 2FA-Methode aktiviert (TOTP, SMS oder WebAuthn)
mfa.disabledBenutzer hat eine 2FA-Methode deaktiviert
account.lockedKonto wurde aufgrund von Brute-Force-Erkennung gesperrt
account.unlockedKontosperre wurde aufgehoben
suspicious_login.detectedVerdächtige Anmeldeaktivität erkannt (neues Gerät, unmögliche Reise, etc.)

Organisationsereignisse

EreignisBeschreibung
organization.createdNeue Organisation erstellt
organization.updatedOrganisationsmetadaten geändert
organization.member_addedBenutzer zu einer Organisation hinzugefügt
organization.member_removedBenutzer aus einer Organisation entfernt
organization.invitation_sentEinladungs-E-Mail gesendet

Systemereignisse

EreignisBeschreibung
webhook.testTestzustellung über die Konsole oder API ausgelöst

Webhook-Payload-Format

Jede Webhook-Zustellung sendet eine POST-Anforderung mit einem JSON-Body:

{ "event": "user.created", "timestamp": "2025-02-18T10:00:00Z", "tenant": "acme-gmbh", "data": { "userId": "usr_abc123", "email": "[email protected]", "firstName": "Alice", "lastName": "Müller" } }
FeldTypBeschreibung
eventstringDer Ereignistyp (z.B. user.created)
timestampstringISO 8601-Zeitstempel des Ereignisses
tenantstringTenant-Bezeichner, in dem das Ereignis aufgetreten ist
dataobjectEreignisspezifische Payload-Daten

Die Form von data variiert je nach Ereignistyp. Benutzerereignisse enthalten Benutzerfelder, Rollenereignisse enthalten Rollendetails und Anmeldeereignisse enthalten die E-Mail und IP-Adresse.

Signaturverifizierung

Jede Zustellung enthält zwei Header für die Signaturverifizierung:

HeaderBeschreibung
X-Webhook-SignatureHMAC-SHA256-Signatur des Anforderungs-Bodys
X-Webhook-TimestampUnix-Zeitstempel (Sekunden), wann die Signatur generiert wurde

Verifizierungsalgorithmus

  1. Lies den rohen Anforderungs-Body als UTF-8-Zeichenkette (nicht zuerst als JSON parsen).
  2. Lies den X-Webhook-Timestamp-Header.
  3. Verketten: timestamp + "." + body
  4. Berechne HMAC-SHA256 der verketteten Zeichenkette mit dem Signing-Secret deines Webhooks.
  5. Vergleiche das hexadezimal kodierte Ergebnis mit dem X-Webhook-Signature-Header mit einem zeitkonstanten Vergleich.
  6. Optional: Zustellungen ablehnen, bei denen der Zeitstempel mehr als 5 Minuten alt ist (zum Schutz vor Replay-Angriffen).

Node.js-Verifizierungsbeispiel

import crypto from 'crypto'; function verifyWebhookSignature(rawBody, signature, timestamp, secret) { // 1. Zeitstempel-Aktualität prüfen (optional, aber empfohlen) const currentTime = Math.floor(Date.now() / 1000); if (Math.abs(currentTime - parseInt(timestamp)) > 300) { throw new Error('Webhook-Zeitstempel ist zu alt'); } // 2. Erwartete Signatur berechnen const signedPayload = `${timestamp}.${rawBody}`; const expectedSignature = crypto .createHmac('sha256', secret) .update(signedPayload) .digest('hex'); // 3. Zeitkonstanter Vergleich const expected = Buffer.from(expectedSignature, 'hex'); const received = Buffer.from(signature, 'hex'); if (expected.length !== received.length) { return false; } return crypto.timingSafeEqual(expected, received); } // Express.js-Handler app.post('/webhooks/auris', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-webhook-signature']; const timestamp = req.headers['x-webhook-timestamp']; const rawBody = req.body.toString('utf-8'); if (!verifyWebhookSignature(rawBody, signature, timestamp, process.env.AURIS_WEBHOOK_SECRET)) { return res.status(401).json({ error: 'Ungültige Signatur' }); } const event = JSON.parse(rawBody); console.log(`Received ${event.event}:`, event.data); // Ereignis verarbeiten... res.status(200).json({ received: true }); });

Python-Verifizierungsbeispiel

import hmac import hashlib import time def verify_webhook_signature(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool: # Zeitstempel-Aktualität prüfen current_time = int(time.time()) if abs(current_time - int(timestamp)) > 300: return False # Erwartete Signatur berechnen signed_payload = f"{timestamp}.{raw_body.decode('utf-8')}" expected = hmac.new( secret.encode('utf-8'), signed_payload.encode('utf-8'), hashlib.sha256 ).hexdigest() # Zeitkonstanter Vergleich return hmac.compare_digest(expected, signature)

Das @auris/js-SDK enthält ein integriertes Webhook-Verifizierungsdienstprogramm: import { verifyWebhookSignature } from '@auris/js'. Es handhabt Zeitstempel-Validierung, HMAC-Berechnung und zeitkonstanten Vergleich. Weitere Details in der SDK-Dokumentation.

Zustellungsverhalten

Timeouts

Auris wartet bis zu 30 Sekunden auf eine Antwort von deinem Webhook-Endpunkt. Wenn dein Endpunkt innerhalb dieses Zeitfensters nicht antwortet, wird die Zustellung als fehlgeschlagen markiert.

Wiederholungsrichtlinie

Fehlgeschlagene Zustellungen werden mit exponentiellem Backoff wiederholt:

VersuchVerzögerung
1. Wiederholung1 Minute
2. Wiederholung5 Minuten
3. Wiederholung30 Minuten

Nach 3 fehlgeschlagenen Wiederholungsversuchen wird die Zustellung als dauerhaft fehlgeschlagen markiert. Sie kann weiterhin manuell über die API oder Konsole wiederholt werden.

Automatische Deaktivierung

Wenn ein Webhook 10 aufeinanderfolgende Fehler akkumuliert (über alle Zustellungen), wird er automatisch deaktiviert (isActive: false). Du musst den Endpunkt reparieren und den Webhook manuell über PATCH /api/webhooks/[id] mit { "isActive": true } wieder aktivieren.

Idempotenz

Dein Webhook-Handler sollte idempotent sein. In seltenen Fällen (Netzwerkprobleme, Wiederholungen) kann dasselbe Ereignis mehr als einmal zugestellt werden. Verwende die Felder timestamp und event, um bei Bedarf zu deduplizieren.

Best Practices

  1. Schnell antworten: Gib so schnell wie möglich einen 2xx-Statuscode zurück. Verarbeite das Ereignis asynchron (z.B. in einer Queue), anstatt schwere Arbeit im Anforderungshandler zu erledigen.
  2. Signaturen verifizieren: Verifiziere immer die HMAC-SHA256-Signatur, bevor du den Payload verarbeitest. Vertraue niemals einem Webhook-Payload ohne Verifizierung.
  3. HTTPS verwenden: Auris lehnt Nicht-HTTPS-Webhook-URLs ab. Verwende ein gültiges TLS-Zertifikat.
  4. Wiederholungen handhaben: Gestalte deinen Handler idempotent. Dasselbe Ereignis kann mehr als einmal zugestellt werden.
  5. Secrets regelmäßig rotieren: Verwende den Rotate-Secret-Endpunkt, um regelmäßig ein neues Signing-Secret zu generieren (z.B. vierteljährlich).
  6. Zustellungen überwachen: Prüfe das Zustellungsprotokoll in der Konsole oder über die API, um sicherzustellen, dass dein Endpunkt gesund ist.

Zugehörige Referenzen