Nutmeg is the latest Open edX named release. It came out June 9th, 2022. In this post we’ll take a look at recent changes to the operator and developer experience (that is, people who write code for Open edX or deploy an Open edX instance). This includes some of the latest and greatest Tutor changes, a spotlight on Open edX events & filters, and some critical notes surrounding deprecations, removals, and security updates.

Tutor Highlights

Changes to Tutor since the Maple release are detailed on the Tutor changelog – versions 13.0.1 through 14.0.0. Some highlights are:

Tutor Features & Improvements

  • A new and expanded “Version 1” plugin API based around the idea of “hooks”, which are extension points that allow plugins to react to Tutor’s actions and to modify Tutor’s behavior using data filters. The old “Version 0” plugin API is still supported, although plugin developers are encouraged to move to the new API.
  • More comprehensive instructions while upgrading
  • Multiple new commands:
    • `tutor  k8s apply`: a direct interface with `kubectl apply`
    • `tutor [dev|local|k8s] status`: provides system information status
    • `tutor dev quickstart`: a variant of `tutor local quickstart` that reduces friction in the development setup process
    • `tutor [local/dev] copyfrom`: copies contents from a container
    • -m/–mount`: an option added to several local and dev commands to auto-magically bind-mount folders from the host, superseding the old `bindmount` command and `–volume` options.
  • `tutor dev start SERVICE` now allows attachment to the service for breakpoint debugging.
  • Starting `dev` containers now stops `local` containers, and vice versa.
  • Ability to install custom packages and run commands as root in the Docker image
  • Ability to override `EDX_PLATFORM_REPOSITORY` and `NPM_REGISTRY` via `config.yml` instead of as Docker build arguments.
  • Ability to hide courses from the LMS’s /course search page by setting course visibility to “none” in Studio.
  • Persistent grades are now enabled by default.

Tutor Deprecations & Breaking Changes

  • `tutor dev runserver` is deprecated in favor of `tutor dev start`.
  • `tutor k8s exec “<some command>”` (with quotes) is deprecated; instead use `tutor k8s exec <some command>`. This aligns with the syntax of `tutor local exec <some command>`.
  • Dropped support for the `TUTOR_EDX_PLATFORM_SETTINGS` environment variable. It is now recommended to create a plugin instead.
  • lms.env.json & cms.env.json are now `lms.env.yml` & cms.env.yml; plugin developers must reformat multiple patches to use YAML format.

And multiple Tutor security & bug fixes; see the Tutor changelog – versions 13.0.1 through 14.0.0 for more.

Open edX Events & Filters

Open edX Events & Filters add a new way of extending the core without having to mess with the internals of edx-platform (this work is part of OEP-50: Hooks Extension Framework).

  • Open edX Events: this standardized version of Django Signals allows developers to extend platform functionality just by listening to the event that’s sent after a key process finishes, e.g after enrollment, login, register, etc.
  • Open edX Filters: through configuration only, extension developers can set a list of functions to be executed before a key process starts, e.g before enrollment, login, register, etc.

For more information, read the OEP, the documentation, or watch Felipe Montoya’s Open edX 2022 Conference Presentation on the background, architecture, and usage of this product.

Important Management Command to Run & Config Var to Set

An internal performance improvement called “learning sequences” has been opt-in for a few releases, but is now always-on for Nutmeg. If you have any courses that have not been re-published on Koa or later, run the simulate_publish cms django command on your courses before upgrading, to populate the learning sequence data.

Failure to set the CLOSEST_CLIENT_IP_FROM_HEADERS config value can result in rate-limiting legitimate traffic or failing to block brute-force attacks, depending on your proxy setup.

Deprecations and Removals

The following deprecations and removals have been made since the Maple release:

  • The edx-certificates repo has been archived
  • Bok-choy (a testing platform) has been archived
  • The django-ratelimit-backend library has been removed from edx-platform; the standard django-ratelimit backend is now in use. This has the side-effect of removing the default Django admin login window; users must now log in first through the LMS.
  • “Old Mongo” course access has finally been fully removed. This means course runs that have keys like Org/Course/Run rather than course-v1:Org+Course+run (visible in the URL of any course page) cannot be accessed by learners.

For more information on these, please see the Deprecations & Removals section of the Nutmeg wiki page.

Security Enhancements

There are two major security enhancements to understand: a new configuration value (CLOSEST_CLIENT_IP_FROM_HEADERS) that must be set, and changes to the SafeSessionMiddleware that require attention prior to upgrading to Nutmeg.

  • CLOSEST_CLIENT_IP_FROM_HEADERS is a new config value that all deployments should set.
    • Failing to set this can result in rate-limiting legitimate traffic or failing to block brute-force attacks, depending on your proxy setup.
    • This is a security-impacting setting that tells your deployment how to determine the IP address of the client. See openedx.core.djangoapps.util.ip for documentation on how (and why) to configure this (as well as the related NUM_PROXIES setting for django-rest-framework).
  • SafeSessionMiddleware is an existing middleware that provides several protections against vulnerabilities that could result from cache misconfigurations or other bugs resulting in one user getting a different user’s session.
    • Previously if a user mismatch was detected between request or session and response, the middleware would log warnings; now, it will invalidate the session and send an error response. The toggle ENFORCE_SAFE_SESSIONS is enabled by default, but can be disabled to return to just log warnings.
    • Before upgrading to Nutmeg: Check that your logs do not contain warnings starting with “SafeCookieData user at request”, or that these warnings are very rare. If they are common, there is likely a false positive caused by some custom login, masquerading, or registration code that needs to call mark_user_change_as_expected. Otherwise, valid requests may be rejected.

For more information, please see the release notes or the Nutmeg wiki page.