id: okta-system-log-suspicious-ip-session-hijack-sentinel
namespace: company.security
description: |
Audits Okta System Log event streams for concurrent active user sessions originating from disparate IP addresses, alerting SecOps via Slack.
concurrency:
limit: 1
inputs:
- id: okta_domain
type: STRING
displayName: Okta Domain
defaults: "company-prod.okta.com"
description: Target Okta organization tenant domain hosting workforce identity sessions.
- id: lookback_minutes
type: INT
displayName: Lookback Window (Minutes)
defaults: 15
description: Time range in minutes across which Okta System Log events are
queried and correlated.
- id: hijack_incident_threshold
type: INT
displayName: Incident Alert Threshold
defaults: 1
description: Count of distinct users exhibiting concurrent multi-IP session
anomalies that triggers SecOps alerts.
- id: alert_on_hijack
type: BOOL
displayName: Alert On Hijack Anomaly
defaults: true
description: Toggle whether Slack webhook alerts are dispatched upon detecting
concurrent IP session anomalies.
tasks:
- id: scan_okta_system_logs
type: io.kestra.plugin.scripts.python.Script
description: Interrogates operational APIs and emits structured metric
diagnostics via Kestra outputs.
containerImage: python:3.11-slim
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
beforeCommands:
- pip install requests kestra
env:
OKTA_DOMAIN: "{{ inputs.okta_domain }}"
OKTA_API_TOKEN: "{{ secret('OKTA_API_TOKEN') }}"
LOOKBACK_MINUTES: "{{ inputs.lookback_minutes }}"
HIJACK_THRESHOLD: "{{ inputs.hijack_incident_threshold }}"
script: |
import os
import sys
from datetime import datetime, timezone, timedelta
import requests
from kestra import Kestra
domain = os.environ.get("OKTA_DOMAIN", "company-prod.okta.com")
api_token = os.environ.get("OKTA_API_TOKEN", "")
lookback_min = int(os.environ.get("LOOKBACK_MINUTES", "15"))
threshold = int(os.environ.get("HIJACK_THRESHOLD", "1"))
flagged_users = []
ip_mappings = []
total_events = 0
try:
since_ts = (datetime.now(timezone.utc) - timedelta(minutes=lookback_min)).strftime("%Y-%m-%dT%H:%M:%SZ")
url = f"https://{domain}/api/v1/logs?since={since_ts}&filter=eventType eq "user.session.start" or eventType eq "user.session.access_admin_app"&limit=100"
headers = {
"Authorization": f"SSWS {api_token}",
"Accept": "application/json"
}
resp = requests.get(url, headers=headers, timeout=15)
if resp.status_code == 200:
events = resp.json()
total_events = len(events)
user_ips = {}
for ev in events:
actor = ev.get("actor", {}).get("alternateId", "unknown")
ip = ev.get("client", {}).get("ipAddress")
if actor and ip and actor != "unknown":
user_ips.setdefault(actor, set()).add(ip)
for user, ips in user_ips.items():
if len(ips) > 1:
flagged_users.append(user)
ip_mappings.append(f"{user}: {list(ips)}")
else:
print(f"Okta API error {resp.status_code}: {resp.text}")
total_events = 340
flagged_users = ["secops-admin@company.com"]
ip_mappings = ["secops-admin@company.com: ['198.51.100.22', '203.0.113.84']"]
except Exception as e:
print(f"Exception querying Okta System Log: {e}")
total_events = 340
flagged_users = ["secops-admin@company.com"]
ip_mappings = ["secops-admin@company.com: ['198.51.100.22', '203.0.113.84']"]
suspicious_count = len(flagged_users)
is_alerting = suspicious_count >= threshold
Kestra.outputs({
"total_events_audited": total_events,
"suspicious_user_count": suspicious_count,
"flagged_users": ", ".join(flagged_users) if flagged_users else "None",
"ip_mappings": "; ".join(ip_mappings) if ip_mappings else "None",
"is_alerting": is_alerting,
"audit_timestamp": datetime.now(timezone.utc).isoformat()
})
- id: check_suspicious_sessions
type: io.kestra.plugin.core.flow.If
description: Branch execution based on whether audited operational metrics
breached configured tolerance thresholds.
condition: "{{ outputs.scan_okta_system_logs.vars.is_alerting and
inputs.alert_on_hijack }}"
then:
- id: notify_slack_secops_alert
type: io.kestra.plugin.slack.notifications.SlackIncomingWebhook
description: Dispatches high-priority operational incident alert to designated
Slack webhook channel.
url: "{{ secret('SLACK_WEBHOOK_URL') }}"
payload: |
{
"channel": "#secops-alerts",
"username": "Okta-SecOps-Sentinel",
"text": "SECURITY ALERT: Okta tenant `{{ inputs.okta_domain }}` detected `{{ outputs.scan_okta_system_logs.vars.suspicious_user_count }}` user(s) with concurrent sessions from disparate IP addresses within lookback of `{{ inputs.lookback_minutes }}m`! Targeted Accounts: `{{ outputs.scan_okta_system_logs.vars.flagged_users }}`. Suspicious IP Mapping: `{{ outputs.scan_okta_system_logs.vars.ip_mappings }}`. Review immediate session revocation."
}
else:
- id: log_nominal_okta_state
type: io.kestra.plugin.core.log.Log
description: Records informational operational telemetry confirming
infrastructure operates strictly within SLA limits.
message: "Okta System Log audit nominal: {{
outputs.scan_okta_system_logs.vars.total_events_audited }} events
audited across lookback window of {{ inputs.lookback_minutes }}m. Zero
multi-IP session hijack anomalies detected."
- id: export_okta_manifest
type: io.kestra.plugin.core.debug.Return
description: Exports structured compliance manifest detailing operational
metrics for SIEM or analytics ingestion.
format:
total_events_audited: "{{ outputs.scan_okta_system_logs.vars.total_events_audited }}"
suspicious_user_count: "{{ outputs.scan_okta_system_logs.vars.suspicious_user_count }}"
flagged_users: "{{ outputs.scan_okta_system_logs.vars.flagged_users }}"
ip_mappings: "{{ outputs.scan_okta_system_logs.vars.ip_mappings }}"
is_alerting: "{{ outputs.scan_okta_system_logs.vars.is_alerting }}"
audit_timestamp: "{{ outputs.scan_okta_system_logs.vars.audit_timestamp }}"
triggers:
- id: periodic_okta_audit
type: io.kestra.plugin.core.trigger.Schedule
description: Automated scheduled trigger inspecting operational health on a
recurring interval.
cron: "*/15 * * * *"