Okta Detections and Queries

Integration

Panther supports Okta System Log as a native API puller. See the onboarding guide here.
The Okta System Log schema can be found under Analysis -> Schema within the Panther UI or from the Panther Analysis repository on Github.

Native Detections

Panther has a number of detections specifically for Okta. These can all be found within the Panther Analysis repository on Github.

Okta Admin Role Assigned - A user has been granted administrative privileges in Okta=

Okta API Key Created - A user created an API Key in Okta

Okta API Key Revoked - A user has revoked an API Key in Okta

Geographically Improbable Okta Login - A user has subsequent logins from two geographic locations that are very far apart

Have other Okta detections that can be used by other customers? Consider sharing detections back to the Panther Analysis repository or work with your Customer Success team!

Custom Detections

Suspicious Behavior Reported

Description: A user has reported suspicious behavior from their account
1
def rule(event):
2
if event.get('eventtype') == 'user.account.report_suspicious_activity_by_enduser':
3
return True
Copied!
Below are some common functions and example deep_get() uses when writing custom detections for Okta. Explanations on different event types can be found in the Okta documentation.
1
#Okta has many event types that are listed here. You can begin your detection based on one of these eventtypes
2
#https://developer.okta.com/docs/reference/api/event-types/
3
event.get('eventtype')
4
5
#To access the city, state, lat, lon etc.
6
deep_get(event, 'client', 'geographicalContext', 'city')
7
deep_get(event, 'client', 'geographicalContext', 'state')
8
deep_get(event, 'client', 'geographicalContext', 'country')
9
deep_get(event, 'client', 'geographicalContext', 'geolocation', 'lon')
10
deep_get(event, 'client', 'geographicalContext', 'geolocation', 'lat')
11
12
#Details on the source of the event
13
deep_get(event, 'client' 'device')
14
deep_get(event, 'client', 'ipAddress')
15
deep_get(event, 'client', 'userAgent')
16
17
18
deep_get(event, 'actor', 'alternateId')
19
deep_get(event, 'actor', 'displayName')
20
21
## Global helpers that may be useful with Okta
22
23
# within panther_base_helpers
24
def okta_alert_context(event: dict):
25
"""Returns common context for automation of Okta alerts"""
26
return {
27
"ips": event.get("p_any_ip_addresses", []),
28
"actor": event.get("actor", ""),
29
"target": event.get("target", ""),
30
"client": event.get("client", ""),
31
}
32
33
# within panther_base_helpers
34
def is_ip_in_network(ip_addr, networks):
35
"""Check that a given IP is within a list of IP ranges"""
36
return any(ip_address(ip_addr) in ip_network(network) for network in networks)
Copied!

Queries

Below are a few queries to get started with investigating and learning about your Okta events. These queries are meant to investigate existing log data. If you are interested in detecting new data that flows in, we recommend trying out the detections shown above.
The following queries are written for Snowflake SQL syntax, unless noted otherwise.

Top logins by user last 7 days

1
-- Top logins by user last 7 days
2
SELECT actor:alternateId as actor, COUNT(*) as total
3
FROM panther_logs.public.okta_systemlog
4
WHERE eventtype = 'user.authentication.sso'
5
and outcome:result = 'SUCCESS'
6
and p_occurs_since(7d)
7
GROUP BY actor
8
ORDER BY total desc
Copied!

Logins by hour last 1 day

1
-- Logins by hour last 1 day
2
SELECT
3
time_slice(p_event_time, 1, 'HOUR', 'START') as "start",
4
time_slice(p_event_time, 1, 'HOUR', 'END') as "end",
5
count(*) as "logins",
6
count(distinct(actor:alternateId)) as "users"
7
FROM panther_logs.public.okta_systemlog
8
WHERE eventtype = 'user.authentication.sso'
9
and outcome:result = 'SUCCESS'
10
and p_occurs_since(1d)
11
GROUP BY "start", "end"
12
ORDER BY "start" desc
Copied!

Top applications last 7 days

1
-- Top applications last 7 days
2
SELECT GET(target, 0):displayName as application, count(*) as total
3
FROM panther_logs.public.okta_systemlog
4
WHERE eventtype = 'user.authentication.sso'
5
and p_occurs_since(7d)
6
GROUP BY Application
7
ORDER BY total desc
Copied!

Top failing users last 7 days

1
-- Top failing users last 7 days
2
SELECT actor:alternateId as actor, COUNT(*) as total
3
FROM panther_logs.public.okta_systemlog
4
WHERE eventtype = 'user.session.start'
5
and outcome:result = 'FAILURE'
6
and outcome:reason = 'INVALID_CREDENTIALS'
7
and p_occurs_since(7d)
8
GROUP BY actor
9
ORDER BY total desc
Copied!

Login failures by reason last 7 days

1
-- Login failures by reason
2
SELECT outcome:reason as reason, COUNT(*) as total
3
FROM panther_logs.public.okta_systemlog
4
WHERE eventtype = 'user.session.start'
5
and outcome:result = 'FAILURE'
6
and p_occurs_since(7d)
7
GROUP BY reason
8
ORDER BY total desc
Copied!

Fake account login attempts last 7 days

1
-- Fake account login attempts
2
SELECT actor:alternateId as actor, COUNT(*) as total
3
FROM panther_logs.public.okta_systemlog
4
WHERE eventtype = 'user.session.start' and
5
outcome:result = 'FAILURE' and
6
outcome:reason = 'VERIFICATION_ERROR'
7
GROUP BY actor
8
ORDER BY total desc
Copied!
Identify Okta Support access to your Okta organization
Snowflake SQL:
1
SELECT
2
p_event_time as event_time,
3
actor:alternateId as actor_email,
4
actor:displayName as actor_name,
5
client:ipAddress as src_ip,
6
client:geographicalContext:city as city,
7
client:geographicalContext:country as country,
8
client:userAgent:rawUserAgent as user_agent,
9
displayMessage,
10
eventType
11
FROM
12
panther_logs.public.okta_systemlog
13
WHERE
14
eventType = 'user.session.impersonation.grant'
15
OR
16
eventType = 'user.session.impersonation.initiate'
17
AND
18
p_occurs_between('YYYY-MM-DD','YYYY-MM-DD')
19
ORDER BY
20
event_time desc
Copied!
Athena SQL:
1
SELECT
2
p_event_time as event_time,
3
actor.alternateid as actor_email,
4
actor.displayName as actor_name,
5
displayMessage,
6
eventType,
7
client.ipAddress as src_ip,
8
client.geographicalContext.city as city,
9
client.geographicalContext.country as country,
10
client.useragent.rawUserAgent as user_agent
11
FROM panther_logs.okta_systemlog
12
WHERE
13
(
14
eventType = 'user.session.impersonation.grant' OR
15
eventType = 'user.session.impersonation.initiate'
16
) and
17
p_occurs_between('YYYY-MM-DD','YYYY-MM-DD')
18
ORDER BY
19
event_time desc
Copied!
Identify all users who have been granted Admin privileges in Okta
Snowflake SQL:
1
SELECT
2
p_event_time as event_time,
3
actor:alternateId as actor_email,
4
actor:displayName as actor_name,
5
displayMessage,
6
eventType,
7
debugContext:debugData:privilegeGranted as priv_granted,
8
target as target_user,
9
client:ipAddress as src_ip,
10
client:geographicalContext:city as city,
11
client:geographicalContext:country as country,
12
client:userAgent:rawUserAgent as user_agent
13
FROM
14
panther_logs.public.okta_systemlog
15
WHERE
16
( eventType = 'user.account.privilege.grant'
17
OR
18
eventType = 'group.privilege.grant'
19
AND
20
debugContext:debugData:privilegeGranted like '%Admin%'
21
)
22
AND
23
p_occurs_between(''YYYY-MM-DD','YYYY-MM-DD')
24
ORDER BY
25
event_time desc
Copied!
Athena SQL:
1
SELECT
2
p_event_time as event_time,
3
actor.alternateid as actor_email,
4
actor.displayName as actor_name,
5
displayMessage,
6
eventType,
7
client.ipAddress as src_ip,
8
client.geographicalContext.city as city,
9
client.geographicalContext.country as country,
10
client.useragent.rawUserAgent as user_agent
11
FROM panther_logs.okta_systemlog
12
WHERE
13
(
14
eventType = 'user.account.privilege.grant' OR
15
eventType = 'group.privilege.grant'
16
) AND
17
p_occurs_between('YYYY-MM-DD','YYYY-MM-DD')
18
ORDER BY
19
event_time desc
Copied!