Skooh.io Logo
Back to blog
IntegrationDeveloper TutorialMay 21, 20258 min

Okta Event Hooks to an Internal Security Service Using Skooh

Forward Okta security events to your SIEM with proper authentication and audit trails.

Overview

Okta Event Hooks notify your systems about security events: logins, MFA challenges, user lifecycle changes, and suspicious activity. These events belong in your SIEM—but your SIEM is internal.

Skooh bridges Okta to your private security service.

Setting Up

1. Create Skooh Endpoint

  1. Create endpoint in Skooh
  2. Copy URL: `https://api.skooh.io/hook/okta-security\`

2. Run the Skooh Proxy

Using the Desktop App:

  1. Download the Skooh Desktop App
  2. Enter your API key and hook token
  3. Set forwarding URL (e.g., `http://localhost:8080/webhooks/okta\`)
  4. Click Connect

Using Docker:

docker run -d \\
  --name skooh-okta \\
  -e SKOOH_TOKEN=okta-security \\
  -e SKOOH_API_KEY=your_api_key \\
  -e FORWARD_URL=http://siem-collector:8080/webhooks/okta \\
  --restart unless-stopped \\
  skooh/proxy

3. Configure Okta Event Hook

Note: See Okta's Event Hooks documentation for current setup instructions.

In Okta Admin Console:

  1. Go to Workflow → Event Hooks
  2. Click Create Event Hook
  3. Enter your Skooh URL
  4. Select events to subscribe to
  5. Complete verification (see below)

Okta Verification Challenge

Okta verifies your endpoint with a one-time challenge:

app.get('/webhooks/okta', (req, res) => {
  // Okta sends verification as GET request
  const challenge = req.headers['x-okta-verification-challenge'];
  if (challenge) {
    return res.json({ verification: challenge });
  }
  res.status(400).send('Missing challenge');
});

Handling Okta Events

app.post('/webhooks/okta', express.json(), async (req, res) => {
  // Verify authorization header
  const authHeader = req.headers['authorization'];
  if (authHeader !== \`Bearer \${process.env.OKTA_HOOK_SECRET}\`) {
    return res.status(401).send('Unauthorized');
  }
  
  const { data } = req.body;
  const { events } = data;
  
  for (const event of events) {
    await processOktaEvent(event);
  }
  
  res.status(200).send('OK');
});

async function processOktaEvent(event) {
  const { eventType, actor, target, outcome, published } = event;
  
  // Log to SIEM
  await siemClient.log({
    source: 'okta',
    type: eventType,
    timestamp: published,
    actor: {
      id: actor.id,
      email: actor.alternateId,
      displayName: actor.displayName
    },
    target: target.map(t => ({
      id: t.id,
      type: t.type,
      displayName: t.displayName
    })),
    outcome: outcome.result,
    reason: outcome.reason
  });
  
  // Alert on suspicious events
  if (isSuspicious(event)) {
    await alertSecurityTeam(event);
  }
}

Key Security Events to Monitor

const HIGH_PRIORITY_EVENTS = [
  'user.session.start',           // Login
  'user.authentication.sso',      // SSO authentication
  'user.mfa.factor.activate',     // New MFA factor
  'user.mfa.factor.deactivate',   // MFA removed
  'user.account.lock',            // Account locked
  'user.account.unlock',          // Account unlocked
  'user.lifecycle.suspend',       // User suspended
  'policy.evaluate_sign_on',      // Sign-on policy evaluation
  'security.threat.detected',     // Threat detected
];

function isSuspicious(event) {
  // Multiple failed logins
  if (event.eventType === 'user.session.start' && 
      event.outcome.result === 'FAILURE') {
    return true;
  }
  
  // MFA bypass attempts
  if (event.eventType.includes('mfa') && 
      event.outcome.result === 'FAILURE') {
    return true;
  }
  
  // Unusual location
  if (event.client?.geographicalContext?.country !== expectedCountry) {
    return true;
  }
  
  return false;
}

Event Filtering in Okta

Don't forward everything—Okta generates many events. Filter in Okta:

  1. In Event Hook settings, click Subscribe to events
  2. Choose specific event types:
    • `user.session.start`
    • `user.authentication.auth_via_mfa`
    • `user.lifecycle.*`
    • `security.threat.detected`

This reduces noise and ensures you focus on security-relevant events.

Audit Trail via Skooh Inspector

Skooh stores every webhook for 30 days. Use this for:

  • Incident investigation: Find all events for a user/timeframe
  • Compliance: Prove you received and processed security events
  • Debugging: Replay events to test your handler

Replaying for Investigation

During a security incident:

  1. Filter webhooks by time window
  2. Find events related to the compromised account
  3. Replay to your analysis tools
  4. Build a timeline without touching production Okta

Set up Okta event hooks →

Written by Skooh Team

Share:

Ready to try Skooh?

Start receiving webhooks in your local environment in under 5 minutes.

Skooh | Okta Event Hooks to an Internal Security Service Using Skooh