diff --git a/README.rst b/README.rst
index 06f8436dc48e54f00ee531be7c5e8f77aa83c985..f571c2c48a8b02465c012df084cf93d1bf660166 100644
--- a/README.rst
+++ b/README.rst
@@ -318,6 +318,13 @@ Please do not report security issues in public. Send security concerns via email
 Changelog
 =========
 
+2.11.0 - 2021-06-10
+-------------------
+
+* Move ``CourseEditLTIFieldsEnabledFlag`` from ``edx-platform`` to this repo
+  while retaining data from existing model.
+
+
 2.10.1 - 2021-06-09
 -------------------
 
diff --git a/lti_consumer/admin.py b/lti_consumer/admin.py
index a32e833ef9abf44b63426a98cbb65ccfb72a4145..c5fae563f0d5192b66abb631c355ce5d9dea93e2 100644
--- a/lti_consumer/admin.py
+++ b/lti_consumer/admin.py
@@ -1,11 +1,15 @@
 """
 Admin views for LTI related models.
 """
+from config_models.admin import KeyedConfigurationModelAdmin
 from django.contrib import admin
+
+from lti_consumer.forms import CourseEditLTIFieldsEnabledAdminForm
 from lti_consumer.models import (
+    CourseEditLTIFieldsEnabledFlag,
     LtiAgsLineItem,
-    LtiConfiguration,
     LtiAgsScore,
+    LtiConfiguration,
     LtiDlContentItem,
 )
 
@@ -19,6 +23,22 @@ class LtiConfigurationAdmin(admin.ModelAdmin):
     readonly_fields = ('location', 'config_id')
 
 
+class CourseEditLTIFieldsEnabledFlagAdmin(KeyedConfigurationModelAdmin):
+    """
+    Admin for LTI Fields Editing feature on course-by-course basis.
+    Allows searching by course id.
+    """
+    form = CourseEditLTIFieldsEnabledAdminForm
+    search_fields = ['course_id']
+    fieldsets = (
+        (None, {
+            'fields': ('course_id', 'enabled'),
+            'description': 'Enter a valid course id. If it is invalid, an error message will be displayed.'
+        }),
+    )
+
+
+admin.site.register(CourseEditLTIFieldsEnabledFlag, CourseEditLTIFieldsEnabledFlagAdmin)
 admin.site.register(LtiConfiguration, LtiConfigurationAdmin)
 admin.site.register(LtiAgsLineItem)
 admin.site.register(LtiAgsScore)
diff --git a/lti_consumer/forms.py b/lti_consumer/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ea866ad85b6c7e6e2827c810f786189eb7a8c69
--- /dev/null
+++ b/lti_consumer/forms.py
@@ -0,0 +1,29 @@
+"""
+Defines a form for providing validation of LTI consumer course-specific configuration.
+"""
+
+
+import logging
+
+from django import forms
+
+from lti_consumer.models import CourseEditLTIFieldsEnabledFlag
+from lti_consumer.plugin.compat import clean_course_id
+
+log = logging.getLogger(__name__)
+
+
+class CourseEditLTIFieldsEnabledAdminForm(forms.ModelForm):
+    """
+    Form for LTI consumer course-specific configuration to verify the course id.
+    """
+
+    class Meta:
+        model = CourseEditLTIFieldsEnabledFlag
+        fields = '__all__'
+
+    def clean_course_id(self):
+        """
+        Validate the course id
+        """
+        return clean_course_id(self)
diff --git a/lti_consumer/migrations/0011_courseeditltifieldsenabledflag.py b/lti_consumer/migrations/0011_courseeditltifieldsenabledflag.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec6cc4873f5ff5c853a9e78e8a6140d6a78f283e
--- /dev/null
+++ b/lti_consumer/migrations/0011_courseeditltifieldsenabledflag.py
@@ -0,0 +1,62 @@
+# Generated by Django 2.2.20 on 2021-05-05 11:56
+import logging
+
+import django.db.models.deletion
+import opaque_keys.edx.django.models
+from django.conf import settings
+from django.db import migrations, models
+
+log = logging.getLogger(__name__)
+
+
+class CreateModelIfNotExists(migrations.CreateModel):
+    """
+    Creates the database table if it doesn't already exist.
+
+    This can be used to move a database model from one app to another.
+    """
+
+    def database_forwards(self, app_label, schema_editor, from_state, to_state):
+        # Get the name of the database table
+        db_table = to_state.apps.get_model(app_label, self.name)._meta.db_table
+        # If the database table for this model already exists, do nothing, otherwise
+        # create the table as usual.
+        if db_table in schema_editor.connection.introspection.table_names():
+            log.info(f"{db_table} already exists. Skipping creation.")
+        else:
+            super().database_forwards(app_label, schema_editor, from_state, to_state)
+
+    def database_backwards(self, app_label, schema_editor, from_state, to_state):
+        # Do nothing when applying this is reverse because the original creation of this
+        # table was handled by edx-platform, so we don't want to delete the table on reversal.
+        pass
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('lti_consumer', '0010_backfill-empty-string-lti-config'),
+    ]
+
+    operations = [
+        CreateModelIfNotExists(
+            name='CourseEditLTIFieldsEnabledFlag',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
+                ('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
+                ('course_id', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)),
+                ('changed_by',
+                 models.ForeignKey(
+                     editable=False,
+                     null=True,
+                     on_delete=django.db.models.deletion.PROTECT,
+                     to=settings.AUTH_USER_MODEL,
+                     verbose_name='Changed by',
+                 )),
+            ],
+            options={
+                'db_table': 'xblock_config_courseeditltifieldsenabledflag',
+            },
+        )
+    ]
diff --git a/lti_consumer/models.py b/lti_consumer/models.py
index 3cd76ec732023250ff7e8b37bc84599830ee80ab..dec339eab7712fb50c1dcb207e8eb4c2056f8a2d 100644
--- a/lti_consumer/models.py
+++ b/lti_consumer/models.py
@@ -10,7 +10,8 @@ from django.utils.translation import ugettext_lazy as _
 
 from jsonfield import JSONField
 from Cryptodome.PublicKey import RSA
-from opaque_keys.edx.django.models import UsageKeyField
+from opaque_keys.edx.django.models import CourseKeyField, UsageKeyField
+from config_models.models import ConfigurationModel
 
 # LTI 1.1
 from lti_consumer.lti_1p1.consumer import LtiConsumer1p1
@@ -18,6 +19,7 @@ from lti_consumer.lti_1p1.consumer import LtiConsumer1p1
 from lti_consumer.lti_1p3.consumer import LtiAdvantageConsumer
 from lti_consumer.lti_1p3.key_handlers import PlatformKeyHandler
 from lti_consumer.plugin import compat
+from lti_consumer.plugin.compat import request_cached
 from lti_consumer.utils import (
     get_lms_base,
     get_lti_ags_lineitems_url,
@@ -531,3 +533,54 @@ class LtiDlContentItem(models.Model):
 
     class Meta:
         app_label = 'lti_consumer'
+
+
+class CourseEditLTIFieldsEnabledFlag(ConfigurationModel):
+    """
+    Enables the editing of "request username" and "request email" fields
+    of LTI consumer for a specific course.
+
+    .. no_pii:
+    """
+    KEY_FIELDS = ('course_id',)
+
+    course_id = CourseKeyField(max_length=255, db_index=True)
+
+    @classmethod
+    @request_cached
+    def lti_access_to_learners_editable(cls, course_id, is_already_sharing_learner_info):
+        """
+        Looks at the currently active configuration model to determine whether
+        the feature that enables editing of "request username" and "request email"
+        fields of LTI consumer is available or not.
+
+        Backwards Compatibility:
+        Enable this feature for a course run who was sharing learner username/email
+        in the past.
+
+        Arguments:
+            course_id (CourseKey): course id for which we need to check this configuration
+            is_already_sharing_learner_info (bool): indicates whether LTI consumer is
+            already sharing edX learner username/email.
+        """
+        course_specific_config = (CourseEditLTIFieldsEnabledFlag.objects
+                                  .filter(course_id=course_id)
+                                  .order_by('-change_date')
+                                  .first())
+
+        if is_already_sharing_learner_info and not course_specific_config:
+            CourseEditLTIFieldsEnabledFlag.objects.create(course_id=course_id, enabled=True)
+            return True
+
+        return course_specific_config.enabled if course_specific_config else False
+
+    def __str__(self):
+        return (
+            f"Course '{self.course_id}': "
+            f"Edit LTI access to Learner information {'' if self.enabled else 'Not '}Enabled"
+        )
+
+    class Meta:
+        # This model was moved from edx-platform, with intention of retaining existing data.
+        # This is referencing the original table name.
+        db_table = "xblock_config_courseeditltifieldsenabledflag"
diff --git a/lti_consumer/plugin/compat.py b/lti_consumer/plugin/compat.py
index c5cbcefc747ec0cb4e54a14c3941d09fe499f9c2..588f81991357f5be27389a7959c69021f5e364e7 100644
--- a/lti_consumer/plugin/compat.py
+++ b/lti_consumer/plugin/compat.py
@@ -1,10 +1,19 @@
 """
 Compatibility layer to isolate core-platform method calls from implementation.
 """
+import logging
+from typing import Callable
+
 from django.core.exceptions import ValidationError
+from django.forms import ModelForm
+from opaque_keys.edx.keys import CourseKey
+
 from lti_consumer.exceptions import LtiError
 
 
+log = logging.getLogger(__name__)
+
+
 # Waffle flags configuration
 
 # Namespace
@@ -185,3 +194,25 @@ def get_lti_pii_course_waffle_flag():
     # pylint: disable=import-error,import-outside-toplevel
     from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
     return CourseWaffleFlag(WAFFLE_NAMESPACE, LTI_NRPS_TRANSMIT_PII, __name__)
+
+
+def request_cached(func) -> Callable[[Callable], Callable]:
+    """
+    Import the `request_cached` decorator from LMS and apply it if available.
+    """
+    try:
+        # pylint: disable=import-outside-toplevel
+        from openedx.core.lib.cache_utils import request_cached as lms_request_cached
+        return lms_request_cached(func)
+    except ImportError:
+        log.warning("Unable to import `request_cached`. This is normal if running tests.")
+        return func
+
+
+def clean_course_id(model_form: ModelForm) -> CourseKey:
+    """
+    Import and run `clean_course_id` from LMS
+    """
+    # pylint: disable=import-error,import-outside-toplevel
+    from openedx.core.lib.courses import clean_course_id as lms_clean_course_id
+    return lms_clean_course_id(model_form)
diff --git a/lti_consumer/tests/unit/test_models.py b/lti_consumer/tests/unit/test_models.py
index 67b9c6baf87d0f0e71d8c552bc1153fe7ecd6a3b..b6f3b9ac9361ae2c664524ab91adc831c9a540ec 100644
--- a/lti_consumer/tests/unit/test_models.py
+++ b/lti_consumer/tests/unit/test_models.py
@@ -1,20 +1,26 @@
 """
 Unit tests for LTI models.
 """
-from datetime import datetime, timedelta, timezone
+from contextlib import contextmanager
+from datetime import datetime, timedelta
 from unittest.mock import patch
 
+import ddt
 from Cryptodome.PublicKey import RSA
 from django.core.exceptions import ValidationError
 from django.test.testcases import TestCase
+from django.utils import timezone
+from edx_django_utils.cache import RequestCache
 from jwkest.jwk import RSAKey
+from opaque_keys.edx.locator import CourseLocator
 
 from lti_consumer.lti_1p1.consumer import LtiConsumer1p1
 from lti_consumer.lti_xblock import LtiConsumerXBlock
 from lti_consumer.models import (
+    CourseEditLTIFieldsEnabledFlag,
     LtiAgsLineItem,
-    LtiConfiguration,
     LtiAgsScore,
+    LtiConfiguration,
     LtiDlContentItem,
 )
 from lti_consumer.tests.unit.test_utils import make_xblock
@@ -353,3 +359,85 @@ class TestLtiDlContentItemModel(TestCase):
             str(content_item),
             "[CONFIG_ON_XBLOCK] lti_1p3 - block-v1:course+test+2020+type@problem+block@test: image"
         )
+
+
+@contextmanager
+def lti_consumer_fields_editing_flag(course_id, enabled_for_course=False):
+    """
+    Yields CourseEditLTIFieldsEnabledFlag record for unit tests
+
+    Arguments:
+        course_id (CourseLocator): course locator to control this feature for.
+        enabled_for_course (bool): whether feature is enabled for 'course_id'
+    """
+    RequestCache.clear_all_namespaces()
+    CourseEditLTIFieldsEnabledFlag.objects.create(course_id=course_id, enabled=enabled_for_course)
+    yield
+
+
+@ddt.ddt
+class TestLTIConsumerHideFieldsFlag(TestCase):
+    """
+    Tests the behavior of the flags for lti consumer fields' editing feature.
+    These are set via Django admin settings.
+    """
+
+    def setUp(self):
+        super().setUp()
+        self.course_id = CourseLocator(org="edx", course="course", run="run")
+
+    @ddt.data(
+        (True, True),
+        (True, False),
+        (False, True),
+        (False, False),
+    )
+    @ddt.unpack
+    def test_lti_fields_editing_feature_flags(self, enabled_for_course, is_already_sharing_learner_info):
+        """
+        Test that feature flag works correctly with course-specific configuration in combination with
+        a boolean which indicates whether a course-run already sharing learner username/email - given
+        the course-specific configuration record is present.
+        """
+        with lti_consumer_fields_editing_flag(
+            course_id=self.course_id,
+            enabled_for_course=enabled_for_course
+        ):
+            feature_enabled = CourseEditLTIFieldsEnabledFlag.lti_access_to_learners_editable(
+                self.course_id,
+                is_already_sharing_learner_info,
+            )
+            self.assertEqual(feature_enabled, enabled_for_course)
+
+    @ddt.data(True, False)
+    def test_lti_fields_editing_is_backwards_compatible(self, is_already_sharing_learner_info):
+        """
+        Test that feature flag works correctly with a boolean which indicates whether a course-run already
+        sharing learner username/email - given the course-specific configuration record is not set previously.
+
+        This tests the backward compatibility which currently is: if an existing course run is already
+        sharing learner information then this feature should be enabled for that course run by default.
+        """
+        feature_enabled = CourseEditLTIFieldsEnabledFlag.lti_access_to_learners_editable(
+            self.course_id,
+            is_already_sharing_learner_info,
+        )
+        feature_flag_created = CourseEditLTIFieldsEnabledFlag.objects.filter(course_id=self.course_id).exists()
+        self.assertEqual(feature_flag_created, is_already_sharing_learner_info)
+        self.assertEqual(feature_enabled, is_already_sharing_learner_info)
+
+    def test_enable_disable_course_flag(self):
+        """
+        Ensures that the flag, once enabled for a course, can also be disabled.
+        """
+        with lti_consumer_fields_editing_flag(
+            course_id=self.course_id,
+            enabled_for_course=True
+        ):
+            self.assertTrue(CourseEditLTIFieldsEnabledFlag.lti_access_to_learners_editable(self.course_id, False))
+
+        with lti_consumer_fields_editing_flag(
+            course_id=self.course_id,
+            enabled_for_course=False
+        ):
+            self.assertFalse(CourseEditLTIFieldsEnabledFlag.lti_access_to_learners_editable(self.course_id, False))
diff --git a/requirements/base.in b/requirements/base.in
index bd89e7b262d3e25038c0367a71bd4d18e723bea0..8f799d6776038e68759dc49b45a0ce35529662f5 100644
--- a/requirements/base.in
+++ b/requirements/base.in
@@ -14,3 +14,4 @@ pyjwkest
 edx-opaque-keys[django]
 django-filter
 jsonfield2
+django-config-models         # Configuration models for Django allowing config management with auditing
diff --git a/requirements/base.txt b/requirements/base.txt
index 1af3ae7f4aceeb750416b525b8dead4f40b6c083..fc0cb17d5aeaafbea18544feb4d19d4c9091f77f 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -12,15 +12,32 @@ certifi==2021.5.30
     # via requests
 chardet==4.0.0
     # via requests
+django-config-models==2.1.1
+    # via
+    #   -c requirements/constraints.txt
+    #   -r requirements/base.in
+django-crum==0.7.9
+    # via edx-django-utils
 django-filter==2.4.0
     # via -r requirements/base.in
+django-waffle==2.2.0
+    # via edx-django-utils
 django==2.2.24
     # via
     #   -c requirements/common_constraints.txt
     #   -r requirements/base.in
+    #   django-config-models
     #   django-filter
+    #   djangorestframework
+    #   edx-django-utils
     #   edx-opaque-keys
     #   jsonfield2
+djangorestframework==3.12.4
+    # via
+    #   -c requirements/constraints.txt
+    #   django-config-models
+edx-django-utils==4.1.0
+    # via django-config-models
 edx-opaque-keys[django]==2.2.1
     # via -r requirements/base.in
 fs==2.4.13
@@ -29,8 +46,10 @@ future==0.18.2
     # via pyjwkest
 idna==2.10
     # via requests
-jsonfield2==4.0.0.post0
-    # via -r requirements/base.in
+jsonfield2==3.0.3
+    # via
+    #   -c requirements/constraints.txt
+    #   -r requirements/base.in
 lazy==1.4
     # via -r requirements/base.in
 lxml==4.6.3
@@ -45,12 +64,16 @@ markupsafe==2.0.1
     # via
     #   mako
     #   xblock
+newrelic==6.4.1.158
+    # via edx-django-utils
 oauthlib==3.1.1
     # via -r requirements/base.in
 packaging==20.9
     # via bleach
 pbr==5.6.0
     # via stevedore
+psutil==5.8.0
+    # via edx-django-utils
 pycryptodomex==3.10.1
     # via
     #   -r requirements/base.in
@@ -83,7 +106,9 @@ six==1.16.0
 sqlparse==0.4.1
     # via django
 stevedore==3.3.0
-    # via edx-opaque-keys
+    # via
+    #   edx-django-utils
+    #   edx-opaque-keys
 urllib3==1.26.5
     # via requests
 web-fragments==1.0.0
diff --git a/requirements/constraints.txt b/requirements/constraints.txt
index 2e75642932749671d0b26458e2aa87b312de5497..d5584b91eaefe7b6844cc135c99f9429aea686ee 100644
--- a/requirements/constraints.txt
+++ b/requirements/constraints.txt
@@ -10,8 +10,14 @@
 
 # Common constraints for edx repos
 -c common_constraints.txt
- 
+
 # TODO: Many pinned dependencies should be unpinned and/or moved to this constraints file.
 
 # Same as in edx-platform
 djangorestframework<4
+
+# jsonfield2 3.1.0 drops support for python 3.5
+jsonfield2<3.1.0
+
+# Same as in edx-platform
+django-config-models>=1.0.0
diff --git a/requirements/dev.txt b/requirements/dev.txt
index cf5ef56a6e7393019f3c0765b5a5c3f547d6eedd..0d3b798d48f34d0d16e3f852975e306e535fd9c3 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -18,15 +18,37 @@ chardet==4.0.0
     # via
     #   -r requirements/base.txt
     #   requests
+django-config-models==2.1.1
+    # via -r requirements/base.txt
+django-crum==0.7.9
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 django-filter==2.4.0
     # via -r requirements/base.txt
+django-waffle==2.2.0
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 django==2.2.24
     # via
     #   -r requirements/base.txt
+    #   django-config-models
+    #   django-crum
     #   django-filter
+    #   djangorestframework
+    #   edx-django-utils
     #   edx-i18n-tools
     #   edx-opaque-keys
     #   jsonfield2
+djangorestframework==3.12.4
+    # via
+    #   -r requirements/base.txt
+    #   django-config-models
+edx-django-utils==4.1.0
+    # via
+    #   -r requirements/base.txt
+    #   django-config-models
 edx-i18n-tools==0.5.0
     # via -r requirements/dev.in
 edx-opaque-keys[django]==2.2.1
@@ -43,7 +65,7 @@ idna==2.10
     # via
     #   -r requirements/base.txt
     #   requests
-jsonfield2==4.0.0.post0
+jsonfield2==3.0.3
     # via -r requirements/base.txt
 lazy==1.4
     # via -r requirements/base.txt
@@ -60,6 +82,10 @@ markupsafe==2.0.1
     #   -r requirements/base.txt
     #   mako
     #   xblock
+newrelic==6.4.1.158
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 oauthlib==3.1.1
     # via -r requirements/base.txt
 packaging==20.9
@@ -68,7 +94,7 @@ packaging==20.9
     #   bleach
 path.py==12.5.0
     # via edx-i18n-tools
-path==15.1.2
+path==16.0.0
     # via path.py
 pbr==5.6.0
     # via
@@ -76,6 +102,10 @@ pbr==5.6.0
     #   stevedore
 polib==1.1.1
     # via edx-i18n-tools
+psutil==5.8.0
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 pycryptodomex==3.10.1
     # via
     #   -r requirements/base.txt
@@ -128,6 +158,7 @@ sqlparse==0.4.1
 stevedore==3.3.0
     # via
     #   -r requirements/base.txt
+    #   edx-django-utils
     #   edx-opaque-keys
 urllib3==1.26.5
     # via
diff --git a/requirements/test.txt b/requirements/test.txt
index c19a819bfdc0e63334da16c4d4c79333d2efb436..fe9387087993ad314356866adb86bb6df1055243 100644
--- a/requirements/test.txt
+++ b/requirements/test.txt
@@ -51,16 +51,31 @@ cryptography==3.4.7
     # via secretstorage
 ddt==1.4.2
     # via -r requirements/test.in
+django-config-models==2.1.1
+    # via
+    #   -c requirements/constraints.txt
+    #   -r requirements/base.txt
+django-crum==0.7.9
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 django-filter==2.4.0
     # via -r requirements/base.txt
 django-pyfs==3.0
     # via -r requirements/test.in
+django-waffle==2.2.0
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
     # via
     #   -c requirements/common_constraints.txt
     #   -r requirements/base.txt
+    #   django-config-models
+    #   django-crum
     #   django-filter
     #   django-pyfs
     #   djangorestframework
+    #   edx-django-utils
     #   edx-lint
     #   edx-opaque-keys
     #   jsonfield2
@@ -68,13 +83,19 @@ django-pyfs==3.0
 djangorestframework==3.12.4
     # via
     #   -c requirements/constraints.txt
+    #   -r requirements/base.txt
     #   -r requirements/test.in
+    #   django-config-models
 docopt==0.6.2
     # via coveralls
 docutils==0.16
     # via
     #   -c requirements/common_constraints.txt
     #   readme-renderer
+edx-django-utils==4.1.0
+    # via
+    #   -r requirements/base.txt
+    #   django-config-models
 edx-lint==5.0.0
     # via -r requirements/test.in
 edx-opaque-keys[django]==2.2.1
@@ -111,8 +132,10 @@ jmespath==0.10.0
     # via
     #   boto3
     #   botocore
-jsonfield2==4.0.0.post0
-    # via -r requirements/base.txt
+jsonfield2==3.0.3
+    # via
+    #   -c requirements/constraints.txt
+    #   -r requirements/base.txt
 keyring==23.0.1
     # via twine
 lazy-object-proxy==1.6.0
@@ -137,6 +160,10 @@ mccabe==0.6.1
     # via pylint
 mock==4.0.3
     # via -r requirements/test.in
+newrelic==6.4.1.158
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 oauthlib==3.1.1
     # via -r requirements/base.txt
 packaging==20.9
@@ -149,6 +176,10 @@ pbr==5.6.0
     #   stevedore
 pkginfo==1.7.0
     # via twine
+psutil==5.8.0
+    # via
+    #   -r requirements/base.txt
+    #   edx-django-utils
 pycodestyle==2.7.0
     # via -r requirements/test.in
 pycparser==2.20
@@ -242,12 +273,13 @@ stevedore==3.3.0
     # via
     #   -r requirements/base.txt
     #   code-annotations
+    #   edx-django-utils
     #   edx-opaque-keys
 text-unidecode==1.3
     # via python-slugify
 toml==0.10.2
     # via pylint
-tqdm==4.61.0
+tqdm==4.61.1
     # via twine
 twine==3.4.1
     # via -r requirements/test.in
diff --git a/requirements/travis.txt b/requirements/travis.txt
index 6147e6ad9ba4787dfd8378dff7b4f96284c72e24..dfe95c130335ebfc8faf0fa7cd2cd06708119278 100644
--- a/requirements/travis.txt
+++ b/requirements/travis.txt
@@ -74,17 +74,32 @@ distlib==0.3.2
     # via
     #   -r requirements/tox.txt
     #   virtualenv
+django-config-models==2.1.1
+    # via
+    #   -c requirements/constraints.txt
+    #   -r requirements/test.txt
+django-crum==0.7.9
+    # via
+    #   -r requirements/test.txt
+    #   edx-django-utils
 django-filter==2.4.0
     # via -r requirements/test.txt
 django-pyfs==3.0
     # via -r requirements/test.txt
+django-waffle==2.2.0
+    # via
+    #   -r requirements/test.txt
+    #   edx-django-utils
 django==2.2.24
     # via
     #   -c requirements/common_constraints.txt
     #   -r requirements/test.txt
+    #   django-config-models
+    #   django-crum
     #   django-filter
     #   django-pyfs
     #   djangorestframework
+    #   edx-django-utils
     #   edx-lint
     #   edx-opaque-keys
     #   jsonfield2
@@ -93,6 +108,7 @@ djangorestframework==3.12.4
     # via
     #   -c requirements/constraints.txt
     #   -r requirements/test.txt
+    #   django-config-models
 docopt==0.6.2
     # via
     #   -r requirements/test.txt
@@ -102,6 +118,10 @@ docutils==0.16
     #   -c requirements/common_constraints.txt
     #   -r requirements/test.txt
     #   readme-renderer
+edx-django-utils==4.1.0
+    # via
+    #   -r requirements/test.txt
+    #   django-config-models
 edx-lint==5.0.0
     # via -r requirements/test.txt
 edx-opaque-keys[django]==2.2.1
@@ -152,8 +172,10 @@ jmespath==0.10.0
     #   -r requirements/test.txt
     #   boto3
     #   botocore
-jsonfield2==4.0.0.post0
-    # via -r requirements/test.txt
+jsonfield2==3.0.3
+    # via
+    #   -c requirements/constraints.txt
+    #   -r requirements/test.txt
 keyring==23.0.1
     # via
     #   -r requirements/test.txt
@@ -184,6 +206,10 @@ mccabe==0.6.1
     #   pylint
 mock==4.0.3
     # via -r requirements/test.txt
+newrelic==6.4.1.158
+    # via
+    #   -r requirements/test.txt
+    #   edx-django-utils
 oauthlib==3.1.1
     # via -r requirements/test.txt
 packaging==20.9
@@ -204,6 +230,10 @@ pluggy==0.13.1
     # via
     #   -r requirements/tox.txt
     #   tox
+psutil==5.8.0
+    # via
+    #   -r requirements/test.txt
+    #   edx-django-utils
 py==1.10.0
     # via
     #   -r requirements/tox.txt
@@ -325,6 +355,7 @@ stevedore==3.3.0
     # via
     #   -r requirements/test.txt
     #   code-annotations
+    #   edx-django-utils
     #   edx-opaque-keys
 text-unidecode==1.3
     # via
@@ -338,7 +369,7 @@ toml==0.10.2
     #   tox
 tox==3.23.1
     # via -r requirements/tox.txt
-tqdm==4.61.0
+tqdm==4.61.1
     # via
     #   -r requirements/test.txt
     #   twine
diff --git a/setup.py b/setup.py
index 0f7c54eac2b4e947efb1e33c74788375b2a00397..38a2ad4e0d02f47f192a71442d5ad04793021201 100644
--- a/setup.py
+++ b/setup.py
@@ -49,7 +49,7 @@ with open('README.rst') as _f:
 
 setup(
     name='lti-consumer-xblock',
-    version='2.10.1',
+    version='2.11.0',
     author='Open edX project',
     author_email='oscm@edx.org',
     description='This XBlock implements the consumer side of the LTI specification.',