Admin — manage users
User management goes through better-auth's admin plugin, exposed at /api/auth/admin/*.
Permission statement
src/auth/permissions.ts declares the full action set:
statement = {
user: ["create", "list", "set-role", "ban", "impersonate", "delete", "set-password", "get", "update", "read"],
session: ["list", "revoke", "delete"],
organization: ["read", "update", "manage_members"],
audit_log: ["read"],
agent: ["create", "read", "update", "delete"],
};
Roles assign which actions are allowed:
| Role | Allowed |
|---|---|
platform_admin | All statement actions |
org_admin | organization.*, audit_log.read, user.get/read |
org_member | organization.read, audit_log.read |
If a required action is missing from statement, hasPermission returns false even for platform_admin. Always keep statement exhaustive.
Frontend parity
fleapo-marketplace/src/lib/permissions.ts must mirror the backend file exactly. If the two diverge, the frontend's adminClient.checkRolePermission() returns wrong results and admin UI elements appear/disappear incorrectly.
This is the single most-easily-missed convention in the codebase. Read Backend → RBAC before changing either file.
Session revocation
POST /api/auth/admin/revoke-sessions (with appropriate permission) invalidates a user's sessions. They are signed out everywhere on the next request.
Audit
Every admin action goes through AuditLogMiddleware. PostHog rows include userId, targetUserId, action, result.