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.

OCI Sessions

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())

 

 

 

Create Policies so that Connector can Access Target to Write files to Object Storage.

After Connector is activated it will start writing files frequently –

 

 




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
 


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

OCI CLI + SearchLogsDetails

Bulk download of logs programmatically

OCI CLI + list_call_get_all_results

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

 

  1. Fusion Identity Upgrade
  2. OCI Audit
  3. OCI Events
  4. OCI Service Connector
  5. OCI Logging
  6. OCI CLI
  7. OCI Dashboard
  8. OCI SDK
  9. OCI Audit API
  10. Manage Oracle Cloud Infrastructure REST APIs Programmatically using Shell and Java Code
  11. Export OCI Audit Logs in CSV format for a custom time range
  12. Implement multicloud security using OCI Audit to capture events from OCI Identity and Access Management
  13. Generate Identity and Access Management Reports from Oracle Cloud Infrastructure Audit