Security

Updated March 31, 2026

9 min read

Admin User Management

Create, manage, and assign roles to admin users. Understand the permission model and user lifecycle.

user managementadmin rolespermissionsuser accountsrbac
Overview

Handover supports multiple admin users with different permission levels. Use this to give clients and team members appropriate access to the admin interface.

User Roles

Handover has four built-in roles with different permission levels.

  • Owner - Full access, created via bootstrap, cannot be deleted
  • Admin - Can manage users and content
  • Editor - Can edit content but not manage users
  • Viewer - Read-only access to content and settings

Creating Users

Only owners and admins can create new users. Username must be unique within the project.

await handover.createAdminUser(
  sessionToken,
  "editor-username",
  "SecurePass123!",
  "editor"  // role: owner | admin | editor | viewer
);
typescript

Updating User Roles

Change a user's role or status (active/disabled). Disabled users cannot log in but their account is preserved.

await handover.updateAdminUser(
  sessionToken,
  userId,
  {
    role: "admin",     // optional
    status: "disabled" // optional: active | disabled
  }
);
typescript

Password Reset

Admins and owners can reset passwords for other users. This revokes all active sessions for that user.

For self-service password reset, generate a one-time reset token valid for 24 hours.

// Direct reset (requires admin session)
await handover.resetAdminPassword(
  sessionToken,
  userId,
  "NewSecurePass123!"
);

// Generate reset token
const { token, expiresAt } = await handover.createPasswordResetToken(
  sessionToken,
  userId
);
// Send token to user via email/SMS

// User resets with token
await handover.resetPasswordWithToken(
  resetToken,
  "NewSecurePass123!"
);
typescript

Deleting Users

Remove users who no longer need access. Owner accounts cannot be deleted to prevent lockout.

await handover.deleteAdminUser(sessionToken, userId);
typescript

Listing Users

View all admin users for the project with their roles, status, and last login time.

const users = await handover.listAdminUsers(sessionToken);

users.forEach(user => {
  console.log(`${user.username} - ${user.role} - ${user.status}`);
});
typescript
Source doc

This page maps to convex/adminUsers.ts in the repository.