Login System & RBAC
Last updated July 17, 2026
Overview
Classgrid uses separate login entry points for students, faculty, organization administrators, and department teams. The portal path helps a user start in the right experience, but the backend is the security boundary. Every protected API request is authenticated and then checked against the user's effective role and organization.
The system uses:
- A signed JWT containing the user ID, primary role, and organization ID.
- An
HttpOnlyauthentication cookie namedtoken. - A bearer-token fallback through the
Authorizationheader. - Organization and tenant checks to prevent a user from signing in through another institution's subdomain.
- Role middleware that rejects protected operations unless the user's effective role is allowed.
The frontend also receives the token in successful login responses and currently stores it in localStorage for API use. Treat that token as sensitive and never print it in logs, support tickets, screenshots, or browser console output.
The 10 Login Portals
These are the ten institution-facing login paths currently registered in the frontend:
The department paths are login entry points. They do not replace server-side permission checks. A user who enters the wrong portal is rejected when the login request declares a conflicting audience or role. After login, API middleware remains responsible for access control.
The platform also has a separate Super Admin login path:
Super Admin accounts are platform-level accounts and are not part of an institution's ten portals. On a tenant subdomain, the backend blocks Super Admin login and directs the user to the Super Admin portal.
Role naming note
The current backend role keys are specific values such as admission_head, fee_manager, and exam_controller. Generic values such as dept_admissions or dept_fees are not the backend's source-of-truth role keys.
The Members page loads the allowed role list from:
Use the returned value exactly. Do not manually create accounts with a role string that is not returned by the organization configuration.
Role-Based Access Control (RBAC)
How Roles Work
Each user has a primary role, and the user record may also contain additional_roles. The primary role determines the main dashboard and is the role used by the core requireRole() middleware. The frontend can display additional roles in its role switcher, but an additional role should not be assumed to grant access to an API unless the corresponding backend route explicitly supports it.
The main role categories are:
The roles available for invitation vary by organization type. The server maintains the role definitions and organization mappings in its centralized role utility. Current organization types include school, junior college, engineering, diploma, and coaching configurations.
API Security
Protected routes normally use middleware in this order:
The checks work as follows:
isAuthenticatedobtains a token from theAuthorization: Bearer ...header or thetoken/jwtcookie.- The JWT signature and expiry are checked with the server's
JWT_SECRET. - The server loads the user from MongoDB and removes sensitive fields such as the password before placing the user on
req.user. - The middleware checks account status, organization status, maintenance mode, global security locks, and recorded password-change invalidation data.
requireRole(...roles)obtains the effective role and allows the request only when it matches one of the route's required roles.requireOrganizationcan be used to require an organization association. Super Admin and Organization Admin accounts bypass that specific association check.
If the check fails, the usual responses are:
Effective role and impersonation
The middleware supports controlled impersonation. During impersonation:
req.userrepresents the account being viewed for data access.req.realUseridentifies the real administrator.getEffectiveRole(req)returns the real administrator's role for permission checks.- The response includes
X-Impersonation: trueso the frontend can show the impersonation state.
This prevents a user being granted or denied permissions based only on the account currently being viewed.
Tenant and organization isolation
When a user signs in through an organization subdomain, the backend resolves that subdomain to an organization. The user must belong to that same organization. A valid password is not enough to sign in through another institution's tenant.
The JWT stores the organization as:
The backend treats organizationId from the verified JWT as the authoritative effective organization ID for middleware checks. Controllers still scope database queries to the authenticated user's organization.
Authentication Flow
1. Select the correct portal
Use the login route that matches the account type. For example:
The frontend selects an authentication intent from the audience and role. Student and faculty requests use standard-user intent; institution administration requests use admin intent; platform accounts use Super Admin intent.
2. Optional email-first check
The frontend can first call:
with:
For an existing account, the response identifies whether a password exists and returns the account role. For an unknown address, the server returns a non-authenticated response and may send a rate-limited security notification. This flow should not be used to reveal account details to other people.
3. Submit credentials
The password login endpoint is:
The frontend sends the email, password, login intent, and selected portal context. A typical request contains fields similar to:
The backend:
- Normalizes the email to lowercase.
- Compares the password with the stored bcrypt hash.
- Applies failed-login tracking and temporary locking.
- Rejects a user who selected an incompatible portal or login type.
- Rejects suspended or blocked users.
- Checks maintenance and global security settings.
- Checks the user's organization status.
- Enforces tenant matching when the request came from an organization subdomain.
- Requires email verification unless the account was created as a trusted admin invitation or has another trusted state.
After five failed attempts, the account can be temporarily locked for five minutes. After several failed attempts, the response can show a password-reset hint.
4. Verify a new device when required
For a non-sandbox, non-internal account, a device fingerprint that is not already trusted can trigger email OTP verification. The login response then indicates:
The OTP is six digits and expires after 60 seconds. The relevant endpoints are:
The verification endpoint accepts the email and OTP. On success, the device fingerprint is added to the user's trusted devices and the normal login token is issued. OTP requests are rate-limited; repeated resend attempts can require a waiting period.
5. Issue the JWT and cookie
The token is signed with the server's JWT_SECRET and contains:
Current token lifetimes are:
The server sets an HttpOnly token cookie. In production it also uses Secure and SameSite=None. For Classgrid subdomains, the production cookie can be scoped to .classgrid.in so it works across the platform's subdomains. Custom domains are not given the .classgrid.in cookie domain.
The successful JSON response also includes the token and user summary. The current frontend stores that token in localStorage and sends it through the API client when required.
6. Use the authenticated session
The frontend can load the current session from:
This response includes the user's primary role, additional_roles, organization branding data, organization association, profile state, and whether a password reset is required.
Every protected request must continue to carry the session cookie or a valid bearer token. A frontend redirect alone never grants access.
7. Log out
Use:
The server clears the host-only token cookie and, in production, the .classgrid.in scoped token cookie. The client should also remove its locally stored token and return the user to the appropriate login page.
Department User Creation
Organization Admins create staff and department accounts from the Members page:
Step 1: Load allowed invitation roles
The Members page requests:
Only roles appropriate for the organization's configured type are returned. The invitable=true filter excludes student, org_admin, and super_admin from the manual staff invitation list.
Step 2: Send the invitation
The Organization Admin submits:
with:
The name, email, and role are required. The department is optional. The server scopes the new account to the Organization Admin's organization_id, rejects an email that already exists, creates the account as active and verified, and sets mustResetPassword so the invitee must establish a password.
The server generates an activation token and sends an invitation email. The activation link is intended to expire after 24 hours. The invitee should use the link, set a password of at least eight characters, and then sign in through the portal appropriate to the assigned role.
Step 3: Track pending invitations
Pending staff accounts can be viewed with:
An account is pending while mustResetPassword is true. After activation, it appears in the active member list:
The Organization Admin can resend an invitation:
or remove a member/invitation:
An Organization Admin cannot remove their own account through this member endpoint.
Password setup for invited users
An invited user whose mustResetPassword flag is true must set a password before normal dashboard access. The authenticated forced-reset endpoint is:
The minimum password length enforced by this endpoint is eight characters. After the password is set, the flag is cleared.
Students can also be created by enrollment and admission workflows. Those flows create a student account, associate it with the organization, and can require a password reset on first access. They are separate from the Organization Admin staff invitation flow.
Troubleshooting Login Issues
"Please use the correct portal"
The account role does not match the selected login tab or expected login type. Use the portal assigned to the account:
- Students use
/student/login. - Teaching staff use
/faculty/login. - Organization and department administrators use the relevant admin or department path.
- Super Admins use
/superadmin/login.
The backend, not the URL alone, decides whether the login is allowed.
401 Not authenticated or Token invalid
Check the following:
- The browser still has the
tokencookie or the API client still has a valid bearer token. - The token has not expired.
- The request is sending
Authorization: Bearer {token}when cookie credentials are unavailable. - The user still exists and has not had the session invalidated by a recorded password change.
Sign out, clear the Classgrid token from browser storage, and sign in again. Do not copy a token into a support message.
Account temporarily locked
Repeated incorrect passwords increment the login-attempt counter. After five failed attempts, the account can be locked for five minutes. Wait for the lock to expire or use the password-reset flow instead of repeatedly retrying.
Device OTP does not arrive
Confirm that the email address is correct and check spam or quarantine folders. A new-device OTP expires after 60 seconds. Resend requests are rate-limited, so wait for the retry timer before requesting another code.
The account is inactive, suspended, or blocked
The authentication middleware rejects accounts whose status is not active. It also rejects users whose organization is suspended or blocked. An Organization Admin should contact the platform administrator or support team rather than attempting to bypass the status check.
Faculty or teacher is asked for an organization code
The login response can return needsOrgCode: true when a faculty or teacher account has no organization_id. Complete the organization-linking flow or ask the Organization Admin to provide the correct organization code. Do not use another institution's code.
Invitation link is expired or already used
Ask the Organization Admin to use Resend for the pending member. The server generates a fresh activation token for the invitation. Make sure the invitee uses the newest email link.
The platform reports maintenance or a security lock
Maintenance mode and the global security lock are enforced by the authentication middleware. Non-Super Admin users cannot bypass them. Wait for the platform administrator to restore access.
Login works but an API returns 403 Access denied
The session is authenticated, but the effective role is not allowed for that operation. Confirm the user's primary role, organization association, and the route's required roles. Adding a label in the frontend does not grant backend permission.
Cookies fail on a custom domain
The .classgrid.in cookie domain is used only for Classgrid platform subdomains. A custom domain receives its own host-scoped cookie. Confirm that the browser accepts secure cookies over HTTPS and that the API client is configured to send credentials for the custom host.
Security Checklist
- Use HTTPS in production.
- Use a strong, unique
JWT_SECRETand keep it outside source control. - Never log JWTs, passwords, OTPs, activation tokens, or raw reset links.
- Assign roles from
GET /api/hierarchy/roles?invitable=truerather than typing role strings manually. - Keep each user linked to the correct organization.
- Remove or suspend accounts promptly when staff leave the institution.
- Keep the Organization Admin emergency login path available during tenant or custom-domain changes.
- Treat
localStoragetokens as sensitive because the current frontend stores the API token there in addition to theHttpOnlycookie.