Admin Overview
Overview of the admin panel features including user management, organization oversight, and platform analytics.
The Admin Panel provides system administrators with tools to manage users, organizations, and monitor platform activity. Access it at /admin when signed in with an admin account.
This documentation covers the admin system built on Better Auth's admin plugin with MakerKit's RBAC layer.
Getting Started
Creating Your First Admin
After running pnpm seed, use these test credentials:
- Email:
admin1@makerkit.dev - Password:
testingpassword
To promote an existing user to admin:
- Run Drizzle Studio:
pnpm --filter "@kit/database" run drizzle:studio - Open the
userstable - Set the
rolecolumn toadminfor your user - Sign out and back in to refresh the session
Alternatively, use the Better Auth CLI or API to update roles programmatically.
Admin Role Verification
When a user accesses /admin/* routes, the system verifies admin status through multiple layers:
- Middleware (
proxy.ts) checks if the user has an admin role - Server Components use
requireAdmin()to validate and redirect if unauthorized - Server Actions use
adminActionClientwhich verifies the user's role before executing
Dashboard Metrics
The admin dashboard at /admin displays four key metrics:
| Metric | Description |
|---|---|
| Total Users | All registered user accounts |
| Active Sessions | Sessions created in the last 24 hours |
| Banned Users | Accounts with restricted access |
| New This Week | Sign-ups from the past 7 days |
These metrics are loaded server-side using React's cache() function to prevent duplicate queries within the same request.
Architecture
The admin system is organized across several packages:
packages/admin/ # Admin UI components and logic├── src/│ ├── dashboard/ # Dashboard page and metrics│ │ ├── lib/│ │ │ ├── actions/ # Server actions│ │ │ ├── loaders/ # Data loaders│ │ │ ├── schemas/ # Zod schemas│ │ │ └── services/ # Business logic│ │ └── page.tsx # Dashboard component│ ├── users/ # User management│ ├── organizations/ # Organization management│ └── hooks/ # Client-side hookspackages/rbac/ # Role-based access control├── src/│ ├── admin/ # Admin RBAC utilities│ │ ├── factory.ts # Config factory│ │ ├── defaults.ts # Default resources/actions│ │ └── client.ts # Permission checking│ └── admin-rbac.config.ts # Your customization filepackages/auth/ # Authentication utilities├── src/utils/│ ├── require-admin.ts # Server-side admin check│ └── is-admin-role.ts # Role validationpackages/action-middleware/ # Server action utilities├── src/│ ├── require-admin-action-middleware.ts # Admin action client│ └── require-admin-permission-middleware.ts # Permission middlewareCore Features
User Management
The Users section (/admin/users) provides full control over user accounts:
- Search: Find users by name or email
- Filter: By role (user/admin) and status (active/banned)
- Sort: By name, email, creation date, role, or status
- Paginated results: 25 users per page
Available actions per user:
| Action | Description |
|---|---|
| View Details | Full user profile with sessions and subscriptions |
| Change Role | Promote to admin or demote to user |
| Impersonate | Sign in as the user for debugging (restrictions apply) |
| Ban/Unban | Restrict or restore account access |
| Remove | Permanently delete the account |
| View Sessions | See all active sessions |
| Revoke Sessions | End specific or all sessions |

See User Management for detailed documentation.
Organization Management
The Organizations section (/admin/organizations) lets you oversee all teams:
- Search: Find organizations by name
- View Details: See organization info, members, and subscriptions
- Member Access: Click through to any member's user details

See Organization Management for detailed documentation.
Role-Based Access Control
Admin permissions are configured via RBAC in packages/rbac/src/admin-rbac.config.ts. The default configuration provides a single admin role with full permissions. You can add custom roles with restricted access:
import { defineAdminRBACConfig } from './admin/factory';export default defineAdminRBACConfig({ // Add custom roles with limited permissions roles: { support: 50, // Can help users but not delete moderator: 30, // Can ban but limited access }, permissions: { support: { user: ['list', 'get', 'ban'], session: ['list', 'revoke'], organizations: ['list', 'view'], dashboard: ['view'], }, },});See RBAC Permissions for detailed documentation on customizing admin roles.
Navigation
The admin sidebar includes:
- Dashboard (
/admin) - Overview and statistics - Users (
/admin/users) - User management - Organizations (
/admin/organizations) - Organization oversight
Click "Back to Dashboard" in the sidebar header to return to your regular account.
Security Layers
The admin panel includes multiple security layers:
1. Route Protection (Middleware)
The middleware in apps/web/proxy.ts blocks non-admin access to /admin/* routes:
// Simplified from apps/web/proxy.tsif (pathname.startsWith('/admin')) { const isAdmin = await isUserAdmin(); if (!isAdmin) { return NextResponse.redirect(new URL('/auth/sign-in', request.url)); }}2. Server-Side Checks
requireAdmin() verifies admin status in server components and redirects to a 403 page if unauthorized:
import { requireAdmin } from '@kit/auth/require-admin';export default async function AdminPage() { await requireAdmin(); // Redirects if not admin // ... render admin content}3. Action Protection
adminActionClient protects all server actions:
import { adminActionClient } from '@kit/action-middleware';export const myAdminAction = adminActionClient .inputSchema(schema) .action(async ({ ctx }) => { // ctx.user is guaranteed to be admin });4. Permission Checks
withAdminPermission() enforces granular RBAC permissions:
import { adminActionClient, withAdminPermission } from '@kit/action-middleware';export const banUserAction = adminActionClient .use(withAdminPermission({ user: ['ban'] })) .inputSchema(schema) .action(async ({ ctx }) => { // Only admins with 'user:ban' permission reach here });5. Impersonation Safeguards
The impersonation feature includes restrictions:
- Cannot impersonate admin users
- Cannot impersonate banned accounts
- A banner appears during impersonation showing the original admin
Key Imports
| Import | Package | Purpose |
|---|---|---|
requireAdmin | @kit/auth/require-admin | Server-side admin check with redirect |
isUserAdmin | @kit/auth/require-admin | Server-side check without redirect |
isAdminRole | @kit/auth/is-admin-role | Client-safe role validation |
adminActionClient | @kit/action-middleware | Protected action client |
withAdminPermission | @kit/action-middleware | Permission middleware |
useAdminPermissions | @kit/admin/hooks/use-admin-permissions | Client permission hook |
For implementation details on adding custom features, see Extending Admin.
Frequently Asked Questions
How do I create my first admin user?
What's the difference between requireAdmin and adminActionClient?
Can I have multiple admin roles with different permissions?
How do I protect a custom admin page?
Can admins impersonate other admin users?
This admin panel is part of the Next.js Drizzle SaaS Kit.
Next: User Management