Enterprise Defense

Okta Log Overview

Leah Zulas
April 4, 2024
min read

If you’re reading this, then welcome to our introductory series of posts designed to demystify user audit records from all kinds of SaaS systems.

At Turngate, we’re focused on taking the pain out of a complicated system of audit records for security practitioners of any level of experience. If you’ve found yourself saying “Help, what do all of these logs mean?” or “How on earth will I find the relevant data I need in all of this mess?” then this Okta log overview was written for you.

We know how important it is to get quick context when you’re in the heat of research. This can be especially frustrating for junior security practitioners who haven’t built the investigation hours to become fast at it. This blog focuses on getting quick clarity from Okta in order to rapidly respond during security investigations – but we’ve got another blog on Google Workspaces, too.

Getting Access

Like audit sources for many SaaS-based products, there are two ways to get access to Okta audit records: through the web-based Admin interface and through the API. In the Okta Admin interface, navigate to Reporting -> System Log and you’ll find all logs for your instance. Okta has documentation on the interface, how to use the filters, and general guidance on the various events.

By default, Okta retains your logs for 90 days. If you try to access logs in the web interface past that retention period, Okta will return an error.

Okta’s API exposes the System Logs (and much more Okta functionality if you’re interested) in a robust and well-documented way. One of the nice things about the Okta API is it supports OpenID Connect and OAuth2. Simply put, when you set up access to their API, you can limit the scope of what that connection has access to and force the connection through a single sign-on process. It does make the setup a bit more complicated, but it’s worth it. Users with API access to Okta can potentially have access to a vast amount of functionality and can bypass many security controls in your organization. Taking the time to set up API access correctly and securely is a necessity when it comes to interfacing with your Identity Provider.

Understanding the Log Structure

Depending on how you access the logs, you’ll be dealing with a very different structure to the log data. In the web interface, each log entry is presented in a table. There are two levels of expansion. The first gets you some high-level detail around the log entry like this.

If you click Expand All, all fields will be completely expanded. Be prepared to scroll. The expanded log contains detailed information about the client location, various identifiers for the transaction, OS and browser information, information on the status of the request, and other odds and ends. Honestly, it’s rare that when looking through Okta logs you find yourself lacking in detail; generally that’s great, but it can be overwhelming.

There’s a search interface for the audit records as well that allows you to search for specific clients, users, IP addresses, and other characteristics available in the logs.

The query language is robust and lets you dig deep into the logs to find exactly what you want. However, there are numerous fields to search against and sometimes it can be confusing to know how to actually search for “exactly what you want.”

When accessed via API, Okta logs come from the source as JSON objects. You can either look at them in that form, or you can use a library from any major language to parse them into something easier to consume. In our research we used Python’s standard JSON library, Python’s flatten_JSON library, and/or Sparks JSON converter

Session IDs and Transaction IDs

The API is well documented and as you dig into your audit data, you’ll want to keep Okta’s API reference for the System Logs close at hand. Okta has a useful piece of information in their logs that not many other SaaS providers will have: the transaction ID. Whereas most audit sources, including Okta, will have a sessionID, or an ID that is associated with a single event in the system, a transaction ID adds slightly more context. A transaction ID bundles many actions into a single transaction to simplify analysis. For example, when a user logs in, the system produces multiple discrete logs from that single transaction (like checking a password, checking a 2FA token, and starting a session). Okta tags all those individual logs with a transaction ID to help you keep track of what logs belong together as a group. Pretty handy, honestly, and we wish more providers offered these types of breadcrumbs in their logs.

Audit Entries of Interest

In an organization of reasonable size, Okta generates a ton of audit data. That’s great because it means the information you want is probably in the logs somewhere. However, understanding what to look for can be overwhelming. Here are some audit entries that we hope will serve as a useful starting point for your analysis.

API Name Location in “Audit and Investigations” Description
user.session.start displayMessage eq "User login to Okta" For all user logins, this is the audit entry that gives you the details on the login event.
varies outcome.result eq "FAILURE" If a user attempts to log in and fails for some reason, these logs will give the reason. Credential (ie: password) and MFA failures are common in small amounts. eventType eq "" If you’ve engaged Okta support, they can assume a role in your organization. Any activities taken by Okta in that scope will be logged here.
user.lifecycle.create/suspend/unsuspend/activate/deactivate eventType eq "user.lifecycle.create/suspend/unsuspend/activate/deactivate" These are entries for lifecycle changes in Okta. There are other ways that users can be created and activated, but this is the basic entry.
user.session.access_admin_app eventType eq "user.session.access_admin_app" Any access to the Admin portal will result in this audit entry.
user.account.lock.limit eventType eq "user.account.lock.limit" An account has been locked out due to excessive login attempts or other reasons.

PI and Confidential Information Considerations

Okta is an Identity Provider. Said another way, it’s the gatekeeper to your entire enterprise. Okta knows who your users are, where they log in from, what applications they access, and when they access them. While not exactly sensitive in the same way that bank account details are, the information contained in Okta constitutes a pattern of life that is sensitive information for that user. It’s important to be respectful of the information stored in Okta and ensure any data you’ve exported from the UI or accessed via the API is protected appropriately.

The good news is that once a user authenticates, they’re passed off to another application. While Okta logs contain pattern-of-life information, they don’t contain more sensitive information like emails, documents that are being worked on, or HR data.

Parting Thoughts

Okta has been a core vendor when it comes to the shift to the cloud many companies have made in the last decade. Okta is aware of the sensitive nature of the service they provide and have created an audit record that allows IT and security staff to troubleshoot and investigate activities in their environment. These records are comprehensive and available through the UI and via API for you to sift through. That said, it can be complicated to dig through all this information on your own, especially if you’re not familiar with Okta’s audit log contents. If you’re in a hurry (or you want to try something new), check out our offering. We can get you up and running quickly, and within a few minutes you’ll have a streamlined view into your Okta data helping you answer complex questions easily.

Share this post