EasyStarter logoEasyStarter
Administrators & RBAC

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:

apps/server/.dev.vars
ADMIN_EMAIL=admin@yourcompany.com

For production:

apps/server/.env.production
ADMIN_EMAIL=admin@yourcompany.com

Upload the production secret:

pnpm -F server secrets:bulk:production

ADMIN_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

PermissionPurpose in the App
admin:accessEnter administrative areas
user:listList users
user:set-roleChange user roles
user:banBan and unban users
credits:adjustAdjust credits
membership:grant-trialGrant a Membership trial
operation:listView 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.