-
Notifications
You must be signed in to change notification settings - Fork 43
docs: add OEP - Multi tenant mobile support #734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
RawanMatar89
wants to merge
2
commits into
openedx:master
Choose a base branch
from
RawanMatar89:oep-multitenant-mobile
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
146 changes: 146 additions & 0 deletions
146
oeps/architectural-decisions/oep-0068-multi-tenant-mobile-support.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
- 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. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@e0d it's probably less complex than it looks like.
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.
There was a problem hiding this comment.
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.