Administrators and RBAC
Configure Web administrator roles, permissions, and management features
EasyStarter includes global RBAC with two roles: user and admin. Each account stores exactly one role.
Configure RBAC
Enable admin features
Update appConfig.common in packages/app-config/src/app-config.ts:
common: {
admin: {
// Enable paid-user management
paidUsers: {
enabled: true,
},
// Enable user management and administrative operation history
userManagement: {
enabled: true,
},
},
auth: {
// Other authentication settings…
rbac: {
defaultRole: "user",
adminRoles: ["admin"],
},
},
}userManagement.enabled controls user management and administrative operation history. paidUsers.enabled controls paid-user management. Disabling a feature removes both its pages and APIs.
Keep defaultRole set to "user". Changing it to "admin" would grant administrative permissions to every new account.
Configure the initial administrator email
Set ADMIN_EMAIL to the real account email that will sign in to the admin area:
ADMIN_EMAIL=admin@yourcompany.comFor production, set it in:
ADMIN_EMAIL=admin@yourcompany.comThen upload the Cloudflare secret:
pnpm -F server secrets:bulk:productionADMIN_EMAIL is not the sender address or supportEmail. It must match the verified email of the account that signs in.
Only one email is supported. Do not provide a comma-separated list. After the initial administrator signs in, use user management to assign the admin role to other accounts.
Activate the administrator role
After setting ADMIN_EMAIL, redeploy the Server.
If the user has already signed in, ask them to sign out and sign in again. The Server updates the account's role to admin when it creates the new session.
Default permissions
| Permission | Purpose | user | admin |
|---|---|---|---|
admin:access | Enter administrative areas | ✗ | ✓ |
user:list | List users | ✗ | ✓ |
user:set-role | Change user roles | ✗ | ✓ |
user:ban | Ban and unban users | ✗ | ✓ |
credits:adjust | Adjust credits | ✗ | ✓ |
membership:grant-trial | Grant a Membership trial | ✗ | ✓ |
operation:list | View administrative operations | ✗ | ✓ |
The permission vocabulary and role matrix live in packages/app-config/src/rbac/index.ts.
How Web uses RBAC
The Web sidebar checks both the feature switch and the current user's permission. Each route repeats the check in beforeLoad:
beforeLoad: ({ context }) => {
if (!webConfig.adminUserManagementEnabled) {
throw notFound();
}
if (!hasPermission(context.user.role, "user", "list")) {
throw redirect({ to: "/forbidden" });
}
},Client checks are only for navigation and user experience. The server must enforce the permission independently.
import { assertPermission, protectedProcedure } from "@/lib/orpc";
export const adjustCredits = protectedProcedure.handler(async ({ context }) => {
assertPermission(context, "credits", "adjust");
// Business logic
});For general administrative access, use adminProcedure. It requires the current account to have admin:access.
Revoke an administrator
Removing or changing ADMIN_EMAIL does not revoke an existing administrator. Change the old administrator's role back to user in user management before updating the environment variable.