Febasidocs
Reference

Audit logs

Every meaningful event Febasi Auth records, what's in each row, and how to query it.

Every authentication and authorization event is appended to the auth_logs table. Logs are tenant-scoped, immutable, and exposed through the /auth-logs endpoint to anyone holding the auth:logs permission.

What gets logged

ActionWhen it fires
LOGINEvery POST /login — success or failure.
LOGOUTEvery POST /logout.
REFRESH_TOKENEvery POST /refresh — success or failure.
REGISTEREvery POST /register — including failures.
USER_DELETEWhen a user is deleted via /users/:id.
ROLE_ASSIGNPOST /roles/assign.
ROLE_REMOVEPOST /roles/remove.
PERMISSION_GRANTPOST /permissions/grant.
PERMISSION_REVOKEPOST /permissions/revoke.

Failures are logged with success = false and errorMessage populated, so you can spot brute-force attempts, mistyped tokens, and forbidden actions all in the same query.

Row shape

FieldTypeNotes
idUUIDPrimary key.
tenant_idUUIDAlways present. Scopes the row.
user_idUUID (nullable)Null for failed logins where the user was unknown.
actionenumOne of the action codes above.
successbooleantrue for successful events.
error_messagetext (nullable)Reason on failures.
ip_addressstringSource IP from X-Forwarded-For or socket.
user_agentstringClient User-Agent if present.
created_attimestampInsertion time. Indexed for range queries.

Querying the log

GET /api/v1/auth-logs?action=LOGIN&success=false&limit=50&offset=0
Authorization: Bearer <jwt-with-auth:logs>

Common query patterns:

GET /api/v1/auth-logs?action=LOGIN&success=false&since=24h

Wire alerts on the count of these. A cluster of failures from a single IP in a 5-minute window is a brute-force fingerprint.

GET /api/v1/auth-logs?action=PERMISSION_GRANT&userId={id}

Useful for compliance reviews — "show me everything that has been granted to this user."

GET /api/v1/auth-logs?ip=203.0.113.42&limit=200

Cross-reference with the security metrics endpoint — IPs flagged as suspicious deserve a closer look here.

Retention

Audit rows are never overwritten. They are kept indefinitely on the production host today; the operations team will publish the retention policy once it's formalized. Plan for "rows live forever" until proven otherwise.

What's not in audit logs

  • Read endpointsGET /users, GET /roles, etc. are not audited by default. If a tenant needs read auditing, request it through the platform team; the infrastructure exists, the events are simply not emitted today.
  • JWT secret rotation — captured in tenant metadata, not in auth_logs.
  • Outbound webhook deliveries — Febasi Auth does not yet emit webhooks. The audit log is the closest thing to an event stream right now.

Pairing with security metrics

For real-time signals (last 5 min / last 24h aggregates), use:

GET /api/v1/tenants/me/metrics/security

For a forensic timeline of a specific user / IP / action, use the audit log. The two are intentionally separate: one is fast and aggregate, the other is authoritative and granular.

On this page