Skip to content

Audit & SIEM

Every tool call, sign-in, and administrative change passes through one place, so the Gateway can record all of it. This page covers what is recorded, where it goes, and what leaves your deployment.

Every setting here lives on your gateway pool in the Britive tenant portal, in the Audit and Integrations groups. Changes reach a running Gateway on its next sync - nothing needs a restart.

Where Events Go

Events are always written to two places, and optionally to two more:

SinkAlways on?Contents
PostgresYes - the durable recordFull events, queryable
stdoutYesStructural line by default; full event optionally
SIEM webhookNoEvery recorded event, as JSON
Britive tenant audit streamYes, by defaultA selected subset

Postgres is the source of truth. The admin console reads it, and every replica sees the same table.

What Is Recorded

Recording is grouped into categories. audit.categories (“Recorded categories”) selects the ones you want:

CategoryContents
accessTool invocations. The audit trail proper.
authUser and administrator sign-in, OAuth token and callback events.
adminOperator changes: mount, unmount, publish, endpoints, sync.
catalogWhich tools a caller can see.
systemThe Gateway’s own bookkeeping - cache hits, sync polls, schema captures, token plumbing. High volume, and not an audit trail. Add it when diagnosing a problem.

The default is ["access", "auth", "admin", "catalog"].

Denials, failures, and policy bypasses are always recorded, regardless of this setting. Narrowing the categories cannot conceal the events an investigation requires.

Catalogue events are recorded on change

catalog events fire when a caller’s resolved tool set changes, not on every listing. Clients re-list constantly, and per-listing rows would dominate the table without adding information. Change events include the resolved tool names.

So that silence still means something, an unchanged catalogue re-affirms itself once every audit.toolsListHeartbeatSeconds (default 86400, 24 hours). An absence of events therefore means nothing changed - not that logging stopped.

Retention

SettingPortal labelDefaultPurpose
audit.retentionDaysRetention90Events older than this are deleted. 0 disables the sweep.
audit.retentionSweepIntervalMinutesRetention sweep1440 (24h)How often the maintenance worker wakes. Advanced group.

Rows are deleted in batches of ten thousand per statement, so a large backlog goes in several short transactions rather than one long one. That batch size is fixed.

The sweep is coordinated across replicas with database advisory locks, so only one container performs each delete.

Set retentionDays to 0 only if a separate process is responsible for the audit table. If you prefer to handle it yourself:

DELETE FROM audit_events WHERE occurred_at < NOW() - INTERVAL '90 days';

The Gateway’s sweep and your own job both no-op safely if the other already ran.

The stdout Line

By default the stdout line is structural only and omits prompts and tool arguments. Turn on audit.stdoutFull (“Full events to standard output”) to write the complete event, and only if your log pipeline is inside your trusted perimeter. Full events always reach Postgres regardless.

There is no JSONL file option. Postgres, stdout, the SIEM webhook, and forwarding to your tenant cover every real destination, and a file path inside a container nobody mounts covered none of them.

Streaming to a SIEM

Every recorded event is POSTed as JSON by a non-blocking background worker. Everything in audit.categories is sent; your pipeline decides what to keep.

SettingPortal labelDefaultPurpose
audit.webhook.urlSIEM webhook""Endpoint. Setting it enables the webhook.
audit.webhook.headersSIEM webhook headers{}Additional headers, as a mapping. Stored encrypted.
audit.webhook.transformSIEM payload transform""Optional JMESPath expression reshaping each event before sending.
audit.webhook.verifyTlsVerify the SIEM’s certificatetrueVerify the endpoint’s certificate.
audit.webhook.timeoutSecondsSIEM timeout5.0Per-request timeout. Advanced group.
audit.webhook.maxRetriesSIEM retries3Retries per event. Advanced group.

The buffer holds ten thousand events; if it fills, events are dropped and logged. That size is fixed.

The headers usually carry your SIEM’s credential, so they are treated as a secret: the platform stores them encrypted, never returns them to an administrative reader, and shows only whether a value is set. Submitting the masked placeholder leaves the stored value alone. The Gateway itself receives them, because it is the one reader that has to.

Splunk HEC

FieldValue
SIEM webhookhttps://splunk.example.com/services/collector/event
SIEM webhook headersAuthorization: Splunk <HEC token>
SIEM payload transform{event: @, sourcetype: 'britive.audit'}

Datadog Logs

FieldValue
SIEM webhookhttps://http-intake.logs.datadoghq.com/api/v2/logs
SIEM webhook headersDD-API-KEY: <api key>
SIEM payload transform{ddsource: 'britive', service: 'mcp-gateway', message: message, attributes: @}

A generic collector

FieldValue
SIEM webhookhttps://your-collector.example.com/events
SIEM webhook headersAuthorization: Bearer <token>, X-Source: britive-mcp-gateway, X-Env: prod
SIEM payload transform(leave empty for the raw event)

If a transform expression fails to evaluate, the original payload is sent and a warning is logged. Events are never dropped silently.

Streaming to Your Britive Tenant

The Gateway also forwards selected events to your tenant, where they appear in its own audit history alongside native events, recorded as gateway.<eventType>. This is on by default, so a Gateway’s activity is visible in the audit history of the tenant it serves. Authentication uses the gateway pool token.

SettingPortal labelDefaultPurpose
audit.platform.enabledSend events to BritivetrueForward to the tenant. Requires a pool token - without one, forwarding disables itself at startup and records why.
audit.platform.eventsEvents to forwardsee belowWhich actions to forward, by name.
audit.platform.includeContentInclude call contentfalseWhether to include prompts, intent, arguments, and captured response bodies.

Batch size, flush interval, buffer size, and request timeout are fixed. Both ends of this sink are Britive’s, so there is nobody for whom a different flush interval is the right answer.

The default event set is the mutating and security-relevant one:

ActionWhat it is
tools.callTool invocations, permitted and denied alike.
user.loginEnd-user sign-in through the Gateway.
admin.loginAdmin console sign-in.
admin.publish-toolsPublishing a backend’s tool catalogue to the platform.

Read-only listing activity is excluded by default because clients re-list frequently and those events would outnumber the ones an auditor is looking for. The portal offers the rest of the vocabulary as a checklist, including tools.list, tools.search, settings.refresh, the oauth.* actions, and backends.sync.

Inspection verdicts (tools.call.inspect) are not forwarded by default. Add the action if you want inspection findings in your tenant’s audit history as well as in the Gateway’s own log and your SIEM.

An unrecognised action name is rejected rather than stored. This is deliberate: a typo would otherwise look configured and forward not one event.

What “Include call content” changes

audit.platform.includeContent: true means prompt text, query text, secret paths, and tool arguments leave your deployment and render verbatim in the tenant’s audit interface. The Gateway treats those fields as sensitive everywhere else, so inclusion is opt-in.

With it disabled, every fact about a call is still forwarded: who called it, which tool and backend, whether it was permitted, inspection verdicts, timings, and failure reasons. The _llm_session_id correlation handle is forwarded either way, because it is an identifier rather than content.

Forwarding needs a tenant whose mcp-manager exposes the audit ingest endpoint. An older tenant rejects the requests and the Gateway logs a warning for each batch - turn Send events to Britive off against such a tenant to stop them.

Reading the Audit Log

The admin console has an Audit Events view with filters for actor, action, backend, tool, decision, outcome, session, and a time range. Expanding a row shows the full event, including any inspection verdict and its findings ordered worst-first.

The same data is available over HTTP:

curl "https://mcp-gateway.example.internal/admin/audit?session_id=<uuid>"

Filtering by session_id is the one worth knowing: it pulls back every call the model made during one chat or coding session as a single episode, rather than leaving you to correlate timestamps.

Next Steps

Last updated on