Collect Cisco Identity Intelligence logs
This document explains how to configure Cisco Identity Intelligence to push logs to Google Security Operations using webhooks.
Cisco Identity Intelligence (formerly Oort Security) is an identity threat detection and response platform that continuously monitors user behavior, authentication patterns, device usage, and access privileges across identity providers. It detects identity-based threats, misconfigurations, and compliance violations by analyzing user activity, failed security checks, trust scores, and risky behaviors.
Before you begin
Make sure that you have the following prerequisites:
- A Google SecOps instance
- Privileged access to a Cisco Identity Intelligence tenant
- Administrative permissions to manage integrations in Cisco Identity Intelligence
- Access to Google Cloud Console (for API key creation)
Create webhook feed in Google SecOps
Create the feed
- Go to SIEM Settings > Feeds.
- Click Add New Feed.
- On the next page, click Configure a single feed.
- In the Feed name field, enter a name for the feed (for example,
Cisco Identity Intelligence Events). - Select Webhook as the Source type.
- Select Cisco Identity Intelligence as the Log type.
- Click Next.
- Specify values for the following input parameters:
- Split delimiter (optional): Enter
\nto split multi-line events. - Asset namespace: The asset namespace
- Ingestion labels: The label to be applied to the events from this feed
- Split delimiter (optional): Enter
- Click Next.
- Review your new feed configuration in the Finalize screen, and then click Submit.
Generate and save secret key
After creating the feed, you must generate a secret key for authentication:
- On the feed details page, click Generate Secret Key.
- A dialog displays the secret key.
- Copy and save the secret key securely.
Get the feed endpoint URL
- Go to the Details tab of the feed.
- In the Endpoint Information section, copy the Feed endpoint URL.
The URL format is:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateor
https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateSave this URL for the next steps.
Click Done.
Create Google Cloud API key
Chronicle requires an API key for authentication. Create a restricted API key in the Google Cloud Console.
Create the API key
- Go to the Google Cloud Console Credentials page.
- Select your project (the project associated with your Chronicle instance).
- Click Create credentials > API key.
- An API key is created and displayed in a dialog.
- Click Edit API key to restrict the key.
Restrict the API key
- In the API key settings page:
- Name: Enter a descriptive name (for example,
Chronicle Webhook API Key)
- Name: Enter a descriptive name (for example,
- Under API restrictions:
- Select Restrict key.
- In the Select APIs dropdown, search for and select Google SecOps API (or Chronicle API).
- Click Save.
- Copy the API key value from the API key field at the top of the page.
- Save the API key securely.
Configure Cisco Identity Intelligence webhook
Construct the webhook URL
Combine the Chronicle endpoint URL and API key:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>Example:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
Replace the following:
<ENDPOINT_URL>: The Chronicle feed endpoint URL copied earlier<API_KEY>: The Google Cloud API key created earlier<SECRET_KEY>: The Chronicle webhook secret key generated earlier
Create webhook notification target in Cisco Identity Intelligence
- Sign in to Cisco Identity Intelligence.
- Go to Integrations.
- Click Add Integration.
- Scroll down to the Webhook section.
- Click Add Webhook Target.
- Provide the following configuration details:
- Name: Enter a descriptive name (for example,
Chronicle SIEM Integration). - Webhook URL: Paste the complete endpoint URL with API key and secret key from above.
- Authorization Type: Select API Key.
- API Key Name: Enter a key name (for example,
x-goog-chronicle-auth). - API Key Value: Enter the Google Cloud API key.
- Name: Enter a descriptive name (for example,
- Expand the Invocation HTTP Parameters section.
- Add the following parameters with the type Header:
- Key:
Content-Type, Value:application/json - Key:
Accept, Value:application/json
- Key:
- In the Use this target for section, select Failed Check to receive notifications when identity checks detect failed results.
Click Save.
Test the webhook connection
- On the Integrations page, find the webhook notification target you created.
- Click the three-dot menu on the right side of the row.
- Select Test Connectivity.
- Verify that the test message is delivered successfully.
Enable the webhook for identity checks
After creating the webhook notification target, you must enable it for the specific identity checks you want to monitor.
- Go to the desired Check details page in Cisco Identity Intelligence.
- Expand the dropdown on the top-right corner of the page.
- Select the checkbox for the webhook notification target you created.
Repeat for each check you want to send to Google SecOps.
For more information, see the Cisco Identity Intelligence webhook documentation.
Authentication methods reference
Chronicle webhook feeds support multiple authentication methods. Choose the method that your vendor supports.
Method 1: Custom headers (Recommended)
If your vendor supports custom HTTP headers, use this method for better security.
Request format:
POST <ENDPOINT_URL> HTTP/1.1 Content-Type: application/json x-goog-chronicle-auth: <API_KEY> x-chronicle-auth: <SECRET_KEY> { "event": "data", "timestamp": "2025-01-15T10:30:00Z" }
Advantages:
- API key and secret not visible in URL
- More secure (headers not logged in web server access logs)
- Preferred method when vendor supports it
Method 2: Query parameters
If your vendor does not support custom headers, append credentials to the URL.
URL format:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>Example:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...Request format:
POST <ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY> HTTP/1.1 Content-Type: application/json { "event": "data", "timestamp": "2025-01-15T10:30:00Z" }
Disadvantages:
- Credentials visible in URL
- May be logged in web server access logs
- Less secure than headers
Method 3: Hybrid (URL + Header)
Some configurations use API key in URL and secret key in header.
Request format:
POST <ENDPOINT_URL>?key=<API_KEY> HTTP/1.1 Content-Type: application/json x-chronicle-auth: <SECRET_KEY> { "event": "data", "timestamp": "2025-01-15T10:30:00Z" }
Authentication header names
Chronicle accepts the following header names for authentication:
For API key:
x-goog-chronicle-auth(recommended)X-Goog-Chronicle-Auth(case-insensitive)
For secret key:
x-chronicle-auth(recommended)X-Chronicle-Auth(case-insensitive)
Webhook limits and best practices
Request limits
| Limit | Value |
|---|---|
| Max request size | 4 MB |
| Max QPS (queries per second) | 15,000 |
| Request timeout | 30 seconds |
| Retry behavior | Automatic with exponential backoff |
UDM mapping table
| Log Field | UDM Mapping | Logic |
|---|---|---|
| account | account_label.value | Value copied directly |
| account | account_label.key | Set to "account" |
| account_label | security_result.detection_fields | Merged into detection_fields |
| additional_detaildescription.key | additional_detaildescription.key | Set to "detail description" |
| detaildescription | additional_detaildescription.value.list_value.values | Merged from detaildescription |
| additional_detaildescription | event.idm.read_only_udm.additional.fields | Merged into additional.fields |
| additional_recommendedaction.key | additional_recommendedaction.key | Set to "recommended action" |
| recommendedAction | additional_recommendedaction.value.list_value.values | Merged from recommendedAction |
| additional_recommendedaction | event.idm.read_only_udm.additional.fields | Merged into additional.fields |
| data1 | usersFailing_label | Value copied directly |
| data.login | login_label | Value copied directly |
| detail-type | security_result.summary | Value copied directly |
| detail.id | security_result.rule_id | Value copied directly |
| detail.title | security_result.rule_name | Value copied directly |
| detail.severity | security_result.severity | Value from detail.severity if in [CRITICAL,ERROR,HIGH,INFORMATIONAL,LOW,MEDIUM], else MEDIUM if moderate |
| detaildescription | value_array.string_value | Value copied directly |
| detailsdata.key | add_label.value, add_label.key | Value from detailsdata.value, key as "loginDetails %{index} details %{detailindex} %{detailsdata.key}" if not failedSigninDetails or ips |
| detailsdata.value | add_label.value, add_label.key | |
| detailsdata.key | security_result.detection_fields | Merged add_label if conditions met |
| detailsdata.value | security_result.detection_fields | |
| field_.value | security_result.detection_fields | Merged for various nested fields in json_array (msg, ipInfo, asn, coordinates, first_event, second_event, locations) with keys like "%{index} %{detailindex} %{index1} %{key}" etc., excluding ipAddress, ip, etc. |
| field_.key | security_result.detection_fields | |
| id | metadata.product_log_id | Value copied directly |
| login_label | principal.user.email_addresses | Merged if matches email regex |
| msg.ipAddress | principal.ip | Merged if not empty |
| msg.first_event.ip_address | principal.ip | Merged if not empty |
| msg.second_event.ip_address | principal.ip | Merged if not empty |
| msg_travels_first_event_ip_address | principal.ip | Merged if not empty |
| msg_travels_second_event_ip_address | principal.ip | |
| recommendedAction | value_array.string_value | Value copied directly |
| security_result | event.idm.read_only_udm.security_result | Merged into security_result |
| source | source_label.value | Value copied directly |
| source | source_label.key | Set to "source" |
| source_label | event.idm.read_only_udm.src.labels | Merged into src.labels |
| time | @timestamp | Parsed using date filter with ISO8601, RFC3339, yyyy-MM-ddTHH:mm:ss.SSSSSSZ |
| usersFailing_label | principal.user.email_addresses | Merged if matches email regex |
| version | metadata.product_version | Value copied directly |
| has_principal | event.idm.read_only_udm.metadata.event_type | Set to "STATUS_UPDATE" if has_principal true, else "USER_UNCATEGORIZED" if has_user true, else "GENERIC_EVENT" |
| has_user | event.idm.read_only_udm.metadata.event_type | |
| metadata.product_name | metadata.product_name | Set to "OORT" |
| metadata.vendor_name | metadata.vendor_name | Set to "OORT" |
Need more help? Get answers from Community members and Google SecOps professionals.