Repository navigation
Record the actor of every admin write action #404
Copy link
Copy link
Closed
Labels
DevOpsSecuritySecurity, access control, and data exposureSecurity, access control, and data exposureenhancementNew feature or requestNew feature or request
Milestone
Description
Activity
- added a parent issue
on Oct 6, 2026 - added a commit that references this issue
on Oct 6, 2026 - changed the title
[-][Security] Admin actions do not record who performed them[/-][+]Record the actor of every admin write action[/+]on Oct 6, 2026 - addedenhancementNew feature or requestNew feature or requestSecuritySecurity, access control, and data exposureSecurity, access control, and data exposureand removedbugSomething isn't workingSomething isn't working
on Oct 6, 2026 Status: fixed in
fd96138onclaude/youthful-lovelace-3nvsc6(fix plan step 1 only). Not merged or deployed yet.What shipped:
adminAuthMiddlewareinapps/hocuspocus.server/src/api/middleware/adminAuth.tswrites oneAdmin actionline throughadminLoggerafterawait next(). It runs for every non-GET admin request. The fields areactor,method,path,statusandrequestId. A 4xx or 5xx result is logged with its status.Differences from the plan:
- There is no separate target field. For single-target routes, the target id is in
path:POST /api/admin/users/:id/toggle-admin,PATCHandDELETE /api/admin/documents/:id, andDELETE /api/admin/audit/ghost-accounts/:id. - Other write routes take their targets from the JSON body, so their line names no target. These are
/documents/stale/bulk-delete,/audit/ghost-accounts/bulk-delete,/audit/ghost-accounts/resend-confirmation,/audit/ghost-accounts/cleanup-anonymousand/audit/notifications/disable-failed. - Step 2 (the
admin_audittable) was not built. The record lasts only as long as the server logs are kept. - Step 3 was optional and was not done.
Check after deploy: do one admin write in the dashboard. Then find its
Admin actionline with your user id asactor.
Generated by Claude Code
- There is no separate target field. For single-target routes, the target id is in
- added 2 commits that reference this issue
on Oct 9, 2026
Metadata
Metadata
Assignees
Labels
DevOpsSecuritySecurity, access control, and data exposureSecurity, access control, and data exposureenhancementNew feature or requestNew feature or request
Summary
No admin write action records its actor. If an admin session is stolen, or an admin makes a mistake, nobody can tell who granted admin, purged a document or deleted an account.
apps/hocuspocus.serveradmin APIWhere
pinoLogger(apps/hocuspocus.server/src/middleware/index.ts:122-171) logsrequestId,method,path,statusandip, but no user.adminAuthMiddlewaresetsuserIdatapps/hocuspocus.server/src/api/middleware/adminAuth.ts:58and never logs it.toggleAdminRole—apps/hocuspocus.server/src/api/services/adminStats.service.ts:393-420deleteGhostAccount—apps/hocuspocus.server/src/api/services/adminGhostAccounts.service.ts:276-315admin_usersrow, so evencreated_by(packages/supabase/scripts/02-z-admin-users.sql:17) disappears.Fix plan
adminAuthMiddleware, afterawait next(), log one line for every non-GET request:actor(user id),method, route path, target id (from params),statusandrequestId. Use the existingadminLogger.admin_audittable (id,actor_id,action,target_type,target_id,status,request_id,created_at). Service role writes it. No client grant. No UPDATE or DELETE.Repo rules for step 2: new migration plus
packages/supabase/scripts/mirror, thenbun run --filter @docs.plus/supabase_back types.Acceptance criteria
Generated by Claude Code