Skip to content

Export to your SIEM

Availability Ultimate · Enterprise.

Tessera keeps a complete audit log in Postgres and can additionally stream every event to an external collector in real time. Configure it under Settings → Integrations → Audit export.

  1. Toggle Export enabled.
  2. Enter your collector’s webhook URL — any HTTP endpoint that accepts a JSON POST (Elastic, a log shipper, or Splunk HEC behind a collector/proxy).
  3. Optionally add a bearer token, sent as Authorization: Bearer <token>.
  4. Click Send test to deliver a sample event.
  • Events are POSTed as JSON, one per event, as they happen.
  • Delivery is best-effort and asynchronous — it never blocks a user action, and the full log always remains in the database as the source of truth.

Alongside the events, the controller sends one chain.sealed message every time it seals a block, carrying the block’s sequence number, its hash, the previous hash, the range of entry ids it covers, and the block’s ed25519 signature itself.

These are the reason the export is worth having even if you never read the rest. The integrity chain inside the database can prove that nothing in the middle of the log was altered, but not that the end of it is still there: delete the newest blocks and what remains verifies perfectly. Your SIEM holds the sequence numbers, so a database whose chain ends lower than the last announcement you received is a discrepancy nobody can hide. Each announcement carries the block’s signature, so the copy in your SIEM can be checked against the public key by somebody who has neither the controller nor its database.

Two limits to keep in view. Delivery is best effort: if the controller cannot reach your collector the announcement is lost, and an attacker who can silence the collector can silence the anchor along with it, so treat a gap in the sequence as an incident rather than as noise. And an announcement is only as trustworthy as the signature it carries, which means this holds only when TESSERA_AUDIT_SIGN_KEY is set. Without a key there is nothing in the message that an attacker who can reach your collector could not have written themselves.

They are not stored in the audit log itself, only sent here.

Every audit event: logins, connects, per-command / query / API-request activity, access requests and approvals, settings changes, and lifecycle events (user disabled, sessions revoked) — the material SOC pipelines and compliance reviewers consume.

Each message carries the same fields the console shows:

FieldMeaning
tsWhen the event happened, to the nanosecond, in UTC. Not when it was sent.
seq, bootA counter within one controller process, and an id for that process.
actionWhat happened, e.g. user.login_failed, session.command, chain.sealed.
severityINFO, NOTICE, WARNING, ERROR or CRITICAL.
outcomeallowed, denied, blocked or error.
subsystemWhich part produced it: api, ssh, kubernetes, database, rdp, oidc, scim, janitor, license.
source_ipThe address the request came from.
user_id, target_id, session_idIds, empty when the event has no such subject.
detailThe event’s own fields. Never a credential.

Delivery is best effort: if the collector is unreachable or the queue is full, the event is dropped rather than held, because an audit write must never wait on a network. That is why seq exists. It counts up within one boot and is taken before the send, so a dropped event still consumes a number and leaves a gap you can see. Alert on a gap, and on tessera_audit_export_total{outcome="dropped"} from Prometheus metrics.