Push Capsule detections, findings, and policy violations to any OpenTelemetry (OTLP) logs endpoint: your own OpenTelemetry Collector, or an observability or SIEM backend that accepts OTLP directly. Put a Collector in front to route events anywhere it can export.
Capsule sends each event as an OTLP log record as it is produced, over OTLP/HTTP with JSON encoding, gzip-compressed.
| Event type | What gets exported |
|---|---|
| Detections | Real-time detections raised on agent activity, with full event context |
| Findings | Posture and configuration findings across your AI inventory |
| Policy violations | Guardrail and policy breaches, with the full evidence the decision was made on |
Capsule event (detection / finding / policy violation)
→ OTLP log record, body = the full Capsule event envelope
→ POST <endpoint>/v1/logs, gzipped JSON, with your headers
→ your OpenTelemetry Collector or OTLP-compatible backendThis is separate from Settings → Notifications. Notifications push individual alerts to a channel; the SIEM integration streams the full, verbose event record for ingestion and long-term correlation.
OTLP/HTTP JSON only. Protobuf encoding and OTLP/gRPC are not supported. An endpoint that only accepts protobuf answers with
HTTP 415. Put a Collector in front of it: the Collector receives JSON and re-exports in whatever protocol the backend needs.
- A Capsule account with admin access, and the SIEM tab visible under Settings
- An OTLP/HTTP logs endpoint reachable from the internet over HTTPS
- The credentials your endpoint expects, as one or more request headers
Capsule accepts either shape:
- A collector base URL, the value you would put in
OTEL_EXPORTER_OTLP_ENDPOINT. Capsule appends/v1/logs. For examplehttps://otel-collector.acme.com:4318is posted tohttps://otel-collector.acme.com:4318/v1/logs. - The full logs URL, the value you would put in
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT. A URL that already ends in/v1/logsis used as is.
The endpoint must be https. Redirects are not followed, so point Capsule at the receiver itself rather than at a URL that forwards to it.
Headers are sent with every request, and are usually how the endpoint authenticates Capsule. They are write-only: Capsule stores them encrypted and never shows the values again. You can add up to 20. Content-Type, Content-Encoding, Content-Length, Host, Transfer-Encoding and Connection are set by Capsule and cannot be overridden.
| Destination | Endpoint | Header |
|---|---|---|
OpenTelemetry Collector with bearertokenauth | https://<your-collector>:4318 | Authorization: Bearer <token> |
| Grafana Cloud OTLP | https://otlp-gateway-<zone>.grafana.net/otlp | Authorization: Basic <base64 of instanceId:token> |
| Honeycomb | https://api.honeycomb.io | x-honeycomb-team: <api key> |
For Grafana Cloud, the instance ID, zone, and a token with write access are on the OpenTelemetry tile of your Grafana Cloud stack. Encode the pair with echo -n '<instanceId>:<token>' | base64.
A collector that authenticates by network rather than by header, for example one behind an IP allow-list, needs no headers at all.
A minimal OpenTelemetry Collector Contrib config that accepts Capsule's events with a bearer token and prints them. Replace the debug exporter with the exporter for your backend once you have seen events arrive.
extensions:
bearertokenauth:
token: ${env:CAPSULE_OTLP_TOKEN}
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
auth:
authenticator: bearertokenauth
tls:
cert_file: /etc/otelcol/tls/server.crt
key_file: /etc/otelcol/tls/server.key
exporters:
debug:
verbosity: detailed
service:
extensions: [bearertokenauth]
pipelines:
logs:
receivers: [otlp]
exporters: [debug]In Capsule, add the header Authorization with the value Bearer <the CAPSULE_OTLP_TOKEN value>. If TLS terminates at a load balancer in front of the Collector, drop the tls block and give Capsule the load balancer's https URL.
- In Capsule, go to Settings → SIEM and click Add integration.
- Set Destination to OpenTelemetry (OTLP).
- Enable the event types you want: Detections, Findings, Policy violations.
- Choose an Event detail level:
- Full sends the whole envelope, matching the S3 and Splunk exports.
- Compact omits activity message bodies. Use it where your backend bills by ingested volume and the transcript is not what you search on.
- Paste the Endpoint from Step 1.
- Under Headers, click Add header for each header your endpoint needs, and enter its name and value.
- Click Save, then enable the integration. A new integration starts disabled and exports nothing until you turn it on.
When you edit the integration later, saved header values stay hidden. Leave Headers empty to keep them. Entering any header replaces the whole saved set, so enter every header the endpoint needs, not only the one you are changing.
Use the row menu's Send test event. Capsule posts a single connection-test log record to your endpoint and reports whether it was accepted, with the endpoint's error if it was not. The record is a capsule.detection.created event whose detection type is CAPSULE_CONNECTION_TEST, so it is easy to filter out. With the Collector example above, the record appears in the Collector's output.
The Delivery column on the SIEM list shows the outcome of the most recent attempt, and the details drawer shows the last error in full.
Each request is one OTLP ExportLogsServiceRequest carrying one resource, one scope, and a batch of log records.
| OTLP field | Value |
|---|---|
Resource attribute service.name | capsule |
Resource attribute capsule.tenant.id | Your Capsule tenant ID |
Scope name / version | capsule.siem-export / 2, the envelope schema version |
timeUnixNano | When the detection, finding, or policy violation was created |
observedTimeUnixNano | When Capsule exported the event |
severityNumber, severityText | Policy violations only, see below |
Attribute event.name | capsule.detection.created, capsule.finding.created, or capsule.policy_violation.created |
Attribute capsule.event.id | The ID of the detection, finding, or policy violation |
Attribute capsule.schema_version | 2 |
body | The full Capsule event envelope, as a structured map |
Policy violations carry Capsule's severity. severityNumber maps it onto the OTLP severity ranges, and severityText carries Capsule's own value.
| Capsule severity | severityNumber | OTLP range |
|---|---|---|
critical | 21 | FATAL |
high | 17 | ERROR |
medium | 13 | WARN |
low | 9 | INFO |
Capsule does not rank detections or findings, so those records have no severity fields rather than an invented one.
The body is the same envelope the S3 and Splunk destinations receive, with the record under event:
{ "schemaVersion": 2, "eventType": "policy_violation.created", "tenantId": "...", "exportedAt": "...", "event": { ... } }It is sent as a structured OTLP value rather than a JSON string, so a backend can query its fields directly. Objects become kvlistValue, arrays become arrayValue, integers become intValue, other numbers become doubleValue, and null becomes an empty value.
Every event carries its anchor resource in full - id, name, type, external id, parent, and the environment and connector it was discovered through - so events correlate against the rest of your inventory without a lookup.
policy_violation.createdis self-contained: the violation, the policy that raised it including its conditions, and the complete finding, detection and activity records the decision was made on.detection.createdcarries the detection, its evidence, and the session activities it was raised on.finding.createdcarries the finding, its evidence, and its remediation steps.
Triage state is exported on all three. Secrets Capsule identified in evidence are masked to a short prefix before export, in evidence text and activity message bodies alike.
One violation, one event. A violation is exported once, when it is first raised. If it is later resolved and the same condition re-triggers, Capsule reuses the existing violation and does not emit a second
policy_violation.created.
- Batching - records are gzipped and split so each request stays under 1 MB compressed, a limit every common OTLP backend accepts.
- Oversized events - a single event that still exceeds the limit after compression is rejected and surfaced on the integration, never truncated. Switching Event detail to Compact is the fix.
- Retries - Capsule retries the statuses the OTLP/HTTP specification marks retryable (
429,502,503,504), timeouts, and network errors, with exponential backoff, honouringRetry-After. Every other failure is a configuration error and is reported instead. - Timeouts - each request has 10 seconds to complete.
- Visibility - the outcome of the most recent attempt is shown per integration in Settings → SIEM, with the full error in the details drawer.
- Backfill - export begins when the integration is enabled. Events raised before that are not sent.
The endpoint did not accept the headers. Check the header name your backend expects and the value's format, for example the Bearer or Basic prefix. Saved values are hidden, so enter every header again and save.
The path is wrong. Give Capsule the collector base URL and let it append /v1/logs, or the full logs URL. A base URL that already includes a different signal path, such as /v1/traces, will not work.
The endpoint only accepts protobuf. Capsule sends JSON only. Route the events through an OpenTelemetry Collector, which accepts JSON and exports protobuf or gRPC to the backend.
The endpoint returned success but reported a partial success, dropping some records. Capsule shows this as a failed delivery with the endpoint's own message, since the dropped records were not stored. The message usually names the limit or field the backend objected to.
- Confirm the integration is enabled and at least one event type is turned on.
- Use Send test event - it reports the exact error from the endpoint.
- Confirm the endpoint is reachable from the internet over
httpson the port in the URL. If it sits behind an IP allow-list, Capsule's egress addresses need to be on it. Contact support for the current list. - A request that takes longer than 10 seconds is retried and then reported as failed. Check the endpoint's load and anything between it and the internet, such as a proxy or load balancer.
For help with this integration, contact support@capsule.security.