Audit Logs ~5 min
Overview
Shell automatically records significant events in audit_logs. The AuditService extracts user context (ID, org, IP, user-agent) from the active request — no manual threading required.
Query activity logs
http
GET /api/admin/audit?limit=50&organizationId=org-uuid
Authorization: Bearer <shell-jwt> (requires settings:read)| Query param | Default | Description |
|---|---|---|
limit | 20 | Max results (capped at 50) |
organizationId | — | Filter by organization |
json
{
"data": [
{
"id": "uuid",
"userId": "user-uuid",
"action": "user.created",
"resource": "users",
"resourceId": "new-user-uuid",
"metadata": { "email": "jane@acme.com" },
"ipAddress": "203.0.113.1",
"userAgent": "Mozilla/5.0 ...",
"createdAt": "2026-03-17T10:00:00Z"
}
]
}What gets logged automatically
| Event | action | resource |
|---|---|---|
| User created | user.created | users |
| User updated | user.updated | users |
| User deleted | user.deleted | users |
| Roles assigned | user.roles_assigned | users |
| Onboarding approved | onboarding.approved | onboarding_requests |
| Onboarding rejected | onboarding.rejected | onboarding_requests |
| Login (local) | auth.login | auth |
| Password changed | auth.password_changed | auth |
| Password reset | auth.password_reset | auth |
Write audit events from your service
Use AuditService in any Ignis service:
typescript
import { inject, BaseService } from '@venizia/ignis';
import { AuditService } from '@/services';
export class EmployeeService extends BaseService {
constructor(
@inject({ key: 'services.AuditService' })
private audit: AuditService,
) {
super({ scope: EmployeeService.name });
}
async createEmployee(data: CreateEmployeeDto) {
const employee = await this.repo.create(data);
await this.audit.log(
'employee.created', // eventType / action
'employees', // resource
employee.id, // resourceId
{ name: data.name }, // metadata (any JSON)
);
return employee;
}
}AuditService.log() automatically extracts from the current request context:
userId— fromAuthentication.CURRENT_USERorganizationId— from the JWT claimsipAddress— fromx-forwarded-forheaderuserAgent— fromuser-agentheader
Audit log table
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key |
userId | uuid | Who performed the action |
action | text | Dot-notation event name (e.g. user.created) |
resource | text | Resource type (e.g. users, employees) |
resourceId | text | ID of the affected record |
metadata | jsonb | Additional context (varies by event) |
ipAddress | text | Client IP (from x-forwarded-for) |
userAgent | text | Browser/client string |
createdAt | timestamp | Event timestamp |
Retention
Audit logs are append-only — there is no delete endpoint. Implement your own archiving/retention policy at the database level if needed.