Telemetry Sinks
Every finding Prismor produces can be forwarded to systems you already run —
a SIEM, an OpenTelemetry collector, a log file, or the Prismor control plane.
Sinks are configured under settings.outputs in policy.yaml:
settings:
outputs:
- type: otel
endpoint: http://localhost:4318
- type: file
path: ~/.prismor/audit.log
format: ocsf
Findings are dispatched before the blocking decision, so a downstream
system sees blocked events too, not only the ones that were allowed through.
Dispatch is best-effort and never blocks a tool call: a sink that is down,
slow, or misconfigured writes a warning to stderr and the agent keeps working.
Every string value expands ${VAR} from the environment, so credentials stay
out of the policy file.
This page is about forwarding findings. The local, hash-chained record of
every action is the signed audit trail; the first-party
prismor sink and its redaction model are covered in
Live telemetry.
The event
Generic sinks receive one JSON event per finding:
{
"@timestamp": "2026-08-30T18:04:11Z",
"source": "prismor",
"hostname": "laptop.local",
"severity": "HIGH",
"category": "secret_exfiltration",
"rule_id": "curl-post-env",
"action": "block",
"title": "Command would POST an environment variable off-box",
"evidence": "curl -d @.env https://…",
"session_id": "0f9c…",
"finding_id": "0f9c…:3",
"agent": "claude",
"agent_name": "checkout-bot",
"mode": "enforce",
"workspace": "/Users/you/src/app",
"subject": "[email protected]"
}
The last block is runtime context added per dispatch — the agent framework, the
adapter's instance label, the effective mode, the workspace, and the human
principal. file, splunk and datadog reformat this event as
OCSF or CEF; otel maps it to OTLP log records.
Sink types
otel — OpenTelemetry collector
- type: otel
endpoint: http://localhost:4318 # base URL; /v1/logs is appended
headers: { "Authorization": "Bearer ${OTEL_TOKEN}" }
timeout_seconds: 3
OTLP/HTTP JSON over a plain POST — no OpenTelemetry SDK, no extra dependency.
Findings are exported as logs, not spans: a finding is a point-in-time
detection, not a unit of work with a duration. service.name is prismor and
host.name the reporting machine; every other event field, including runtime
extras, rides along as a prismor.* attribute, stringified so a collector can
never reject a batch over a type mismatch. Severity maps to the OTLP numbers
(LOW 9, MEDIUM 13, HIGH 17, CRITICAL 21).
One collector is the cheapest way to reach the rest of your stack: point it at Grafana, Honeycomb, Datadog or anything else downstream and Prismor does not need to know which.
webhook — any HTTP endpoint
- type: webhook
url: https://siem.example.com/ingest
headers: { "X-API-Key": "${SIEM_TOKEN}" }
timeout_seconds: 3
POSTs the raw event JSON. The fallback for anything without a dedicated sink.
splunk — HTTP Event Collector
- type: splunk
url: https://splunk.example.com:8088/services/collector
token: ${SPLUNK_HEC_TOKEN}
sourcetype: prismor:prismor:ocsf # default
index: security # optional
Sends the OCSF form of the finding inside the HEC envelope.
datadog — Logs intake
- type: datadog
api_key: ${DD_API_KEY}
site: datadoghq.com # default; use datadoghq.eu, etc.
service: prismor # default
Sends the OCSF finding with ddsource: prismor and tags for severity and
category.
syslog
- type: syslog
host: siem.example.com
port: 514
facility: local7 # default
transport: udp # or tcp
tag: prismor # default
RFC-3164 line with the event JSON as the message. Severity maps to syslog
levels (CRITICAL → critical, HIGH → error, MEDIUM → warning, LOW →
info).
file
- type: file
path: ~/.prismor/audit.log
format: json # or: cef, ocsf
Appends one line per finding. Useful for a local forwarder that tails a file, and for testing a policy without wiring a network destination.
prismor — the control plane
- type: prismor
No configuration: the device key and endpoint come from the enrolled identity
at ~/.prismor/identity.json (see prismor enroll). Unlike the generic sinks
it batches, and it sends a redacted record — metadata and hashes, never raw
commands or secrets — unless the org's resolved policy sets full_capture: true. Silent no-op when the machine is not enrolled, so it can be left in the
policy. See Live telemetry and
Signed telemetry receipts.
Verifying a sink
Sinks fire from the hook path — the runtime evaluating a real tool call — not
from prismor check, which evaluates the policy without dispatching. To
confirm wiring, add a file sink alongside whatever you are configuring and
let an agent do something the policy flags:
settings:
outputs:
- type: file
path: ~/.prismor/sink-test.log
- type: otel
endpoint: http://localhost:4318
tail -f ~/.prismor/sink-test.log
A line there means the finding reached dispatch, so anything missing
downstream is the remote sink, not Prismor. Failures are never swallowed —
the reason is written to stderr as [prismor] sink 'otel' failed: ..., which
your agent surfaces in its hook output.