Audit, security events and metrics

What the engine records, where, and how it reaches your SIEM and your monitoring.

The audit store

Two tables in your PostgreSQL. detection_runs records one row per protect call: tenant, key, context and prompt ids, a hash of the input, the kind of input, timing and the layers that answered. detected_matches records one row per span: entity type, byte offsets, confidence, source layer, verifier verdict, cluster and the token used. The matched text is stored as a hash always, and as ciphertext under the audit key when AUDIT_ENCRYPT_TEXT is on, which is the chart default. Retention purges runs older than AUDIT_RETENTION_DAYS every hour.

Writes are best-effort: if the database is unavailable the batch is dropped and the protect call still succeeds. The service refuses to start without a reachable database, and the audit queue depth is exported as a metric so an outage is visible.

Detection runs captured for review keep the original input encrypted for the reviewer.

Security events

Every service emits structured JSON lines on standard output, aligned with the Elastic Common Schema, with a stable event code per kind of event:

Code family Covers
SALUS-GW-001/002 Gateway request accepted or rejected
SALUS-AUTH-001/002 Authentication success or failure
SALUS-HTTP-001/002 HTTP request handling and errors
SALUS-DATA-001/002 Detection runs and restore calls
SALUS-CONFIG-001/002 Configuration loaded or changed
SALUS-AUDIT-001/002 Audit writes and failures
SALUS-CONSOLE-001…005 Console sign-in, sign-out, changes
SALUS-SVC-001/002 Service start, stop and dependency state

Never logged: authorisation headers, keys, request bodies, documents, matched values, protected output or restored output.

Forwarding is your cluster’s job, not a Salus connector: on OpenShift, a ClusterLogForwarder sends the namespace’s logs to your SIEM. Where a SIEM expects CEF, convert in your pipeline (Vector, Logstash or similar); a field mapping ships with the deployment documentation.

Metrics

Each service serves OpenMetrics on its metrics port. All services export build information, request counts, request duration histograms and in-flight gauges. The main service adds detection counts and durations, cache hits, windows and spans processed, downstream attempts and degraded counts, guardrail callbacks and actions, and audit records and queue depth. Detection services add inference counts, durations and in-flight gauges. Labels never carry a tenant, a key, an identifier, an address, text or a token.

Latency percentiles are computed by your monitoring from the histograms; a sample p95 query ships with the deployment documentation. Scraping is configured on your side with a ServiceMonitor or scrape config. Dashboards and alert rules are yours to define against these names.

What leaves the cluster

Nothing, unless you forward it. The engine does not open connections to a SIEM, a vendor service or the internet. The only outbound traffic from a Salus deployment is the traffic your own tooling creates.

All example values in this documentation are synthetic.