Authentication and Access Control
Authentication
Section titled “Authentication”Sylva uses a combination of custom authentication and Firebase Authentication for user login and session management.
Login Methods
Section titled “Login Methods”Email/Password Login
- Users authenticate via the
/SystemUsers/LoginAPI endpoint - Upon successful login, the system returns a
userIdandtoken - The system then checks organization access via
/SystemUsers/{userId}/checkOrgAccess/{organizationId} - If the user has access to the organization, authentication proceeds
Firebase Authentication
- After successful login, Sylva uses Firebase Authentication for session management
- Custom tokens are generated via
/SystemUsers/{userId}/fbAuthToken/{organizationId} - The frontend signs in with the custom token using
firebase.auth().signInWithCustomToken() - Firebase handles session persistence and token refresh
Email Link Authentication
- Users can authenticate using email links sent to their email address
- The system supports password reset via email links
Current User API
Section titled “Current User API”The /SystemUsers/currentUser endpoint provides the current authenticated user’s information:
- Parameters: Optional
_orgparameter to specify organization context - Response: User object containing:
- User ID, name, email
- Roles (system, organization, and course roles)
- Organization information
- Access permissions
The current user data is injected into all API requests and stored in the application state.
Session Management
Section titled “Session Management”- User sessions are managed through Firebase Authentication
- The current user is fetched on application initialization
- Organization context (
_org) is automatically added to API request headers - Session data is stored in the application state and persisted across page reloads
Access Control
Section titled “Access Control”Sylva implements a multi-level role-based access control (RBAC) system with three distinct role levels. While these role levels don’t follow a strict hierarchy, permissions are inherited based on the hierarchical context: System > Organization > Course.
Role Architecture
Section titled “Role Architecture”The three role levels are:
- System Roles - Applied at the environment level (beta, production, etc.)
- Organization Roles - Applied within an organization context
- Course Roles - Applied within a specific course/project
System Roles
Section titled “System Roles”System roles are assigned at the environment level and apply across all organizations within that environment.
| Role | Description | Storage |
|---|---|---|
superadmin | Special role that allows access to the whole environment | MongoDB SystemAccess collection |
developer | Adds special debugging options to all apps | MongoDB SystemAccess collection |
sylvauser | Base role that all invited users inherit | MongoDB SystemAccess collection |
creouser (deprecated) | Used to allow users to access CREO | MongoDB SystemAccess collection |
Notes:
- System roles are assigned separately for each environment (e.g., beta, production, CH, US)
- Roles are injected into each user via the
/currentUserAPI endpoint - Role assignments are stored in a MongoDB collection called
SystemAccess
Organization Roles
Section titled “Organization Roles”Organization roles control access and permissions within a specific organization.
| Role | Description | Permissions |
|---|---|---|
admin | Full organization access | Can create/delete courses, view/edit all courses in the org, access org settings |
moderator | Content management access | Can view/edit all courses |
auditor | Read-only access | Can view all courses, but cannot access the editor and cannot invite/delete users |
creator | Limited creation access | Can create courses but does not have access to other courses except their own |
Notes:
- Organization roles are assigned separately for each environment
- Roles are injected via the
/currentUserAPI with an_orgparameter - The
_orgparameter is automatically added to all API request headers - Role assignments are stored in a MongoDB collection called
OrganizationAccess
Course Roles
Section titled “Course Roles”Course roles control access and permissions within a specific course/project.
There are two important “layers” of course/project roles in the frontend:
- Raw project roles: values coming from backend storage (
ProjectAccess) and assigned by invitation/admin UIs. - Effective access roles: a normalized set used by route guards and UI logic.
In other words: a user might be assigned the raw role student, but the app will treat them as effective participant.
Raw project roles (assigned)
Section titled “Raw project roles (assigned)”These are the role values you actually assign at the project level (e.g. from the project People/invitation UI):
| Raw role | UI label (typical) | Notes |
|---|---|---|
student | Participant | Mapped to effective participant |
guest | Participant (guest) | Mapped to effective guest |
contentmanager | Staff | Common “staff” assignment in UI |
lecturer | Staff | Staff category |
owner | Staff | Typically assigned automatically on create |
projectadmin | Staff | Staff category |
teachingassistant | Staff | Staff category |
reviewer | Reviewer | Reviewer access (not a participant) |
grader | Grader | Grader access (not a participant) |
Effective access roles (used for access checks)
Section titled “Effective access roles (used for access checks)”The frontend normalizes raw project roles to an effective role via CourseRoleMap (session store). These effective roles are what most guards/visibility checks use:
| Effective role | Meaning |
|---|---|
staff | Course staff / course admin capabilities (depending on route/feature) |
participant | Regular participant experience |
reviewer | Reviewer experience (restricted participation) |
grader | Grader experience (restricted participation) |
guest | Guest participant experience |
Raw → effective role mapping (canonical)
Section titled “Raw → effective role mapping (canonical)”Canonical mapping used by the frontend:
| Raw role | Effective role |
|---|---|
owner | staff |
projectadmin | staff |
lecturer | staff |
contentmanager | staff |
teachingassistant | staff |
grader | grader |
reviewer | reviewer |
student | participant |
guest | guest |
Notes:
- Course roles are assigned separately for each course/project
- Roles are injected via the
/linkedProjectsAPI endpoint - Role assignments are stored in a MongoDB collection called
ProjectAccess
Dashboard Access (new staff dashboard vs participant dashboard)
Section titled “Dashboard Access (new staff dashboard vs participant dashboard)”Sylva has two dashboard experiences:
- New dashboard (“staff dashboard”): designed for staff workflows and quick links.
- Participant dashboard: the participant-first view (welcome card / start-focused experience).
The app decides which dashboard to show based on organization role and project-level effective role.
Testable rules (who sees which dashboard)
Section titled “Testable rules (who sees which dashboard)”New dashboard is shown if any of the following is true:
- Organization role is one of:
adminmoderatorauditorcreator
- OR the user has at least one linked project where the effective project role is:
staffreviewer
Participant dashboard is shown otherwise, i.e. when:
- the user has no qualifying organization role, and
- all linked projects map to effective roles in:
participantguestgrader(graders do not get the staff dashboard)
Why this matters (historical bug)
Section titled “Why this matters (historical bug)”A previous implementation attempted to infer staff access using a loose rule like “not participant-like ⇒ staff-ish”. That is unsafe because:
- unknown/legacy/unexpected role strings can appear under
project.roles,project.role, or nestedaccess.rolefields - “not participant” is not equivalent to “staff”
The current logic avoids this by:
- normalizing raw roles
- mapping them through the canonical
CourseRoleMap - making decisions against a small, explicit set of effective roles
Implementation Details
Section titled “Implementation Details”API Integration
Section titled “API Integration”All API requests automatically include:
- Authentication token from the current session
- Organization context (
_orgheader) when available - User role information injected via the
/currentUserendpoint
Frontend Implementation
Section titled “Frontend Implementation”The authentication and access control system is implemented in the Vue.js frontend:
- Session Store: Manages current user state and authentication status
- API Interceptors: Automatically add organization context to requests
- Route Guards: Protect routes based on user roles and permissions
- Component Guards: Control component visibility and functionality based on roles
Data Storage
Section titled “Data Storage”Role assignments are stored in MongoDB collections:
SystemAccess- System-level role assignmentsOrganizationAccess- Organization-level role assignmentsProjectAccess- Course/project-level role assignments
Each collection links users to their roles within the respective context.
See also
Section titled “See also”- Repositories and workspace map — where the frontend and API code live
- Backend API and api-models — how ACLs and models are loaded
- Frontend (Sylva Enterprise) — boot flow, tokens, and
window._org - API reference —
/SystemUsers/login,currentUser,fbAuthToken, etc.