switching clears the token & responses
No token
38

Investigate with the audit log (cross-tenant)

The canonical cross-tenant forensic read. Allow-listed filters only; cursor-paginated. Requires security-investigator. ip / userAgent are deliberately not exposed.

  1. GET /v1/admin/audit → audit entries across all tenants (filter by allow-listed params)
GET/v1/admin/auditadminCross-tenant audit query

Filters are an allow-list only — no raw columns, no $ne / bracket syntax; an unknown param → 400. Forensic-sensitive ip / userAgent are DELIBERATELY not exposed; act-as actions appear with actOperatorId / actReason (the cross-profile flow that produced them is scenario 37). Enhancement 4 added nine event codes worth filtering on: device_challenge_issued, device_trusted, device_trust_failed, device_untrusted, login_challenge_failed, registration_resumed, registration_completed, invitation_sent, login_mode_changed. device_trust_failed is the one to alert on — a CORRECT password followed by repeated device-challenge failures is the fingerprint of credential stuffing landing on a real account, a signal neither login_failed nor mfa_failed can express.

Query parameters
ℹ︎Field guide — what each value means & where it comes from9 fields

No request body — this is a bodyless GET with optional, allow-listed query filters only (all optional; default limit 20). Authorization is the security-investigator role gate via the gateway (Authorization / x-gateway-context handled by the tester); no step-up factor is required or accepted, and the .strict() schema rejects any unknown param.

tenantIdqueryUUIDoptionalfrom a response
Optional filter restricting results to one tenant. You obtain the UUID by copying it from a prior tenant list/get response (e.g. a tenant's id) or from a captured audit entry's tenantId; you do not invent it. Narrows the cross-tenant audit query to that tenant.
userIdqueryUUIDoptionalfrom a response
Optional filter restricting results to events for one user. Copy the UUID from a prior user list/get response (the user's id) or from an audit entry's userId field; it is not freely typed. Scopes the audit read to that user's events.
eventquerystringoptionalyou choose
Optional security-event code filter, 1-64 chars (e.g. act_as_started). The user types the event code they want to query for; it filters the audit stream to matching events.
operatorIdqueryUUIDoptionalfrom a response
Optional filter on the acting operator (maps to act_operator_id). Copy the operator UUID from a prior operator list/get response or from an audit entry's actOperatorId; not typed by hand. Limits results to events performed by that operator.
outcomequeryenumoptionalyou choose
Optional filter on the event outcome. The user picks one of the two allowed values to show only successful or only failed events.
  • successReturn only audit entries whose recorded outcome was a success.
  • failureReturn only audit entries whose recorded outcome was a failure.
fromqueryISO-8601optionalyou choose
Optional lower time bound (inclusive). The user supplies an ISO-8601 timestamp that MUST include a timezone offset. Restricts results to events at or after this instant.
toqueryISO-8601optionalyou choose
Optional upper time bound. The user supplies an ISO-8601 timestamp that MUST include a timezone offset. Restricts results to events at or before this instant.
limitqueryintegeroptionalyou choose
Optional page size, integer 1-100, defaulting to 20 if omitted. The user chooses how many audit entries to return per page.
cursorquerystringoptionalfrom a response
Optional opaque keyset pagination token, 1-512 chars. You do not type this yourself: copy it from the prior response's meta.nextCursor to fetch the next page. Omit it for the first page.
Bearer token
GET https://api.kerja.team/v1/admin/audit?event=act_as_started&outcome=success&limit=20
↩︎Response guide — what comes back & what each value means13 fields

200 OK returning the standard { data, meta } envelope (no special response headers; not a token endpoint so no Set-Cookie/Cache-Control). `data` is an array of AuditEntry items (forensic `ip`/`userAgent` are intentionally omitted); `meta` carries the result count and keyset cursor for pagination.

data[].idstringalways
Unique identifier of the audit event record. Use to reference or de-duplicate a specific entry.
data[].eventstringalways
Security-event code describing what happened (e.g. act_as_started). Display as the event type; can be fed back as the ?event filter.
data[].userIdUUIDconditional
The subject user the event concerns; null when the event is not tied to a specific user. Nullable.
data[].tenantIdUUIDalways
The tenant the event occurred in. Use to scope or group entries by tenant.
data[].outcomeenumalways
Whether the audited action succeeded or failed.
  • successThe audited action completed successfully.
  • failureThe audited action failed or was denied.
data[].reasonstringconditional
Free-text reason/justification recorded for the event (e.g. a ticket reference). May be null when no reason was captured.
data[].actOperatorIdUUIDconditional
For act-as/impersonation events, the operator who performed the action (maps to act_operator_id). Null when not an act-as event.
data[].actReasonstringconditional
Justification supplied for an act-as action (e.g. support ticket reference). Null when not an act-as event.
data[].stepUpMethodenumconditional
The step-up factor used to authorize a sensitive mutation that produced this event. Null when no step-up applied.
  • passwordStep-up was satisfied by re-entering the operator password.
  • recoveryCodeStep-up was satisfied by a one-time recovery code (the other accepted operator step-up factor; the step-up set is { password?, recoveryCode? }).
data[].traceIdstringalways
Distributed-trace correlation id for the request that generated the event. Use to cross-reference logs/traces.
data[].occurredAtISO-8601always
Timestamp when the event occurred (UTC). Part of the keyset sort (occurredAt, id); display as the event time.
meta.countintegeralways
Number of AuditEntry items returned in this page (length of data).
meta.nextCursorstringconditional
Opaque keyset pagination token; pass back as ?cursor to fetch the next page. Null when there are no further results.