Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions oeps/architectural-decisions/oep-0068-multi-tenant-mobile-support.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
.. _OEP-68 Multi-Tenant Mobile Support:

OEP-68: Multi-Tenant Support in Open edX Mobile Apps
####################################################

.. list-table::
:widths: 25 75

* - OEP
- :ref:`OEP-68 Multi-Tenant Mobile Support`
* - Title
- Multi-Tenant Support in Open edX Mobile Apps
* - Last Modified
- 2025-03-18
* - Authors
-
* Rawan Matar <rawan@zeitlabs.com>
* Ivan Stepanok <ivan.stepanok@raccoongang.com>

* - Arbiter
- TBD
* - Status
- Draft
* - Type
- Architecture Decision
* - Created
- 2025-03-18
* - Review Period
- TBD
* - References
-
* `Multi-tenant PR <https://github.com/zeit-labs/openedx-app-ios-contrib/pull/10>`_

.. contents::
:local:
:depth: 1

Abstract
********
This OEP proposes adding **multi-tenant support** to the Open edX mobile applications.
Currently, the apps support only a single institution per build.
This proposal introduces a mechanism for users to select their institution (tenant) at runtime,
with each tenant providing its own branding, configuration, and API endpoints.
This reduces duplication and enables a white-labeling approach
within a single mobile app module.

Motivation
**********
The Open edX mobile app is increasingly used by multiple institutions.
Releasing separate app builds for each tenant creates duplication, higher maintenance burden,
and inconsistent user experience. Multi-tenancy enables:

* A single app build for multiple institutions.
* Dynamic branding (logo, color scheme, names).
* Institution-specific API and authentication endpoints.
* Future extensibility to fetch tenant definitions dynamically.

Current State
=============
- Mobile apps support only one tenant per build (YAML-based config).
- Persistence layer uses a single Core Data/SQLite DB, risking data leakage across tenants.
- Push notification manager doesn’t account for tenant context.
- Branding and login flows are static per build.

Decision
********
We propose supporting **multi-tenancy** in one app build by:

* Providing a tenant selector screen at login.
* Defining tenant metadata (branding, API URLs, auth URLs, etc.) in a JSON configuration file.
* Allowing runtime tenant switching without reinstallation.
* Maintaining isolated databases per tenant.
* Enhancing push notifications with tenant context.

Specification
*************

Tenant Selection
================
- On launch, show a tenant selector if multiple tenants are configured.
- If only one tenant exists, preserve the current flow.

Tenant Configuration
====================
Tenant metadata will be stored in a JSON config file, including:

* ``name`` (tenant_id)
* ``display_name``
* ``logo_url``
* ``primary_color``
* ``api_base_url``
* ``auth_url``

Example::

{
"tenants": [
{
"name": "tenant_a",
"display_name": "University A",
"logo_url": "https://example.com/logo.png",
"primary_color": "#FF5733",
"api_base_url": "https://tenant_a.example.com/api",
"auth_url": "https://tenant_a.example.com/auth"
}
]
}

Database Management
===================
- Each tenant has its own Core Data/SQLite store.
- Database name pattern: ``opendx_{tenant_id}_db``.
- A `DatabaseManagerProvider` maintains tenant-specific DB managers.
- Switching tenants reloads the persistence stack.

Push Notifications
==================
- One device token is maintained.
- Token registered with all tenants.
- Payloads include ``tenant_id``.
- Notifications routed to the correct tenant listener.

Alternatives
************
- Separate app per tenant (high maintenance).
- Remote configuration (scalable but adds backend dependency).
- Custom login screen only (limited branding flexibility).

Impact
******
- **Users**: Access multiple institutions in one app.
- **Institutions**: Branded experiences without custom builds.
- **Developers**: Reduced duplication and simpler long-term maintenance.
- **Backend**: No changes required, except for including ``tenant_id`` in notification payloads.

Future Work
***********
- Fetch tenant metadata dynamically from an API.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a sense of how complex this is? Dynamic addition of tenants feels like the feature that really unlocks the value of a centralized app. It would potentially introduce some bigger questions like "do we need a registry of academies?" However, the technical piece doesn't feel too complicated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a sense of how complex this is?

@e0d it's probably less complex than it looks like.

t would potentially introduce some bigger questions like "do we need a registry of academies?" However, the technical piece doesn't feel too complicated.

I would suggest that we don't have a centralized registry.

I recommend considering the following login flow for the centralized app:

Enter the URL:
Email:
Password:
This is Moodle app workflow and I think it's a good one.

Having a directory in Firebase or any other REST API backend is nice to show an auto-complete on the URL field, but the app should be generic for everyone to include installations of institutions who many not know how to apply i.e. someone who barely speaks English and just wants to try the app on their institute.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the Moodle flow authenticate on the part of the learner? If that's how it works, I would recommend a different approach using OAuth. One would get the URL of the backend, maybe via a QR for ease, and then be directed via the OAuth flow to authorize the mobile app to access the appropriate scopes.

- Allow tenant switching post-login via settings/profile.
- Adopt design tokens for consistent theming across platforms.

Change History
**************
2025-03-18
==========
* Initial draft created based on ADR.