Agent skill

OneLogin Webhooks Skill

Receive and authenticate OneLogin Event Broadcaster webhooks. Use when setting up a OneLogin webhook endpoint, checking the secret custom header, debugging 401s, or handling batched events by event_type_id such as user login success (5), login failed (6), logout (7), changed password (11) and added an MFA device (22).

Install this skill

npx skills add hookdeck/webhook-skills --skill onelogin-webhooks


OneLogin's Event Broadcaster POSTs batches of account events to your endpoint in near real time. It sends every event type on the account, so you filter by event_type_id. Requests are not signed: you authenticate them with a secret custom header that you add to the broadcaster in the OneLogin admin portal and compare against your stored copy. The header name is your choice (the docs suggest an arbitrary string as the value).

When to Use This Skill

  • How do I receive OneLogin webhooks / Event Broadcaster events?
  • Does OneLogin sign webhook payloads? (No: use a secret custom header)
  • How do I authenticate a OneLogin webhook request?
  • How do I handle event_type_id 5 (login success), 6 (login failed) or 11 (password changed)?
  • Why does my OneLogin webhook endpoint return 401, or why is OneLogin retrying?

Verification (core)

const crypto = require('crypto');

function safeEqual(a, b) {
  const ba = Buffer.from(String(a)), bb = Buffer.from(String(b));
  return ba.length === bb.length && crypto.timingSafeEqual(ba, bb); // throws on unequal lengths
}

function verifyOneLoginRequest(headers,
    secret = process.env.ONELOGIN_WEBHOOK_SECRET,
    headerName = process.env.ONELOGIN_WEBHOOK_HEADER || 'Authorization') {
  if (!secret) return false;                          // never accept when unconfigured
  const received = headers[headerName.toLowerCase()]; // Node lower-cases header names
  return typeof received === 'string' && received.length > 0 && safeEqual(received, secret);
}
  • There is no signature algorithm. Compare the whole header value, exactly as you typed it in OneLogin, including any Bearer prefix. Do not strip or parse a prefix.
  • Look the header up case-insensitively. Missing header or mismatch: 401.
  • Python: hmac.compare_digest(received.encode(), secret.encode()). Encode both sides to bytes; passing str raises TypeError on non-ASCII.
  • A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS only, keep the value long and random, and rotate it in both OneLogin and your environment if it leaks.
  • Read the body raw (express.raw({ type: '*/*' })) so any content type works, and parse JSON only after the credential check.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Payload and Event Types

Choose the JSON Array format type in the broadcaster configuration, as OneLogin recommends: the body is then a JSON array of event objects, sent as a POST. OneLogin's docs describe no other format, so the examples handle only the JSON array. Iterate every element. Each event has a numeric event_type_id plus fields such as user_id, user_name, app_name, ipaddr, risk_score, event_timestamp and uuid.

event_type_idEvent
5User Login Success
6User Login Failed
7User Logout
8User Logged into an App
11User Changed Password
22User Added an MFA Device

These are the examples OneLogin documents. The complete list comes from the Event Types API; acknowledge unknown IDs with 200.

Responses and Retries

Respond 200 on success. A non-200 or a timeout makes OneLogin send the payload again, for a maximum of 3 attempts, then it is dropped. Make handlers idempotent (use each event's uuid).

Environment Variables

ONELOGIN_WEBHOOK_HEADER=Authorization        # custom header name you configured (default: Authorization)
ONELOGIN_WEBHOOK_SECRET=your-long-random-string  # exact, whole header value

Local Development

OneLogin can't reach localhost. Tunnel with the Hookdeck CLI (no account required):

npx hookdeck-cli listen 3000 onelogin --path /webhooks/onelogin

Use the printed URL as the listener URL in the Event Broadcaster.

Resources


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 3, 2026

View on GitHub →