# Audit log export

Stream your organization's audit trail to your own security tooling. seekrit
ships every new audit event — writes, grants, revocations, token and lease
actions, denied resolves — to an **OTLP/HTTP logs endpoint** as OpenTelemetry
log records, so you can alert, retain, and correlate seekrit activity alongside
the rest of your infrastructure.

> **Note:** Exported records carry only what's already in your audit log: action, attribution (user or service token), IP, resource ids, and redacted metadata (names and counts). They **never** contain secret values, ciphertext, private keys, passphrases, or token strings.

## How it works

A per-organization background sweep runs **every minute**. For each configured
sink it finds audit rows newer than a stored watermark, POSTs them to your
endpoint as an OTLP `LogsData` payload (`content-type: application/json`), and
advances the watermark **only after your collector returns a 2xx**. Delivery is
therefore **at-least-once**: if your endpoint is briefly unavailable, the same
events re-ship on a later tick rather than being dropped (repeated failures back
off exponentially, up to a few minutes between attempts).

Each event becomes one log record:

- **Body** — the audit action (e.g. `secret.created`, `token.revoked`).
- **Severity** — `WARN` for revocations, deletions, and denied resolves; `INFO`
  otherwise, so you can alert on security-significant events directly.
- **Attributes** — `audit.id`, `audit.action`, `audit.resource_type`,
  `audit.resource_id`, `actor.type`, `actor.id`, `client.address`, and the
  event's redacted metadata as `audit.metadata.*`.
- **Resource** — `service.name=seekrit`, plus `seekrit.org.id` and
  `seekrit.org.slug`.

## Configure a sink

In the dashboard, open your organization → **settings** (admins only), or use
the API directly:

```bash
curl -X PUT https://api.seekrit.dev/v1/orgs/$ORG/log-sink \
  -H "authorization: Bearer $SEEKRIT_TOKEN" \
  -H "content-type: application/json" \
  -d '{
        "endpoint": "https://collector.example.com/v1/logs",
        "headers": { "Authorization": "Bearer <your-collector-token>" },
        "enabled": true
      }'
```

- **Endpoint** — the full OTLP/HTTP logs URL, typically ending in `/v1/logs`.
- **Headers** — sent with every export request; use these for your collector's
  auth (e.g. `Authorization`, or `DD-API-KEY` for Datadog). They are **encrypted
  at rest** and never returned — reads only ever show the header *names*. Omit
  `headers` on a later update to keep the stored value; pass `{}` to clear it.
- **Enabled** — toggle export off without deleting the configuration.

When first enabled, the watermark starts at the newest existing audit event, so
you receive events from that point forward rather than a backfill of history.

## Test the connection

Send a synthetic event to verify connectivity and auth before you rely on it —
click **Send test event** in the dashboard, or:

```bash
curl -X POST https://api.seekrit.dev/v1/orgs/$ORG/log-sink/test \
  -H "authorization: Bearer $SEEKRIT_TOKEN"
# → { "ok": true, "status": 200, "error": null }
```

The dashboard also surfaces the last successful export time and the last error,
so a misconfigured endpoint is easy to spot.

> **Warning:** The header you configure is a credential for **your** collector. Anyone with admin access to the organization can change the endpoint — treat the ability to reconfigure the sink as security-sensitive, and prefer a scoped, rotatable token over a long-lived one.
