App Administrators and RBAC
Configure App administrators, management entry points, and route permissions
EasyStarter's App and Web clients share one global RBAC system. The Server stores either user or admin on each account, and the App uses the session role to display administrative entry points.
Configure App administration
Enable the shared feature switches
Update 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"],
},
},
}apps/native/configs/app-config.ts reads these shared values and exposes adminUserManagementEnabled and adminPaidUsersEnabled.
Keep defaultRole set to "user" so new accounts do not become administrators automatically.
Configure the initial administrator on the Server
For local development:
ADMIN_EMAIL=admin@yourcompany.comFor production:
ADMIN_EMAIL=admin@yourcompany.comUpload the production secret:
pnpm -F server secrets:bulk:productionADMIN_EMAIL is a server secret. Do not place it in apps/native/.env* or any EXPO_PUBLIC_* variable.
Use the verified email of a real account, not the sender address or supportEmail. Only one email is supported.
Activate the administrator in the App
After setting ADMIN_EMAIL, redeploy the Server.
If the user has already signed in to the App, ask them to sign out and sign in again. The new session contains the admin role, and the Profile screen then displays the administrative entry points.
Administrative entry points in the App
apps/native/app/(tabs)/(profile)/index.tsx checks authentication, the feature switch, and the permission together:
const canManageUsers =
isAuthenticated &&
appConfig.adminUserManagementEnabled &&
hasPermission(user?.role, "user", "list");
const canViewPaidUsers =
isAuthenticated &&
appConfig.adminPaidUsersEnabled &&
hasPermission(user?.role, "admin", "access");The App administration area currently includes:
- User management
- Paid-user management
- Credit adjustments and Membership trial grants
- Administrative operation history
Protect App administration screens
Do not only hide the Profile menu. The administration route layout should also require admin:access:
if (!isAuthenticated) {
return <Redirect href="/(auth)/sign-in" />;
}
if (!hasPermission(user?.role, "admin", "access")) {
return <Redirect href="/(tabs)/(profile)" />;
}
return <Slot />;Use AdminFeatureStack in each feature's _layout.tsx to enforce its feature switch:
<AdminFeatureStack enabled={appConfig.adminUserManagementEnabled}>
<Stack.Screen name="index" />
</AdminFeatureStack>These App checks only control navigation and rendering. Every user, role, ban, credit, and Membership operation must be authorized again by the server-side oRPC procedure.
Default permissions
| Permission | Purpose in the App |
|---|---|
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 user role has none of these administrative permissions. The admin role has all default administrative permissions.
Revoke an administrator
Removing or changing ADMIN_EMAIL does not revoke an existing administrator. Change the old administrator's role back to user before updating the server environment variable.
After a role change, have that user sign out and sign in again in the App to refresh the local session and administrative entry points.