from datetime import datetime, timedelta
import requests
OKTA_TOKEN = "YOUR_OKTA_TOKEN"
LUMOS_TOKEN = "YOUR_LUMOS_TOKEN"
base_url = "https://YOUR_ENVIRONMENT.okta.com/api/v1"
users_endpoint = "/users"
logs_endpoint = (
'/logs?filter=eventType+eq+"user.authentication.sso"'
'+and+actor.id+eq+"{actor_id}"&since={since}&until={until}'
'&sortOrder=DESCENDING&limit=1000'
)
def fetch_okta_users():
users = []
next_url = base_url + users_endpoint
while next_url:
response = requests.get(
next_url,
headers={ "Authorization": f"SSWS {OKTA_TOKEN}" }
)
next_url = response.links.get("next", {}).get("url")
users += response.json()
return users
def fetch_logs_for_user(user):
logs = []
checkpoint_start = datetime.utcnow() - timedelta(days=90)
next_url = base_url + logs_endpoint.format(
actor_id=user['id'],
since=checkpoint_start.isoformat(),
until=datetime.utcnow().isoformat(),
)
while next_url:
response = requests.get(
next_url,
headers={ "Authorization": f"SSWS {OKTA_TOKEN}" }
)
next_url = response.links.get("next", {}).get("url")
logs += response.json()
return logs
def format_logs(logs):
formatted_logs = []
for log in logs:
timestamp = log.get("published")
targets = log.get("target", [])
app_identifiers = [
target["id"]
for target in targets
if target.get("type") == "AppInstance"
]
app_identifier = app_identifiers[0]
actor_id = log.get("actor", {}).get("id", "")
formatted_logs.append({
"timestamp": timestamp,
"event": { "type": "LOGIN" },
"app": { "instance_identifier": app_identifier },
"account": { "external_id": actor_id },
"source_app_id": "OKTA_APP_ID"
})
return formatted_logs
# Save activity records for each user
for user in users:
logs = fetch_logs_for_user(user)
formatted_logs = format_logs(logs)
# upload to Lumos
requests.post(
"https://api.lumos.com/activity_records",
headers={ "Authorization": f"Bearer {LUMOS_TOKEN}" },
json={
"records": formatted_logs
}
)