Google SecOps Instances Integration Guide
Overview
The Google SecOps Instances integration allows your NINA workflows to connect with Google Security Operations (Google SecOps) to search UDM events, investigate entities, validate detection rules, manage instance configuration, and perform threat hunts. This integration targets the Google SecOps Instances API and provides full programmatic access to a single Google SecOps instance.
Capabilities
This integration provides access to 1 resource (instance) with 55 operations covering:
- UDM Search & Query: Search events, validate queries, find field values, translate queries
- Entity Investigation: Find entities, summarize entities, find related entities and alerts
- Detection Engineering: Verify rules, test findings refinements, run threat hunts, generate rules with AI
- Instance Configuration: Get and update BigQuery export, risk config, enrichment combinations, agent settings
- Ingestion Visibility: Query product source stats, search raw logs
- AI Capabilities: Generate detection rules, suggest SQL, generate synthetic events
- Instance Lifecycle: Graduate PoC instances, delete, restore (undelete)
- Reference Data: Verify reference lists, batch validate watchlist entities
API Versions
The connector targets the most stable version available per operation:
| API Version | Usage |
|---|---|
v1 | Stable operations: get, sub-resource reads (getBigQueryExport, getRiskConfig, etc.), listAllFindingsRefinementDeployments, and sub-resource writes (updateBigQueryExport, updateRiskConfig) |
v1alpha | All other operations — query, entity, AI, and lifecycle endpoints not yet promoted to v1 |
Note: The Google SecOps API exposes the same logical operations across
v1,v1alpha, andv1beta. The connector usesv1where it is available andv1alphafor everything else.v1betais not used directly, but the same credentials work across all versions.
Credential Configuration
Authentication Method
Google SecOps Instances uses Google Service Account (OAuth2 service-account flow). The integration authenticates by exchanging a service account JSON key for a short-lived Google access token, which is refreshed automatically.
| Field | Description | Required |
|---|---|---|
serviceAccountJson | Full content of the Google service account JSON key file | Yes |
region | Google SecOps API region prefix (e.g. us, eu) | Yes |
project | GCP project ID or project number that owns the Google SecOps instance | Yes |
location | GCP location string for the instance (e.g. us, eu, europe-west2) | Yes |
instance | Google SecOps instance UUID | Yes |
How Authentication Works
- You provide the service account JSON key when creating a credential.
- On each request the connector calls the Google OAuth2 token endpoint using the private key from the JSON to obtain a short-lived access token (
https://www.googleapis.com/auth/cloud-platformscope). - The token is presented as a
Bearertoken on every Google SecOps API request. - Google access tokens expire after 1 hour. The connector uses the
golang.org/x/oauth2/googlelibrary, which handles renewal automatically. - No user interaction, redirect URLs, or browser flows are involved.
Google SecOps API Regions
Select the region that matches where your Google SecOps instance is deployed:
| Region value | Label | Google SecOps API base URL |
|---|---|---|
us | United States | https://us-chronicle.googleapis.com |
eu | Europe | https://eu-chronicle.googleapis.com |
asia-southeast1 | Asia Pacific — Singapore | https://asia-southeast1-chronicle.googleapis.com |
australia-southeast1 | Australia — Sydney | https://australia-southeast1-chronicle.googleapis.com |
northamerica-northeast2 | Canada — Montreal | https://northamerica-northeast2-chronicle.googleapis.com |
me-central1 | Middle East — Qatar | https://me-central1-chronicle.googleapis.com |
The location field is the GCP location used in the resource path (/v1/projects/{project}/locations/{location}/instances/{instance}). For most deployments location and region have the same value (e.g. eu), but some regions use a full GCP location name (e.g. europe-west2). Confirm the exact location string with your Google SecOps administrator.
How to Obtain a Service Account Key
Step 1 — Identify or create the service account
- Go to Google Cloud Console and select the GCP project that owns the Google SecOps instance.
- Navigate to IAM & Admin > Service Accounts.
- Either select an existing service account or click Create Service Account.
- Name: Use a descriptive name (e.g.
nina-chronicle-integration). - Description: e.g. "Service account for NINA Google SecOps Instances connector".
- Name: Use a descriptive name (e.g.
- Click Create and Continue.
Step 2 — Grant the required IAM role
The minimum IAM role required for read-only operations is Google SecOps API Viewer (roles/chronicle.viewer). For write operations (update config, delete instance, etc.) you need Google SecOps API Editor (roles/chronicle.editor).
| Use case | Recommended IAM role |
|---|---|
| Read-only (search, entity lookup, config read) | roles/chronicle.viewer |
| Full read + write (update config, lifecycle operations) | roles/chronicle.editor |
| All operations including destructive (delete, undelete, graduate) | roles/chronicle.editor or higher |
Important: Google SecOps IAM roles are granted at the GCP project level. Granting
chronicle.editorgives the service account editor access to all Google SecOps resources in that project.
Google SecOps-specific roles and their permissions are documented at: https://docs.cloud.google.com/iam/docs/roles-permissions/chronicle
To grant the role:
- In IAM & Admin > IAM, click Grant Access.
- Enter the service account email.
- Select the appropriate Google SecOps role.
- Click Save.
Step 3 — Create a JSON key
- Go to IAM & Admin > Service Accounts and click your service account.
- Open the Keys tab.
- Click Add Key > Create new key.
- Select JSON format.
- Click Create. The key file downloads automatically.
- Store the key file securely. Anyone with this file can authenticate as the service account.
The JSON key file looks like:
{
"type": "service_account",
"project_id": "your-gcp-project-id",
"private_key_id": "abc123...",
"private_key": "<the full private key from your key file, including its BEGIN/END PRIVATE KEY lines>",
"client_email": "[email protected]",
"client_id": "123456789",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "...",
"universe_domain": "googleapis.com"
}
Step 4 — Locate your Google SecOps instance details
The project, location, and instance values come from the Google SecOps instance resource name, which has the form:
projects/{project}/locations/{location}/instances/{instance}
You can find these in the Google SecOps UI:
- Navigate to Settings > Google SecOps API.
- The Customer ID shown in the UI is the
instanceUUID. - The Project ID is your GCP project ID.
- The Location is shown alongside the API endpoint URL.
Alternatively, the Google SecOps administrator who provisioned the instance can provide these values.
Creating a Google SecOps Instances Credential in NINA
- Navigate to the Credentials section in NINA.
- Click Add New Credential.
- Fill in the credential details:
- Integration Service: Select "Google SecOps Instances"
- Service Account JSON: Paste the entire content of the downloaded JSON key file
- Region: Select your Google SecOps deployment region
- Project: Enter your GCP project ID (e.g.
my-project-123) - Location: Enter the GCP location (e.g.
usoreu) - Instance: Enter the Google SecOps instance UUID (e.g.
fca7f167-b9d1-43b1-9d03-0257d31dcb63)
- Click Test Connection to verify the credentials are valid.
- Click Save to store the credential securely.
Note on the
logfield inextractSyslog: The Google SecOps API requires this field to be base64-encoded bytes. The connector automatically base64-encodes plain string values before sending, so you can pass raw log strings directly without encoding them yourself.
Rate Limits and Service Limits
Google SecOps enforces per-operation quotas. The most relevant limits are:
| Limit | Value |
|---|---|
udmSearch — queries per minute | 120 QPM |
udmSearch — max results per call | 10,000 events |
findEntity / entity operations | 60 QPM |
| General API calls | 600 QPM per project |
extractSyslog | 60 QPM |
For a full and up-to-date list of service limits, refer to: https://docs.cloud.google.com/chronicle/docs/reference/service-limits
The connector retries automatically on HTTP 429 (Too Many Requests) using exponential back-off (1 s, 2 s, 4 s, up to 3 retries).
Supported Operations
All operations belong to the single instance resource.
| Operation | Name | HTTP | API Version |
|---|---|---|---|
get | Get Instance | GET | v1 |
getBigQueryExport | Get BigQuery Export | GET | v1 |
getEnrichmentCombination | Get Enrichment Combination | GET | v1 |
getRiskConfig | Get Risk Config | GET | v1 |
getThreatCollectionFilterSet | Get Threat Collection Filter Set | GET | v1 |
listAllFindingsRefinementDeployments | List All Findings Refinement Deployments | GET | v1 |
udmSearch | UDM Search | GET | v1alpha |
validateQuery | Validate Query | GET | v1alpha |
findEntity | Find Entity | GET | v1alpha |
findEntityAlerts | Find Entity Alerts | GET | v1alpha |
findRelatedEntities | Find Related Entities | GET | v1alpha |
searchEntities | Search Entities | GET | v1alpha |
summarizeEntity | Summarize Entity | GET | v1alpha |
summarizeEntitiesFromQuery | Summarize Entities From Query | GET | v1alpha |
findUdmFieldValues | Find UDM Field Values | GET | v1alpha |
queryProductSourceStats | Query Product Source Stats | GET | v1alpha |
fetchFederationAccess | Fetch Federation Access | GET | v1alpha |
getAgentSettings | Get Agent Settings | GET | v1alpha |
getManagedDomainSettings | Get Managed Domain Settings | GET | v1alpha |
getMultitenantDirectory | Get Multitenant Directory | GET | v1alpha |
extractSyslog | Extract Syslog | POST | v1alpha |
computeAllFindingsRefinementActivities | Compute All Findings Refinement Activities | POST | v1alpha |
testFindingsRefinement | Test Findings Refinement | POST | v1alpha |
verifyRuleText | Verify Rule Text | POST | v1alpha |
verifyReferenceList | Verify Reference List | POST | v1alpha |
search | Search | POST | v1alpha |
searchRawLogs | Search Raw Logs | POST | v1alpha |
runThreatHunt | Run Threat Hunt | POST | v1alpha |
evaluateRuleCoverage | Evaluate Rule Coverage | POST | v1alpha |
countAllCuratedRuleSetDetections | Count All Curated Rule Set Detections | POST | v1alpha |
batchValidateWatchlistEntities | Batch Validate Watchlist Entities | POST | v1alpha |
generateCollectionAgentAuth | Generate Collection Agent Auth | POST | v1alpha |
generateUdmKeyValueMappings | Generate UDM Key-Value Mappings | POST | v1alpha |
generateRules | Generate Rules (AI) | POST | v1alpha |
suggestSql | Suggest SQL (AI) | POST | v1alpha |
translateUdmQuery | Translate UDM Query | POST | v1alpha |
translateYlRule | Translate YL Rule | POST | v1alpha |
generateSyntheticEvents | Generate Synthetic Events | POST | v1alpha |
submitResponseFeedback | Submit Response Feedback | POST | v1alpha |
createFeedback | Create Feedback | POST | v1alpha |
updateBigQueryExport | Update BigQuery Export | PATCH | v1 |
updateRiskConfig | Update Risk Config | PATCH | v1 |
patch | Update Instance | PATCH | v1alpha |
updateAgentSettings | Update Agent Settings | PATCH | v1alpha |
delete | Delete Instance | DELETE | v1alpha |
undelete | Undelete Instance | POST | v1alpha |
graduatePocInstance | Graduate PoC Instance | POST | v1alpha |
continuePocGraduation | Continue PoC Graduation | POST | v1alpha |
generateSoarAuthJwt | Generate SOAR Auth JWT | POST | v1alpha |
generateSoarChatMessage | Generate SOAR Chat Message | POST | v1alpha |
generateThreatDetectionOpportunity | Generate Threat Detection Opportunity | POST | v1alpha |
generateWorkspaceConnectionToken | Generate Workspace Connection Token | POST | v1alpha |
legacyCaseFederationPlatforms | Legacy Case Federation Platforms | POST | v1alpha |
legacySystemMetadata | Legacy System Metadata | POST | v1alpha |
verifyNonce | Verify Nonce | POST | v1alpha |
Operation Details
get
Retrieve metadata and configuration details for the Google SecOps instance.
HTTP: GET /v1/projects/{project}/locations/{location}/instances/{instance}
No parameters required.
Example:
{}
getBigQueryExport
Retrieve the BigQuery export configuration for the instance.
HTTP: GET /v1/projects/{project}/locations/{location}/instances/{instance}/bigQueryExport
Note: Returns HTTP 400
FAILED_PRECONDITIONif BigQuery export has never been enabled for the instance.
No parameters required.
Example:
{}
getEnrichmentCombination
Retrieve the enrichment combination settings for the instance.
HTTP: GET /v1/projects/{project}/locations/{location}/instances/{instance}/enrichmentCombination
No parameters required.
Example:
{}
getRiskConfig
Retrieve the risk scoring configuration for the instance.
HTTP: GET /v1/projects/{project}/locations/{location}/instances/{instance}/riskConfig
No parameters required.
Example:
{}
getThreatCollectionFilterSet
Retrieve the threat collection filter set applied to the instance.
HTTP: GET /v1/projects/{project}/locations/{location}/instances/{instance}/threatCollectionFilterSet
Note: Requires the service account to have explicit permission on the threat collection feature. Returns HTTP 403
PERMISSION_DENIEDif the service account does not have access.
No parameters required.
Example:
{}
listAllFindingsRefinementDeployments
List all findings refinement deployments active on the instance.
HTTP: GET /v1/projects/{project}/locations/{location}/instances/{instance}:listAllFindingsRefinementDeployments
No parameters required.
Example:
{}
udmSearch
Search Unified Data Model (UDM) events within the Google SecOps instance using a UDM query. All parameters are sent as query string parameters.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:udmSearch
Important: Time range parameters use proto dot-notation in the query string (e.g.
timeRange.startTime=2024-01-01T00:00:00Z). The connector handles this encoding automatically — pass them as flat keys with the dot-notation names shown below.
Important: The
timeRangemust fall within the instance's data retention window. Queries outside the retention window return HTTP 400OUT_OF_RANGE.
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | UDM search query string (YARA-L 2.0 boolean syntax, e.g. metadata.event_type = "NETWORK_CONNECTION"). |
timeRange.startTime | string | No | Start of the time range in RFC3339 format (e.g. 2024-01-01T00:00:00Z). |
timeRange.endTime | string | No | End of the time range in RFC3339 format. |
limit | number | No | Maximum number of events to return. Default 100, max 10000. |
Example:
{
"query": "metadata.event_type = \"NETWORK_CONNECTION\"",
"timeRange.startTime": "2024-06-01T00:00:00Z",
"timeRange.endTime": "2024-06-02T00:00:00Z",
"limit": 50
}
validateQuery
Validate a UDM query string without executing it. Returns parse and semantic errors if the query is malformed.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:validateQuery
| Name | Type | Required | Description |
|---|---|---|---|
rawQuery | string | Yes | UDM query string to validate. |
Example:
{
"rawQuery": "metadata.event_type = \"NETWORK_CONNECTION\""
}
findEntity
Find a security entity by indicator value and UDM field. All four parameters are required.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:findEntity
| Name | Type | Required | Description |
|---|---|---|---|
indicator | string | Yes | The entity indicator value (e.g. 8.8.8.8, malicious.example.com, a SHA256 hash, or a username). |
udmField | string | Yes | The UDM field path the indicator belongs to (e.g. principal.ip, target.hostname, principal.user.userid). |
entityNamespace | string | Yes | Namespace of the entity (use default if no custom namespace is configured). |
referenceTime | string | Yes | Reference point in time for the entity context, in RFC3339 format (e.g. 2024-01-01T00:00:00Z). |
Example:
{
"indicator": "8.8.8.8",
"udmField": "principal.ip",
"entityNamespace": "default",
"referenceTime": "2024-06-01T00:00:00Z"
}
findEntityAlerts
Find security alerts related to a given entity within a time range. Use entityId to scope to a specific entity — without it, all alerts in the time window are returned.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:findEntityAlerts
Note:
entityIdis an opaque ID returned byfindEntityorsearchEntities. ThefieldAndValueunion field (documented in the raw API) cannot be passed as query parameters and is therefore not exposed in this connector.
| Name | Type | Required | Description |
|---|---|---|---|
timeRange.startTime | string | Yes | Start of the time range (RFC3339). |
timeRange.endTime | string | Yes | End of the time range (RFC3339). |
entityId | string | No | Opaque entity ID to scope results to a specific entity. Obtain from findEntity or searchEntities. |
Example:
{
"timeRange.startTime": "2024-06-01T00:00:00Z",
"timeRange.endTime": "2024-06-02T00:00:00Z",
"entityId": "<entity-id-from-findEntity>"
}
findRelatedEntities
Find entities related to a given entity based on observed connections in UDM event data.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:findRelatedEntities
| Name | Type | Required | Description |
|---|---|---|---|
timeRange.startTime | string | Yes | Start of the time range (RFC3339). |
timeRange.endTime | string | Yes | End of the time range (RFC3339). |
entityId | string | No | Opaque ID of the source entity. Obtain from findEntity or searchEntities. |
limit | number | No | Maximum number of related entities to return (max 100). |
Example:
{
"timeRange.startTime": "2024-06-01T00:00:00Z",
"timeRange.endTime": "2024-06-02T00:00:00Z",
"entityId": "<entity-id>",
"limit": 50
}
searchEntities
Search for entities across the Google SecOps instance by indicator value.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:searchEntities
| Name | Type | Required | Description |
|---|---|---|---|
indicator | string | Yes | Indicator value to search for (partial match supported, e.g. 8.8.8 matches 8.8.8.8). |
Example:
{
"indicator": "8.8.8.8"
}
summarizeEntity
Get a rich summary of a single entity including associated events, alerts, first/last seen times, and metadata.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:summarizeEntity
Note:
entityIdis required by the API to scope the summary to a specific entity. Without it the call returns HTTP 400INVALID_ARGUMENT. Obtain the entity ID fromfindEntityorsearchEntitiesfirst.
| Name | Type | Required | Description |
|---|---|---|---|
timeRange.startTime | string | Yes | Start of the summary time range (RFC3339). |
timeRange.endTime | string | Yes | End of the summary time range (RFC3339). |
entityId | string | No* | Opaque entity ID. Required in practice — the API returns an error without it. |
returnPrevalence | boolean | No | Set to true to include prevalence data in the response. |
returnAlerts | boolean | No | Set to true to include alert counts in the response. |
Example:
{
"timeRange.startTime": "2024-06-01T00:00:00Z",
"timeRange.endTime": "2024-06-02T00:00:00Z",
"entityId": "<entity-id-from-findEntity>",
"returnPrevalence": true,
"returnAlerts": true
}
summarizeEntitiesFromQuery
Summarize all entities that appear in the results of a UDM search query.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:summarizeEntitiesFromQuery
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | UDM query whose matching events' entities will be summarized. |
timeRange.startTime | string | Yes | Start of the time range (RFC3339). |
timeRange.endTime | string | Yes | End of the time range (RFC3339). |
Example:
{
"query": "metadata.event_type = \"NETWORK_CONNECTION\"",
"timeRange.startTime": "2024-06-01T00:00:00Z",
"timeRange.endTime": "2024-06-02T00:00:00Z"
}
findUdmFieldValues
Find distinct values for a UDM field or autocomplete partial values. Useful for building dynamic filter dropdowns.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:findUdmFieldValues
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Partial value to match against a UDM field (e.g. workstation returns all hostnames containing workstation). |
limit | number | No | Maximum number of values to return. Default 250, max 1000. |
Example:
{
"query": "workstation",
"limit": 100
}
queryProductSourceStats
Query ingestion statistics broken down by product source for the instance. Returns counts of events ingested per log source.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:queryProductSourceStats
| Name | Type | Required | Description |
|---|---|---|---|
timeRange.startTime | string | No | Start of the time range (RFC3339). If omitted, returns all retained log stats. |
timeRange.endTime | string | No | End of the time range (RFC3339). |
Example:
{
"timeRange.startTime": "2024-06-01T00:00:00Z",
"timeRange.endTime": "2024-06-02T00:00:00Z"
}
fetchFederationAccess
Fetch the federation access configuration for the instance.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:fetchFederationAccess
No parameters required.
Example:
{}
getAgentSettings
Retrieve agent settings for the Google SecOps instance.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:getAgentSettings
No parameters required.
Example:
{}
getManagedDomainSettings
Retrieve managed domain settings for the instance.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:getManagedDomainSettings
No parameters required.
Example:
{}
getMultitenantDirectory
Retrieve multitenant directory information for the instance.
HTTP: GET /v1alpha/projects/{project}/locations/{location}/instances/{instance}:getMultitenantDirectory
No parameters required.
Example:
{}
extractSyslog
Parse and extract structured fields from a raw log message using the Google SecOps parser.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:extractSyslog
Important: The Google SecOps API requires the
logfield to be base64-encoded bytes (TYPE_BYTES). The connector automatically base64-encodes plain string values — you do not need to encode the log yourself.
Note: The
preprocessConfigfield contains GROK-style extraction rules specific to your Google SecOps parser configuration. Contact your Google SecOps administrator to obtain the correctpreprocessConfigstructure for your log type.
| Name | Type | Required | Description |
|---|---|---|---|
log | string | Yes | Raw log message. Plain strings are automatically base64-encoded by the connector before sending. |
preprocessConfig | object | No | Pre-processing configuration (GROK-style extraction rules). Required by many Google SecOps parsers. |
Example:
{
"log": "Jan 1 00:00:00 host sshd[1234]: Accepted password for user from 1.2.3.4 port 22 ssh2"
}
computeAllFindingsRefinementActivities
Compute statistics and activity metrics for all findings refinement rules deployed on the instance.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:computeAllFindingsRefinementActivities
| Name | Type | Required | Description |
|---|---|---|---|
interval | object | Yes | Time interval for activity measurement. |
interval.startTime | string | Yes | Start of the interval in RFC3339 format. |
interval.endTime | string | Yes | End of the interval in RFC3339 format. |
Example:
{
"interval": {
"startTime": "2024-06-01T00:00:00Z",
"endTime": "2024-06-02T00:00:00Z"
}
}
testFindingsRefinement
Evaluate a findings refinement rule against recent data without saving or deploying it. Use this to preview the impact of a rule before deployment.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:testFindingsRefinement
| Name | Type | Required | Description |
|---|---|---|---|
rule | string | Yes | YARA-L 2.0 findings refinement rule text to test. |
Example:
{
"rule": "rule test_refinement {\n meta:\n author = \"analyst\"\n events:\n $e.metadata.event_type = \"NETWORK_CONNECTION\"\n condition:\n $e\n}"
}
verifyRuleText
Validate YARA-L 2.0 detection rule text for syntax and semantic correctness. Returns detailed parse errors if the rule is invalid.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:verifyRuleText
| Name | Type | Required | Description |
|---|---|---|---|
ruleText | string | Yes | The YARA-L 2.0 rule text to verify. |
Example:
{
"ruleText": "rule detect_lateral_movement {\n meta:\n author = \"analyst\"\n events:\n $e.metadata.event_type = \"NETWORK_CONNECTION\"\n $e.principal.ip = /10\\.0\\.0\\..*/\n condition:\n $e\n}"
}
verifyReferenceList
Verify that a reference list is syntactically valid before creating or updating it in Google SecOps.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:verifyReferenceList
| Name | Type | Required | Description |
|---|---|---|---|
syntaxType | string | Yes | Syntax type of the entries. One of: REFERENCE_LIST_SYNTAX_TYPE_PLAIN_TEXT_STRING, REFERENCE_LIST_SYNTAX_TYPE_REGEX, REFERENCE_LIST_SYNTAX_TYPE_CIDR. |
entries | array | Yes | Array of entry objects, each with a value string field (e.g. [{"value": "192.168.1.0/24"}]). |
Example:
{
"syntaxType": "REFERENCE_LIST_SYNTAX_TYPE_CIDR",
"entries": [
{"value": "192.168.1.0/24"},
{"value": "10.0.0.0/8"},
{"value": "172.16.0.0/12"}
]
}
search
Search across the Google SecOps instance using a general query.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:search
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query string. |
Example:
{
"query": "lateral movement"
}
searchRawLogs
Search raw log data ingested into the Google SecOps instance before UDM normalization.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:searchRawLogs
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Raw log search query string. |
timeRange | object | No | Time range for the search. |
timeRange.startTime | string | No | Start time (RFC3339). |
timeRange.endTime | string | No | End time (RFC3339). |
Example:
{
"query": "failed login",
"timeRange": {
"startTime": "2024-06-01T00:00:00Z",
"endTime": "2024-06-02T00:00:00Z"
}
}
runThreatHunt
Run a retroactive threat hunt using a YARA-L detection rule across historical event data.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:runThreatHunt
| Name | Type | Required | Description |
|---|---|---|---|
ruleText | string | No | YARA-L 2.0 rule text to use for the hunt. |
startTime | string | No | Start of the hunt time range (RFC3339). |
endTime | string | No | End of the hunt time range (RFC3339). |
Example:
{
"ruleText": "rule hunt_suspicious_outbound {\n events:\n $e.metadata.event_type = \"NETWORK_CONNECTION\"\n $e.principal.ip = /10\\.0\\.0\\..*/\n $e.target.port = 443\n condition:\n $e\n}",
"startTime": "2024-06-01T00:00:00Z",
"endTime": "2024-06-07T00:00:00Z"
}
evaluateRuleCoverage
Evaluate the detection coverage of all rules deployed on the instance.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:evaluateRuleCoverage
No parameters required.
Example:
{}
countAllCuratedRuleSetDetections
Count all detections produced by Google SecOps's curated (managed) rule sets on the instance.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:countAllCuratedRuleSetDetections
No parameters required.
Example:
{}
batchValidateWatchlistEntities
Validate a batch of watchlist entity entries before adding them to a watchlist.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:batchValidateWatchlistEntities
| Name | Type | Required | Description |
|---|---|---|---|
entities | array | Yes | List of watchlist entity entries to validate. |
Example:
{
"entities": [
{"value": "[email protected]"},
{"value": "192.168.100.50"}
]
}
generateCollectionAgentAuth
Generate an authentication token for a Google SecOps collection agent.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateCollectionAgentAuth
No parameters required.
Example:
{}
generateUdmKeyValueMappings
Generate UDM key-value mappings for log normalization.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateUdmKeyValueMappings
| Name | Type | Required | Description |
|---|---|---|---|
logType | string | No | Log type identifier for which to generate mappings (e.g. WINDOWS_SYSMON). |
Example:
{
"logType": "WINDOWS_SYSMON"
}
generateRules
Use Google SecOps's AI to auto-generate YARA-L 2.0 detection rules from a natural language description.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateRules
Note: Requires AI features to be enabled on the Google SecOps instance. Contact your Google SecOps administrator if this operation returns an error.
| Name | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Natural language description of the detection logic to generate (e.g. "detect brute force login attempts from external IPs"). |
Example:
{
"prompt": "detect brute force login attempts — more than 5 failed authentication events from the same IP within 5 minutes"
}
suggestSql
Use Google SecOps's AI to suggest a SQL query based on a natural language description.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:suggestSql
Note: Requires AI features to be enabled on the Google SecOps instance.
| Name | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Natural language description of the data to query. |
Example:
{
"prompt": "Show me all network connections from internal hosts to port 443 in the last 24 hours"
}
translateUdmQuery
Translate a UDM query into an alternative format or dialect.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:translateUdmQuery
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The UDM query string to translate. |
Example:
{
"query": "metadata.event_type = \"NETWORK_CONNECTION\" AND principal.ip = \"10.0.0.1\""
}
translateYlRule
Translate a YARA-L rule to an alternative format.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:translateYlRule
| Name | Type | Required | Description |
|---|---|---|---|
ruleText | string | Yes | The YARA-L rule text to translate. |
Example:
{
"ruleText": "rule example {\n events:\n $e.metadata.event_type = \"NETWORK_CONNECTION\"\n condition:\n $e\n}"
}
generateSyntheticEvents
Generate synthetic UDM test events that match a given detection rule. Useful for testing rules without requiring real data.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateSyntheticEvents
| Name | Type | Required | Description |
|---|---|---|---|
ruleText | string | No | YARA-L rule text for which to generate matching synthetic events. |
Example:
{
"ruleText": "rule detect_network {\n events:\n $e.metadata.event_type = \"NETWORK_CONNECTION\"\n condition:\n $e\n}"
}
submitResponseFeedback
Submit user feedback on a Google SecOps AI-generated response (e.g. rating a generated rule or SQL suggestion).
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:submitResponseFeedback
| Name | Type | Required | Description |
|---|---|---|---|
feedback | object | Yes | Feedback payload. Structure depends on the Google SecOps AI feature being rated. |
Example:
{
"feedback": {
"rating": "POSITIVE",
"comment": "The generated rule was accurate"
}
}
createFeedback
Create a general feedback entry for a Google SecOps feature or response.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:createFeedback
| Name | Type | Required | Description |
|---|---|---|---|
feedback | object | Yes | Feedback object to create. |
Example:
{
"feedback": {
"type": "FEATURE_REQUEST",
"description": "Additional UDM field support in queries"
}
}
updateBigQueryExport
Update the BigQuery export configuration for the instance.
HTTP: PATCH /v1/projects/{project}/locations/{location}/instances/{instance}/bigQueryExport
Warning: Mutating operation. Requires
chronicle.editorIAM role. Not tested against live infrastructure.
| Name | Type | Required | Description |
|---|---|---|---|
exportDatasetUri | string | No | BigQuery dataset URI to export data to (e.g. bq://my-project.my_dataset). |
enabled | boolean | No | Whether BigQuery export is enabled. |
Example:
{
"exportDatasetUri": "bq://my-project.chronicle_export",
"enabled": true
}
updateRiskConfig
Update the risk scoring configuration for the instance.
HTTP: PATCH /v1/projects/{project}/locations/{location}/instances/{instance}/riskConfig
Warning: Mutating operation. Requires
chronicle.editorIAM role.
| Name | Type | Required | Description |
|---|---|---|---|
riskConfig | object | Yes | Risk configuration fields to update. Refer to the Google SecOps API reference for the full RiskConfig schema. |
Example:
{
"riskConfig": {
"enabled": true
}
}
patch
Update instance-level configuration fields.
HTTP: PATCH /v1alpha/projects/{project}/locations/{location}/instances/{instance}
Warning: Mutating operation. Requires
chronicle.editorIAM role.
| Name | Type | Required | Description |
|---|---|---|---|
updateMask | string | No | Comma-separated list of fields to update using proto field mask syntax (e.g. displayName,description). If omitted, all provided fields are updated. |
Example:
{
"displayName": "Production Google SecOps Instance",
"updateMask": "displayName"
}
updateAgentSettings
Update agent settings for the Google SecOps instance.
HTTP: PATCH /v1alpha/projects/{project}/locations/{location}/instances/{instance}:updateAgentSettings
Warning: Mutating operation. Requires
chronicle.editorIAM role.
| Name | Type | Required | Description |
|---|---|---|---|
agentSettings | object | Yes | Agent settings fields to update. Refer to the Google SecOps API reference for the AgentSettings schema. |
Example:
{
"agentSettings": {}
}
delete
Delete a Google SecOps instance. This is a destructive, irreversible operation.
HTTP: DELETE /v1alpha/projects/{project}/locations/{location}/instances/{instance}
Warning: Destructive operation. Requires
chronicle.editoror higher IAM role. The instance can be restored within the recovery window usingundelete.
No parameters required.
Example:
{}
undelete
Restore a previously deleted Google SecOps instance within the recovery window.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:undelete
Warning: Mutating operation. Only works within the deletion recovery window.
No parameters required.
Example:
{}
graduatePocInstance
Graduate a proof-of-concept Google SecOps instance to a production instance.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:graduatePocInstance
Warning: Mutating lifecycle operation. Irreversible — once graduated, the instance cannot be converted back to PoC.
No parameters required.
Example:
{}
continuePocGraduation
Continue a previously initiated PoC graduation process (e.g. after resolving a prerequisite failure).
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:continuePocGraduation
No parameters required.
Example:
{}
generateSoarAuthJwt
Generate a SOAR authentication JWT token for the instance, used by SOAR integrations to authenticate against Google SecOps.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateSoarAuthJwt
No parameters required.
Example:
{}
generateSoarChatMessage
Generate a SOAR chat message for the instance.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateSoarChatMessage
| Name | Type | Required | Description |
|---|---|---|---|
message | string | No | Chat message content. |
Example:
{
"message": "Summarize recent high-severity detections"
}
generateThreatDetectionOpportunity
Generate threat detection opportunities for the instance based on current data and rule coverage.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateThreatDetectionOpportunity
No parameters required.
Example:
{}
generateWorkspaceConnectionToken
Generate a token for connecting a Google Workspace tenant to the Google SecOps instance.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:generateWorkspaceConnectionToken
No parameters required.
Example:
{}
legacyCaseFederationPlatforms
Legacy endpoint for case federation platform management. Use only when required for backward compatibility.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:legacyCaseFederationPlatforms
No parameters required.
Example:
{}
legacySystemMetadata
Legacy endpoint for system metadata operations. Use only when required for backward compatibility.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:legacySystemMetadata
No parameters required.
Example:
{}
verifyNonce
Verify a nonce value for the Google SecOps instance, used in security handshake flows.
HTTP: POST /v1alpha/projects/{project}/locations/{location}/instances/{instance}:verifyNonce
| Name | Type | Required | Description |
|---|---|---|---|
nonce | string | Yes | The nonce value to verify. |
Example:
{
"nonce": "<nonce-value>"
}
Common Workflows
Investigate an IP address
- Use
findEntitywithindicator=<ip>,udmField=principal.ip,entityNamespace=default, and areferenceTimeto retrieve the entity ID. - Use
summarizeEntitywith the returnedentityIdto get a full summary including first/last seen, event counts, and alerts. - Use
findEntityAlertswith theentityIdto retrieve associated alerts. - Use
findRelatedEntitieswith theentityIdto see other entities the IP has communicated with.
Validate and deploy a detection rule
- Write the YARA-L 2.0 rule text.
- Use
verifyRuleTextto check for syntax errors — fix any reported errors before proceeding. - Use
testFindingsRefinement(if it is a findings refinement rule) to preview its impact. - Use
generateSyntheticEventsto generate test events that match the rule for QA. - Deploy the rule through the Google SecOps UI or Detections API (out of scope for this connector).
Check ingestion health
- Use
queryProductSourceStatswith a time range to see event counts per log source. - Use
getto retrieve overall instance status. - Use
evaluateRuleCoverageto assess which MITRE ATT&CK techniques are covered by deployed rules.
Best Practices
-
Use specific time ranges: All time-based operations require the range to fall within the instance's data retention window. Google SecOps typically retains data for 12 months. Queries outside this window return
OUT_OF_RANGE(HTTP 400). -
Obtain entity IDs before entity operations:
findEntityAlerts,findRelatedEntities, andsummarizeEntityall work best with anentityId. CallfindEntityorsearchEntitiesfirst to obtain a valid ID. -
Use
validateQuerybeforeudmSearch: Validate query syntax before executing searches to avoid runtime errors and wasted quota. -
Respect rate limits: Google SecOps enforces per-operation QPM limits. For bulk searches, add delays between calls or use the
limitparameter to keep individual response sizes small. -
Minimise IAM scope: Grant
chronicle.viewerfor read-only workflows. Only grantchronicle.editorif the workflow needs to update configuration or perform lifecycle operations. -
Rotate service account keys: Google recommends rotating service account keys every 90 days. Create a new key, update the credential in NINA, then delete the old key.
-
Use
verifyReferenceListbefore creating lists: Validate syntax (CIDR,REGEX, etc.) before submitting lists to Google SecOps to avoid ingestion errors. -
Handle
FAILED_PRECONDITIONgracefully: Some operations (getBigQueryExport) return this error when the feature is not enabled for the instance. Treat it as a skip condition, not a failure.
Troubleshooting
| Error | HTTP Status | Cause | Solution |
|---|---|---|---|
UNAUTHENTICATED | 401 | Invalid or expired service account key | Verify the JSON key content; check that the key has not been deleted in GCP; re-generate if necessary |
PERMISSION_DENIED | 403 | Service account lacks the required Google SecOps IAM role | Grant roles/chronicle.viewer or roles/chronicle.editor on the GCP project |
NOT_FOUND | 404 | Wrong project, location, instance ID, or API version | Verify all four credential fields; confirm the instance UUID with your Google SecOps administrator |
INVALID_ARGUMENT | 400 | Missing required parameter or wrong field name | Check the operation's parameter table; ensure entityId is provided for entity operations that require it |
FAILED_PRECONDITION | 400 | Feature not enabled (e.g. BigQuery export not provisioned) | Contact your Google SecOps administrator to enable the feature |
OUT_OF_RANGE | 400 | Time range falls outside data retention window | Use a time range within the last 12 months (or your configured retention period) |
RESOURCE_EXHAUSTED / 429 | 429 | Rate limit exceeded | The connector retries automatically up to 3 times with exponential back-off; reduce call frequency if persistent |
INTERNAL | 500 | Google SecOps-side error | Retry after a short delay; contact Google SecOps support if persistent |
| Token acquisition failed | — | Service account JSON is malformed or private key is corrupted | Re-download the JSON key from GCP Console; ensure the entire file content is pasted (including newlines inside the private key, represented as \n in JSON) |
Verifying credentials manually
To confirm the service account JSON is valid and the credentials allow token acquisition, run from the repository root:
go run - <<'EOF'
package main
import (
"context"
"fmt"
"os"
"golang.org/x/oauth2/google"
)
func main() {
json := os.Getenv("CHRONICLE_SERVICE_ACCOUNT_JSON")
cfg, err := google.JWTConfigFromJSON([]byte(json), "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
fmt.Printf("ERROR: %v\n", err)
os.Exit(1)
}
fmt.Printf("Service account email: %s\n", cfg.Email)
tok, err := cfg.TokenSource(context.Background()).Token()
if err != nil {
fmt.Printf("ERROR: %v\n", err)
os.Exit(1)
}
fmt.Printf("Token acquired, expires: %s\n", tok.Expiry.Format("15:04:05"))
}
EOF
Running integration tests
export CHRONICLE_SERVICE_ACCOUNT_JSON=$(cat /path/to/sa-key.json)
export CHRONICLE_REGION=eu
export CHRONICLE_PROJECT=your-gcp-project-id
export CHRONICLE_LOCATION=eu
export CHRONICLE_INSTANCE=your-instance-uuid
go test -v -count=1 -timeout 120s ./internal/integrations/chronicle-instances/...
Generating an evidence report
./scripts/generate-evidence.sh chronicle-instances
The report is written to evidence/chronicle-instances/<date>-chronicle-instances-report.md.
Support
For issues with this integration, provide the following information when contacting support:
- The operation name (e.g.
udmSearch) - The full error message and HTTP status code
- The Google SecOps region, project, and instance UUID (never share private keys or the full JSON)
- Whether
ValidateCredentialssucceeds
For Google SecOps API documentation:
- Google SecOps REST API Reference
- Google SecOps API Permissions and Roles
- Google SecOps Service Limits
Updated: 2026-07-07