[RFC] Pluginifying edx-enterprise — looking for community interest & collaborators


TL;DR

I’m proposing to convert openedx/edx-enterprise into a plugin using the existing Open edX plugin framework, so that:

  • edx-platform no longer directly imports or requires the enterprise module.
  • Enterprise behavior is provided entirely via well-defined plugin hooks.
  • Operators can install the official plugin, their own fork, or run non-enterprise LMS with zero enterprise code.

This would provide cleaner code boundaries, reduce coupling, and make enterprise functionality truly optional.

The goal of this post is to gather feedback on direction and identify potential collaborators before investing heavily in implementation.


Background: Current Pain Points

Today, edx-enterprise is tightly coupled with edx-platform through direct imports across core modules. The ENABLE_ENTERPRISE_INTEGRATION setting doesn’t fully disable enterprise code paths or imports.

For operators:

  • Customizing or forking edx-enterprise requires maintaining compatibility with upstream module names and function signatures indefinitely.
  • Enterprise code paths cannot be fully switched off, increasing error surface area even for non-enterprise deployments.

For developers:

  • Tight coupling obscures where enterprise code lives and creates risk of unintended side-effects when modifying either enterprise or platform logic.

Proposed Solution

We evaluated simpler alternatives (requirement swaps, patchsets) but found they created unsustainable maintenance burdens. Instead, we propose to convert edx-enterprise into a true plugin, which can be done incrementally in phases:

  1. Define a clear “Enterprise plugin interface” in edx-platform using the existing plugin framework.
  2. Migrate enterprise integration points behind plugin hooks (can be done incrementally).
  3. Remove edx-enterprise from base requirements, making edx-platform agnostic to which (if any) enterprise plugin is installed.

The following edx-platform functionality depends on the enterprise module, and will be the main targets for adding plugin hooks:

  1. Third-party auth (common/djangoapps/third_party_auth)
  2. Courseware access and DSC redirects (lms/djangoapps/courseware)
  3. User API and retirement (openedx/core/djangoapps/user_api)
  4. RBAC role mappings and other enterprise settings (lms/envs/common.py)
  5. Enterprise support Django app (openedx/features/enterprise_support)
  6. Potentially more…

Please see the attached PDF for the full proposal details.


How to Get Involved

Please reply if you have an interest in collaborating, or also if you have any specific feedback/concerns. If there’s positive interest, I may move forward with an Open edX Enhancement Proposal (OEP) to facilitate collaboration. Looking forward to your feedback and seeing if this can become a shared community effort!

SOL-[Discovery] Forking edx-enterprise-260126-224958.pdf (1.2 MB)

8 Likes

+1!. I have for years thought this is the right approach to edx-enterprise. It was one of the first use cases we tried to understand when initially developing the hooks framework. As a maintainer of the events and filters libraries, I’d be happy to help move things along.

If you see that there are things that are required for this migrations that the libraries don’t yet support, I’ll also be happy to remove those blockers.

2 Likes

Big +1 from me as well.

+1. This looks great.

I think this makes a ton of sense, and it will be good to get the interface points needed to make this work moved to openedx-events and openedx-filters.

I agree with everyone else: this is fantastic. Thank you.

FWIW, I think that one or more ADRs in the edx-enterprise repo should be sufficient, as opposed to a full OEP.

Yep, I was just thinking the same.

I think this a great proposal and am very supportive of this approach. Thanks for putting this together.

FYI, my team got the green light to start work on this. This also coincided with gaining claude-code access, so I spent almost a week doing a claude deep-dive and generated about 80% of the overall work as draft PRs. These are designed to be mergeable and deployable incrementally, so no need to do a big bang release.

Some of them are good to go, but most need additional work. While the CI are failing, checks do pass locally where my virtualenvs are wired correctly to install as editable (pip install -e) the libs they depend on. There are other issues, e.g.:

  • Sometimes claude decided to run isort against files which should have been excluded from isort,
  • pluggable_overrides were never actually wired up in plugin_settings,
  • libraries all still need version bumps,
  • etc.

Feel free to take a look and put in some reviews! In the meantime, we’ll spend the next ~month chipping away at all the tickets to carry these over the line.

3 Likes

Have you given any thought to the best approach for releasing these changes? Top of mind as we have a code cut in 5 weeks.

Well, we’ve already started merging—starting with user retirement:

The goal is to leverage the specific 1-month approval for capacity to get as much in as possible, starting last week. Each grouping of PRs are designed to be mergeable and deployable in isolation. It’s inevitable that we cut a release with half of these merged in.

If that’s not okay, then I guess we could just merge to our local edx/edx-platform fork, then do a big bang backport upstream before we trash our release-ulmo branch, but it starts to get confusing.

Here’s what I mean by “trashing” our release-ulmo branch: