Skip to main content
The SMS platform uses two separate authentication layers: one for platform (system) administrators and one for school (tenant) users. Both use JWT for stateless sessions. Optional API keys allow server-to-server or script access.

Authentication layers

1. System authentication — /api/v1/system/auth/

For platform administrators only (e.g. superusers, support staff). These users have no client (tenant) in the database.
  • Login: POST /api/v1/system/auth/login/ with credentials. Returns JWT access and refresh.
  • Me: GET /api/v1/system/auth/me/ — current platform user (no tenant context).
  • Refresh: Use the system refresh endpoint (if exposed) with {"refresh": "<token>"} to get a new access token.
Users who have a client (school users) must not use system auth. The API returns 403 Forbidden if a school user tries to log in via system auth.
Use the public domain (e.g. main app host) for system auth, not a tenant subdomain.

2. School authentication — /api/v1/school/auth/

For tenant users (teachers, principals, office staff). Each user has a client pointing to one school.
  • Login: POST /api/v1/school/auth/login/ on the tenant domain (or with tenant set via JWT/header). Returns JWT pair and tenant-scoped profile (e.g. roles, teacher profile).
  • Me: GET /api/v1/school/auth/me/ — current user and tenant context (roles, teacher info).
  • Refresh: POST /api/v1/school/auth/refresh/ with {"refresh": "<refresh_token>"} to get a new access token.
A JWT issued for School A must only be used on School A’s domain (or with that tenant’s schema). Using it on School B’s domain will not grant access to School B’s data; tenant isolation is enforced.

3. API key authentication (optional)

For programmatic access (e.g. chatbot, scripts, integrations):
  • Header: X-API-KEY: <your-api-key>.
  • API keys are managed via the system API (e.g. APIKeyViewSet under system routes). Keys can be scoped or global depending on implementation.
  • Use when you need long-lived, non-interactive access instead of JWT.

User model

  • Identifier — Users can be identified by email and/or phone (unified identifier backend).
  • clientnull for platform admins; set to a Client for school users.
  • Platform roles — For system users (e.g. superadmin, platform admin). School roles — Assigned per tenant via RBAC (Core module).

Token management (JWT)

After login you receive:
  1. access — Short-lived. Send as Authorization: Bearer <access> on every request.
  2. refresh — Long-lived. Use only to get a new access token when it expires.
Example refresh (school):
POST /api/v1/school/auth/refresh/
Content-Type: application/json

{
  "refresh": "<your_refresh_token>"
}
Response includes a new access (and sometimes refresh) token.

RBAC (school/tenant)

Inside a tenant, access is controlled by School roles and permissions:
  • SchoolRole — Named roles (e.g. Teacher, Head, Admin) with assigned permissions.
  • UserRoleAssignment — Links users to roles within that tenant.
  • Views check dynamic model permissions: the user’s roles must allow the HTTP action (GET, POST, PUT, PATCH, DELETE) on the resource.
Cross-tenant: a user’s roles in School A do not apply in School B; each tenant has its own role and permission set.