# Google SecOps (Chronicle) Forwards processed logs to Google Security Operations (Chronicle) via the [v1 `logs:import` ingestion API](https://cloud.google.com/chronicle/docs/reference/ingestion-methods). ## Requirements - A Google Cloud project with a [Chronicle (SecOps) instance](https://cloud.google.com/chronicle/docs). - A GCP service account with the **`chronicle.logs.import`** IAM permission on the Chronicle instance. - A JSON key for that service account. - Network access to `chronicle.{region}.rep.googleapis.com`. ## Create a service account 1. In the **Google Cloud Console**, go to **IAM & Admin → Service Accounts**. 2. Click **Create Service Account**. Name it something like `monad-chronicle-writer`. 3. Grant it the **Chronicle API Log Import** role (or a custom role containing `chronicle.logs.import`). 4. Under the service account's **Keys** tab, click **Add Key → Create new key → JSON**. Download and save the key file — you'll paste its contents into Monad. ## Find your Chronicle instance details 1. Open the **SecOps console** (`https://{customer}.backstory.chronicle.security`). 2. Your **Instance ID** (Customer ID) is the GUID shown in **Settings → SIEM Settings → Instance ID**. 3. Your **GCP Project ID** is the project that hosts the instance. 4. Your **Region** is the Chronicle regional endpoint you were provisioned in (e.g. `us`, `europe`, `asia-southeast1`). 5. Your **Log Type** is the Chronicle log type for the data you're sending (e.g. `WINDOWS_DHCP`, `OKTA`, `CORELIGHT`). See [Chronicle's supported log types](https://cloud.google.com/chronicle/docs/ingestion/data-types). ## Details - **Endpoint:** `POST https://chronicle.{region}.rep.googleapis.com/v1/projects/{project}/locations/{region}/instances/{instance}/logTypes/{log_type}/logs:import` - **Auth:** OAuth2 with the service account's JWT credentials, scope `https://www.googleapis.com/auth/cloud-platform`. - **Payload:** JSON body with `inlineSource.logs[]`, each event base64-encoded in the `data` field. - **Timestamps:** `logEntryTime` and `collectionTime` are extracted from each event via configurable JSON paths. If the path is missing or the value is unparseable, the current time is used. - **Compression:** optional gzip (`Content-Encoding: gzip`), off by default. - **Batching:** up to 500 records or 2 MiB per request by default, flushed every 30 seconds. Chronicle enforces a 4 MB uncompressed body limit. - **Retries:** exponential backoff, up to 4 attempts per batch. ## Configuration #### Settings | Setting | Type | Required | Description | |---------|------|----------|-------------| | GCP Project ID | string | Yes | Google Cloud project ID that hosts the Chronicle instance. | | Region | string | Yes | Chronicle regional endpoint (e.g. `us`, `europe`, `asia-southeast1`). Used for both the hostname and the API path. Defaults to `us`. | | Instance ID | string | Yes | Chronicle instance identifier (Customer ID / GUID from the SecOps console). | | Log Type | string | Yes | Chronicle log type for every batch (e.g. `WINDOWS_DHCP`, `OKTA`, `CORELIGHT`). | | Log Entry Time Field | JSON path | Yes | JSON path to the event timestamp used as Chronicle's `logEntryTime`. Falls back to now if missing or unparseable. | | Collection Time Field | JSON path | Yes | JSON path to the collection timestamp used as Chronicle's `collectionTime`. Falls back to now if missing or unparseable. | | Environment Namespace | string | No | Static `environmentNamespace` tag applied to every log for data-domain partitioning. | | Forwarder Resource Name | string | No | Optional forwarder resource name (`projects/

/locations//instances//forwarders/`). | | Endpoint Override | URL | No | Full URL to send to instead of the region-based default. Use for Private Service Connect or test environments. | | Compress Request | boolean | No | Gzip the request body. Reduces egress at the cost of CPU. Off by default. | | Batch Config | object | No | Override batch record count (1–1000), batch data size (1 KiB–4 MiB), and flush interval (1–300 s). | #### Secrets | Secret | Type | Required | Description | |--------|------|----------|-------------| | Service Account Credentials JSON | string | Yes | JSON key for a GCP service account with the `chronicle.logs.import` IAM permission. Raw JSON or base64-encoded JSON both accepted. | ## Verifying data in Chronicle - **Search** — open the Chronicle Search page and run a query filtered to your log type and time range. - **Data Ingestion & Health** — under **Settings → SIEM Settings → Data Feeds**, check ingestion status and error rates. - **Raw Log Scan** — run a raw log scan for the log type to confirm events are landing. ## Troubleshooting | Symptom | Likely cause | |---------|--------------| | `401 Unauthorized` | Service account key is invalid or expired. Regenerate the key in GCP Console. | | `403 Forbidden` | Service account lacks the `chronicle.logs.import` permission on the instance. | | `404 Not Found` | Wrong project, region, instance ID, or log type in the endpoint path. | | `400 INVALID_ARGUMENT` | Malformed request body — check that the log type string matches a Chronicle-supported type. | | Timestamps showing as ingestion time | The JSON path for `logEntryTime` or `collectionTime` doesn't match a field in your events, or the value isn't parseable as a timestamp. | | `413 Payload Too Large` | Batch exceeds Chronicle's 4 MB limit. Lower the batch data size setting. |