Audit log
The audit log captures every state-changing call to /api/v1/admin/* —
collection edits, settings updates, hook saves, admin invites, file uploads,
backup triggers, and so on. One row per request, append-only, designed for
compliance and forensic lookups.
What gets recorded
Section titled “What gets recorded”A row is written for every POST / PUT / PATCH / DELETE to
/api/v1/admin/*. GET is not audited — read traffic is high-volume and
already covered by the request log.
Skip-list (intentionally not audited):
/api/v1/admin/auth/login,/api/v1/admin/auth/logout— auth attempts already log via the request log/api/v1/admin/setup— fresh-install bootstrap/api/v1/admin/migrations/diff— read-only despite being POST- Any path matching
/api/v1/admin/preview-*or/api/v1/admin/.*/preview$
Each row is immutable. The application never updates or deletes audit
rows; operators who need to prune for storage budget can DELETE directly
from the vaultbase_audit_log table.
Schema
Section titled “Schema”CREATE TABLE vaultbase_audit_log ( id TEXT PRIMARY KEY, actor_id TEXT, -- admin id from the JWT actor_email TEXT, -- email cached at the time of action method TEXT NOT NULL, path TEXT NOT NULL, action TEXT NOT NULL, -- logical label, e.g. "collections.create" target TEXT, -- best-effort id from the path status INTEGER NOT NULL, ip TEXT, -- only set when VAULTBASE_TRUSTED_PROXIES is configured summary TEXT, -- optional human / JSON at INTEGER NOT NULL -- unix-seconds);Indexes on (actor_id), (at DESC), (action).
Action labels
Section titled “Action labels”action is derived from the path + method. Examples:
| Method | Path | action |
|---|---|---|
| POST | /api/v1/admin/collections | collections.create |
| PATCH | /api/v1/admin/collections/posts | collections.update |
| DELETE | /api/v1/admin/admins/admin-42 | admins.delete (target = admin-42) |
| POST | /api/v1/admin/hooks/123/test | hooks.test |
Uncategorised paths fall back to <METHOD> <path>.
Read API
Section titled “Read API”GET /api/v1/admin/audit-log ?page=1&perPage=50 &actorId=<id> &actionPrefix=collections. &from=<unix-seconds>&to=<unix-seconds>Returns:
{ "data": { "data": [ { "id": "...", "actor_email": "ops@acme", "action": "collections.delete", ... } ], "page": 1, "perPage": 50, "totalItems": 1234, "totalPages": 25 }}Admin UI
Section titled “Admin UI”Sidebar → System → Audit log. Filter by actor id, action prefix, and date range; click a row to see the full entry (path, status, target, IP, timestamp, summary). The table paginates server-side; default page size 50.
IP capture
Section titled “IP capture”The audit row’s ip field is populated from X-Forwarded-For only when
VAULTBASE_TRUSTED_PROXIES is set. Without it the column stays null —
a defensive default that prevents spoofing on direct-exposed deployments.
Environment=VAULTBASE_TRUSTED_PROXIES=10.0.0.0/8,127.0.0.1/32Same env var the rate-limiter uses for its real-IP resolution.