Introduction
OCI Audit is an OCI service that automatically records calls to all supported OCI APIs as events. OCI Audit offers the following benefits:
- All audit data with multiple identity domains is available in one central place
- Provides a single source of truth for all actions in your cloud
- Tracking who did what, when, and from where
- Data can be pushed to external systems such as SIEMs
- OCI Audit stores event data for a year
Please read blog – Methods and ways to extract OCI Events using OCI Audit and Integrate into external systems, to understand various options available & implementation details along with prerequisites, same would be used to extract Session Information – in our use case we will consider – Fusion Cloud Application hosted inside OCI.
In Current state for Fusion cloud applications, to get Fusion Session Login Information below API is used –
Fusion Security: Using Sign In – Sign Out Audit REST API (Doc ID 2661308.1)
This provides login IP Address, type, login status, device (browser as user agent) etc…
However, post ongoing identity upgrade into OCI IAM, this method would no longer work.
Oracle Cloud Infrastructure Identity and Access Management Audit Events API’s which was earlier used for IAM identity domains are deprecated (May 2025).
Therefore now we have standardization of Audit API’s for all OCI resources, going forward you will need to use the OCI Audit APIs instead.
This blog explores methods to extract session-related events (e.g., logins) for any application hosted on OCI, in this case – Fusion Cloud Applications —and integrate the data into external systems like SIEM for enhanced visibility and security.
Details:
Below are overall details of how Session information can be extracted for given compartment ID, in our use case we will consider compartment where Fusion Application is hosted, we will discuss all this in detail.

Examples of events associated with IAM Activities are listed here, We will use them to track Fusion Application Session information which is residing in Fusion Application IAM domain.
OCI Events which are interest to us are grouped under – IdentitySignOn events:
| Event Name |
Description |
| IdentitySignOn.VerifyMfaToken |
Multi-Factor Authentication (MFA) token verified successfully for a user session. |
| IdentitySignOn.TokenRequest |
User or application requested an access token to authenticate with OCI services. |
| IdentitySignOn.SupportAccountSamlRequest |
SAML request initiated to access a support account (cross-account or delegated access). |
| IdentitySignOn.ModifySSOSession |
A user’s session was modified, such as extending duration or updating session state. |
| IdentitySignOn.InteractiveLogin |
A user initiated an interactive login, typically via UI (console, federated login, etc.). |
| IdentitySignOn.FederatedInteractiveloginattempt |
A user attempted to log in via a federated identity provider (e.g., Okta, Azure AD). |
| IdentitySignOn.FactorMfa |
A specific MFA factor (like OTP, push notification) was triggered or used. |
| IdentitySignOn.DeleteSession |
User session was explicitly terminated or logged out. |
| IdentitySignOn.ChangePassword |
User changed their password through self-service or admin action. |
| IdentitySignOn.AuthcodeRequest |
Authorization code request initiated during OAuth2 flow (before token exchange). |
| IdentitySignOn.AccessApp |
User accessed an OCI-integrated application or service via identity federation. |
Listing few Important attributes that can be extracted out of IdentitySignOn events JSON response –
data.additionalDetails
| Attributes |
Example |
| actorDisplayName |
rats_monitor |
| clientIp |
X.X.X.X |
| eventid |
sso.session.delete.success |
| ssoIdentityProvider |
UserNamePassword |
| compartmentId |
ocid1.tenancy.oc1 |
| compartmentName |
XXX |
| eventName |
DeleteSession |
| message |
DeleteSession succeeded |
| response. Status |
200 |
| responseTime |
2025-08-01T09:57:57.699Z |
| type |
com.oraclecloud.IdentitySignOn.DeleteSession |
data.identity
| Attributes |
Example |
| ipAddress |
X.X.X.X |
| principalId |
ocid1.user.oc1.. |
| principalName |
rats_monitor |
| tenantId |
ocid1.tenancy.oc1… |
| userAgent |
Mozilla/5.0 (Windows NT 10.0; Win64; x64) |
We will use below options for extracting and processing Fusion Session Information.
Connecting to OCI REST APIs using an SDK involves leveraging language-specific libraries provided by Oracle to interact with OCI services programmatically. This approach simplifies API calls by handling authentication, request signing, and response parsing.
OCI CLI commands wrapped inside scripts or Python code that run as serverless functions (OCI Functions). These functions can be triggered via API Gateway endpoints, enabling external systems to call them easily over REST APIs.
We will use Oracle Cloud Infrastructure SDK for Python
Below two methods can be used to fetch Audit logs –
Invoke oci.loggingsearch.models.SearchLogsDetails to perform log queries, as we search in OCI Logging UI Search.
Refer example – Export OCI Audit Logs in CSV format for a custom time range
You need to pass query statement as you can query in Logging UI along with start time & end time
Query variable contains – Compartment ID, User Principle, Events, Event Attributes etc., same way you query in Logging UI, this search provides more flexibility for adhoc searches.
Sample Code –
Below is Sample code how to extract event from API, you need to extend this method to write as file in Object Storage & then use it inside Oracle Functions to be called Via REST API or whatever ways you need to consume it.
| import oci from datetime import datetime, timedelta, timezone # Load OCI config from default location (~/.oci/config) and default profile config = oci.config.from_file() # Optional: print config to confirm it’s loading correctly # print(config) # Initialize LogSearchClient client = oci.loggingsearch.LogSearchClient(config) # Replace this with your compartment OCID (tenancy or sub-compartment) compartment_id = config[“tenancy”] # Time range: last 1 day # Use explicit time range (example: last 1 hour) end_time = datetime.now(timezone.utc) start_time = end_time – timedelta(hours=1) # Convert to ISO 8601 string with ‘Z’ for UTC iso_start = start_time.strftime(“%Y-%m-%dT%H:%M:%S.%f”)[:-3] + “Z” iso_end = end_time.strftime(“%Y-%m-%dT%H:%M:%S.%f”)[:-3] + “Z” # Print to verify print(f”Query Time Range:\nStart: {iso_start}\nEnd: {iso_end}”) # Query to Pass for selected compartment and identity events query = f’search “{compartment_id}/_Audit” “{compartment_id}” | where upper(data.eventName) in (\’ACCESSAPP\’, \’INTERACTIVELOGIN\’, \’MODIFYSSOSESSION\’, \’VERIFYMFATOKEN\’, \’TOKENREQUEST\’, \’SUPPORTACCOUNTSAMLREQUEST\’, \’FEDERATEDINTERACTIVELOGINATTEMPT\’, \’FACTORMFA\’, \’DELETESESSION\’, \’CHANGEPASSWORD\’, \’AUTHCODEREQUEST\’) | sort by datetime desc’ print(query) # Prepare search request search_details = oci.loggingsearch.models.SearchLogsDetails( time_start=start_time, time_end=end_time, search_query=query, is_return_field_info=False ) # Execute search print(“Execute search.”) response = client.search_logs(search_logs_details=search_details) print(“Status Code:”, response.status) #print(“Headers:”, response.headers) #print(“Data:”, response.data) results = response.data.results if results: for item in results: # print(item) continue # Skip non-matching domains else: print(“No results found or query failed.”)
# Define expected fields fields = [ “actorName”, “eventId”, “httpResponseStatus”, “ssoLocalIp”, “domainDisplayName”, “domainName”, “actorType”, “message”, “userAgent”, “authType”, “callerId”, “callerName”, “credentials”, “ipAddress”, “principalName” ] # Print header print(“|”.join(fields)) # Iterate through each result for item in response.data.results: log_data = item.data.get(“logContent”, {}).get(“data”, {}) additional = log_data.get(“additionalDetails”, {}) identity = log_data.get(“identity”, {}) row = [ str(additional.get(“actorName”, “”)), str(additional.get(“eventId”, “”)), str(additional.get(“httpResponseStatus”, “”)), str(additional.get(“ssoLocalIp”, “”)), str(additional.get(“domainDisplayName”, “”)), str(additional.get(“domainName”, “”)), str(additional.get(“actorType”, “”)), str(log_data.get(“message”, “”)), str(identity.get(“userAgent”, “”)), str(identity.get(“authType”, “”)), str(identity.get(“callerId”, “”)), str(identity.get(“callerName”, “”)), str(identity.get(“credentials”, “”)), str(identity.get(“ipAddress”, “”)), str(identity.get(“principalName”, “”)) ] print(“———“) print(“|”.join(row)) |
Response variable will return JSON Payload response as per Audit REST API Schema.
Automatically fetches more data from the service until the no more records are available
Use oci.pagination.list_call_get_all_results to fetch complete results efficiently
Refer pagination API Sample Code using oci-python-sdk
You need to pass Compartment ID (tenancy ID), start time & end time & it will return all information till all pages are fetched recursively, this way you can export entire audit logs for provided time range.
Sample Code –
Below is Sample code how to extract event from API, you need to extend this method to write as file in Object Storage & then use it inside Oracle Functions to be called Via REST API or whatever ways you need to consume it.
| import oci from datetime import datetime, timedelta, timezone config = oci.config.from_file(“~/.oci/config”, “DEFAULT”) audit_client = oci.audit.AuditClient(config) #print(config[“region”]) # Set compartment OCID compartment_id = config[“tenancy”] # Define time range (last 1 hour) end_time = datetime.now(timezone.utc) start_time = end_time – timedelta(hours=10) # Get ALL events, response = oci.pagination.list_call_get_all_results( audit_client.list_events, compartment_id=compartment_id, start_time=start_time, end_time=end_time ) # Print header print(“event_time | event_id | principal_name | domain | Action | Device | IP | Event”) # Track if any logs matched matched = False count = 0 # Filter and display for event in response.data: data = event.data #print(data) identity = getattr(data, “identity”, None) additional_details = getattr(data, “additional_details”, None) domain = additional_details.get(“domainDisplayName”, “-“) if additional_details else “-“ # FILTER: Only show events with domain = exfhtest if domain != “XX”: continue # Skip non-matching domains # EXCLUDE: Skip if principal name or event contains ‘rats_monitor’ if “rats_monitor” in (getattr(identity, “principal_name”, “”).lower()): continue # Skip events triggered by rats_monitor #print(data) print(‘—————————————————————————‘) FulleventId = additional_details.get(“eventId”, “-“) if additional_details else “-“ #resource_name = getattr(event, “resource_name”, “-“) action = getattr(data, “event_name”, “-“) principal_name = getattr(identity, “principal_name”, “-“) if identity else “-“ user_agent= getattr(identity, “user_agent”, “-“) ip_address= getattr(identity, “ip_address”, “-“) print(f”{event.event_time} | {event.event_id} | {principal_name} | {domain} | {action} | {user_agent} | {ip_address} | {FulleventId}”) matched = True count += 1 if count >= 100: break # STOP after 100 rows # If no logs matched, print a message if not matched: print(f”\nNo logs found for domain ‘exfhtest’ between {start_time} and {end_time}.”) |
Response variable will return JSON Payload response as per Audit REST API Schema.
Service Connector in OCI Logging is used to stream log data from one OCI service (like Logging or Audit) to another destination (like Object Storage, Streaming, Functions, Topics, Monitoring, etc.)
We will use Standard Source – _Audit log group provided by OCI Audit.
We will cover below targets , you can refer for more scenarios
Stream logs to Oracle Streaming for real-time processing or alerting.
Create Connector, Source as Log group – _Audit , Target as Stream
Filter on OCI Service Name & OCI Event Type which you want to capture.
Select All Event Types for Service – Identity SignOn.

Define Oracle Stream & use that as Target


Create Policies so that Connector can Access Target to Stream data.
Script to Test if Stream is working
| import oci import base64 import time
# Load config from ~/.oci/config (or specify config_path, profile_name) config = oci.config.from_file()
# Replace with your actual values stream_ocid = “ocid1.stream. “ # your stream endpoint stream_endpoint = “https://<XXX>.streaming.us-ashburn-1.oci.oraclecloud.com”
# Create StreamClient with custom endpoint stream_client = oci.streaming.StreamClient(config, service_endpoint=stream_endpoint)
# Create a cursor to read messages cursor_details = oci.streaming.models.CreateCursorDetails( partition=”0″, # assuming 1 partition type=”TRIM_HORIZON” ) cursor = stream_client.create_cursor(stream_ocid, cursor_details).data
# Read messages get_messages_result = stream_client.get_messages(stream_ocid, cursor.value, limit=10) print(“Read messages:”) for msg in get_messages_result.data: print(“Key:”, msg.key, “Value:”, base64.b64decode(msg.value).decode()) |
-
- Export logs to Object Storage for long-term retention and analysis.
Create Connector, Source as Log group – _Audit , Target as Object Storage.
Filter on OCI Service Name & OCI Event Type which you want to capture.
Select All Event Types for Service – Identity SignOn

Define Object Storage Bucket & use that as Target

- Export logs to Object Storage for long-term retention and analysis.
Create Policies so that Connector can Access Target to Write files to Object Storage.
After Connector is activated it will start writing files frequently –

-
- Using Topics for Notifying external receipting using – Email, Slack, SMS
Create Connector, Source as Log group – _Audit , Target as Stream
Filter on OCI Service Name & OCI Event Type which you want to capture.
Select Event Types for Service – Identity SignOn in which you want to be notified, in below case I have used event – Change Password Event.

Define Topic & use that as Target
- Using Topics for Notifying external receipting using – Email, Slack, SMS

Create Policies so that Connector can Access Target to Send Notification to Topic.
Check if mail Notification is received after Event occurred.
OCI Logging Saved Search – A predefined query in OCI Logging that filters and retrieves log data based on custom criteria for quick access and analysis
OCI Dashboard – A customizable visual interface in OCI that displays metrics, logs, and saved searches in a unified, interactive view for monitoring and insights
-
- Create Saved Searches and build custom dashboards to visualize and monitor audit events interactively.
Refer this working example – Generate Identity and Access Management Reports from Oracle Cloud Infrastructure Audit
- Create Saved Searches and build custom dashboards to visualize and monitor audit events interactively.
In our case refer Search query being used, this uses Identity SignOn Events.
Search Query –
| search “ocid1.tenancy.oc1..XX/_Audit” “ocid1.tenancy.oc1..XXX” | where upper(data.eventName) in (‘ACCESSAPP’, ‘INTERACTIVELOGIN’, ‘MODIFYSSOSESSION’, ‘VERIFYMFATOKEN’, ‘TOKENREQUEST’, ‘SUPPORTACCOUNTSAMLREQUEST’, ‘FEDERATEDINTERACTIVELOGINATTEMPT’, ‘FACTORMFA’, ‘DELETESESSION’, ‘CHANGEPASSWORD’, ‘AUTHCODEREQUEST’) | sort by datetime desc |

You can use OCI Audit API for the Audit Service. Use this API for compliance monitoring in your tenancy, these API are good for queries, but not bulk-export operations.
Since Oracle Cloud Infrastructure (OCI) REST APIs do not support Basic Authentication (username/password) — you must use OCI Signature-based authentication, Oracle Integration Cloud (OIC) Gen 3 and other OCI services enforce OCI Signature Version 1.
You need to setup OCI API keys for the user based on which REST APIs will connect to the OCI tenancy.
Use the REST Adapter with OCI Signature-based authentication to programmatically retrieve audit events into workflows or third-party tools.
Refer OCI Gen3 Connection Method – OCI Signature Version 1
Parameters used for /20190901/AuditEvent/ListEvents are limited to compartment ID, Start time & End time
OCI Sample Connection –

Sample Integration – Mapping Parameters

Conclusion
Each method for accessing and analyzing OCI Audit logs offers distinct advantages based on use case, scalability, and integration needs:
| Need / Scenario |
Methods |
| Ad-hoc search and filtering of log events |
|
| Bulk download of logs programmatically |
|
| Near real-time log streaming/Long Term Archival |
Service Connector Hub to Stream or Object Storage |
| Dashboards, saved reports for audit team |
OCI Logging UI with saved searches |
| Middleware-based integration Workflows (e.g., OIC) |
OCI Audit REST API with OCI Signature Auth |
Align the choice of method with your organization’s operational model, tooling maturity, and compliance requirements.
References
- Fusion Identity Upgrade
- OCI Audit
- OCI Events
- OCI Service Connector
- OCI Logging
- OCI CLI
- OCI Dashboard
- OCI SDK
- OCI Audit API
- Manage Oracle Cloud Infrastructure REST APIs Programmatically using Shell and Java Code
- Export OCI Audit Logs in CSV format for a custom time range
- Implement multicloud security using OCI Audit to capture events from OCI Identity and Access Management
- Generate Identity and Access Management Reports from Oracle Cloud Infrastructure Audit
