> ## Documentation Index
> Fetch the complete documentation index at: https://www.osohq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SIEM export

> Stream Oso for Agents alerts and events to your own S3 bucket for ingestion into your SIEM.

Oso for Agents can continuously deliver your alerts and events to a storage location you own, so your security team can investigate them in the SIEM you already use. Export delivers to an **Amazon S3 bucket** (or any S3-compatible object store) as gzipped JSON.

## What gets exported

An export destination is scoped to one **record source**:

* **Alerts** — the alerts Oso raises, enriched with the policy decision and approval outcome behind each one.
* **Events** — the raw agent activity Oso ingests (tool calls, messages, responses).

Configure a separate destination for each source you want to export.

## How it works

Oso writes each new record to your bucket as its own gzipped JSON object:

* **Key:** `<prefix>/<environment>/<alert|event>/<record-id>.json.gz` — you choose the key **prefix** (required); `<environment>` is your Oso environment id and `<alert|event>` is the record source.
* **Headers:** `Content-Type: application/json` and `Content-Encoding: gzip`.

Delivery is at-least-once, and each object is keyed by its record id — so a redelivery overwrites the same object in place (idempotent) rather than creating a duplicate.

## Record schema

Every object is a flat JSON envelope of the record's own fields, tagged with `record_type` (`alert` or `event`), with the record's full detail nested under `data`. Fields marked optional are omitted when empty.

### Alert record

An **alert** is a deduplicated detection — its `count` is how many times it fired.

| Field         | Always present | Description                                                                                                                       |
| ------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `record_type` | yes            | Literal `"alert"`.                                                                                                                |
| `id`          | yes            | Alert id.                                                                                                                         |
| `environment` | yes            | Your Oso environment id.                                                                                                          |
| `timestamp`   | yes            | RFC 3339 UTC.                                                                                                                     |
| `type`        | yes            | Alert type (for example `content`).                                                                                               |
| `severity`    | yes            | Alert severity.                                                                                                                   |
| `status`      | yes            | Alert status (for example `open`).                                                                                                |
| `title`       | yes            | Short title.                                                                                                                      |
| `description` | yes            | Human-readable description.                                                                                                       |
| `count`       | yes            | Occurrences deduplicated into this alert.                                                                                         |
| `users`       | yes            | The authorizing identities the activity ran as.                                                                                   |
| `data`        | yes            | The alert's detection detail; shape varies by `type`.                                                                             |
| `agent_id`    | optional       | Agent the activity ran as.                                                                                                        |
| `session_id`  | optional       | Session the alert belongs to.                                                                                                     |
| `event_id`    | optional       | The originating event.                                                                                                            |
| `trigger_id`  | optional       | The rule that fired.                                                                                                              |
| `device_id`   | optional       | Endpoint device, when known.                                                                                                      |
| `enrichment`  | optional       | Derived context, present when available: `policy` (`enforce_kind`, `policy_ids`) and `approval` (`status`, `by`, `at`, `reason`). |

```json Alert theme={null}
{
  "record_type": "alert",
  "id": "8f3b6c2e-1d4a-4e7b-9c11-2a5f0e9d7a10",
  "environment": "env_3xK9Wb2",
  "timestamp": "2026-08-10T14:12:06Z",
  "type": "content",
  "severity": "critical",
  "status": "open",
  "title": "Sensitive content detected",
  "description": "matched a custom content pattern",
  "count": 3,
  "users": [{ "type": "User", "id": "alice@example.com" }],
  "agent_id": "claude-cli",
  "session_id": "session-1a2b3c",
  "event_id": "b71e2f44-0c3d-4a9e-8f21-6d0b5c4e3a92",
  "trigger_id": "d0c9a1b2-3e4f-5a6b-7c8d-9e0f1a2b3c4d",
  "device_id": "device-0099",
  "data": { "entity": { "key": "email" } },
  "enrichment": {
    "policy": { "enforce_kind": "monitor", "policy_ids": ["pol_01H9Z"] },
    "approval": { "status": "approved", "by": "manager@example.com", "at": "2026-08-10T14:12:59Z", "reason": "reviewed" }
  }
}
```

### Event record

An **event** is a single raw agent activity — the firehose you correlate in your SIEM. For a `tool.request` event, `data` is the tool call itself, including its parameters.

| Field          | Always present | Description                                                                                                 |
| -------------- | -------------- | ----------------------------------------------------------------------------------------------------------- |
| `record_type`  | yes            | Literal `"event"`.                                                                                          |
| `id`           | yes            | Event id.                                                                                                   |
| `environment`  | yes            | Your Oso environment id.                                                                                    |
| `timestamp`    | yes            | RFC 3339 UTC.                                                                                               |
| `type`         | yes            | Event type (for example `tool.request`).                                                                    |
| `agent_id`     | yes            | Agent the activity ran as.                                                                                  |
| `session_id`   | yes            | Session the event belongs to.                                                                               |
| `users`        | yes            | The authorizing identities the activity ran as.                                                             |
| `data`         | yes            | The full event payload; shape varies by `type`. A `tool.request` carries `tool_name` and `tool_parameters`. |
| `device_id`    | optional       | Endpoint device, when known.                                                                                |
| `enforce_kind` | optional       | How the event was enforced (for example `monitor`).                                                         |

```json Event theme={null}
{
  "record_type": "event",
  "id": "b71e2f44-0c3d-4a9e-8f21-6d0b5c4e3a92",
  "environment": "env_3xK9Wb2",
  "timestamp": "2026-08-10T14:12:04Z",
  "type": "tool.request",
  "agent_id": "claude-cli",
  "session_id": "session-1a2b3c",
  "users": [{ "type": "User", "id": "alice@example.com" }],
  "device_id": "device-0099",
  "enforce_kind": "monitor",
  "data": {
    "tool_name": "linear__list_issues",
    "tool_parameters": { "assignee": "me" }
  }
}
```

## Prerequisites

* An Oso for Agents environment with alerts or events flowing.
* An S3 bucket (or S3-compatible store) you control.
* Permission to manage connections in the Oso environment.

## Create an export destination

<Steps>
  <Step title="Open Connections">
    In Oso, open your environment and go to **Connections**, where export destinations are configured.
  </Step>

  <Step title="Add the destination">
    Add an export destination, choose the **record source** (Alerts or Events) and destination type **Amazon S3**, and enter the **bucket**, **region**, and a key **prefix** (the bucket and prefix are both required).
  </Step>

  <Step title="Choose authentication">
    Pick an authentication method (below) and save.
  </Step>
</Steps>

## Authentication

### Role assumption

Oso assumes an IAM role in your AWS account to write objects, so no long-lived credentials ever leave your account. Oso generates an `ExternalId` that you must use to restrict your trust policy, preventing other users from using Oso to send unauthorized events by guessing your role ARN.

When you set up a role-assumption destination, Oso shows two policies for you to apply, with the exact principal ARN, `ExternalId`, and bucket filled in:

<Steps>
  <Step title="Copy the policies">
    Copy the **trust policy** and the **permissions policy** Oso displays.
  </Step>

  <Step title="Create the role">
    Create an IAM role in your account using the trust policy as its trust relationship, and attach the permissions policy.
  </Step>

  <Step title="Bind the role">
    Paste the role's ARN back into Oso and save. Oso verifies the role can only be assumed **with** the `ExternalId` before it enables delivery.
  </Step>
</Steps>

```json Trust policy theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "<oso-principal-arn>" },
      "Action": "sts:AssumeRole",
      "Condition": { "StringEquals": { "sts:ExternalId": "<oso-generated-id>" } }
    }
  ]
}
```

```json Permissions policy theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::<your-bucket>/<your-prefix>/*"
    }
  ]
}
```

<Note>
  The console scopes this to your chosen key **prefix** (`<bucket>/<prefix>/*`) so Oso can write only under that prefix. The bucket and prefix are both required.
</Note>

### Access keys

For S3-compatible object stores (such as MinIO or Ceph), or where role assumption isn't available, provide an **access key ID** and **secret access key** for a principal that can `s3:PutObject` to your bucket. Oso encrypts the secret at rest.

<Note>
  On the managed Oso Cloud service, role assumption is the supported method for AWS. Access keys are available on self-hosted deployments and for S3-compatible stores.
</Note>

## Ingest into your SIEM

Any SIEM that can read from S3 can ingest the exported objects: point its S3 input at your bucket (and prefix) and configure it to decompress gzip and parse JSON. See your SIEM provider's documentation for how to set up an S3 input — on the Oso side, the destination setup above is all that's required.
