diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py
index ae875457762edfa6bcc2a87b23758cd103dd4a09..be3d1b809b21baf041639fc1191f5b74c1021b66 100644
--- a/openedx/core/djangoapps/content_libraries/api.py
+++ b/openedx/core/djangoapps/content_libraries/api.py
@@ -9,6 +9,7 @@ import attr
 from django.core.validators import validate_unicode_slug
 from django.db import IntegrityError
 from lxml import etree
+from opaque_keys.edx.locator import BundleDefinitionLocator, LibraryLocatorV2, LibraryUsageLocatorV2
 from organizations.models import Organization
 import six
 from xblock.core import XBlock
@@ -17,7 +18,6 @@ from xblock.exceptions import XBlockNotFoundError
 from cms.djangoapps.contentstore.views.helpers import xblock_type_display_name
 from openedx.core.djangoapps.content_libraries.library_bundle import LibraryBundle
 from openedx.core.djangoapps.xblock.api import get_block_display_name, load_block
-from openedx.core.djangoapps.xblock.learning_context.keys import BundleDefinitionLocator
 from openedx.core.djangoapps.xblock.learning_context.manager import get_learning_context_impl
 from openedx.core.djangoapps.xblock.runtime.olx_parsing import XBlockInclude
 from openedx.core.lib.blockstore_api import (
@@ -33,7 +33,6 @@ from openedx.core.lib.blockstore_api import (
     delete_draft,
 )
 from openedx.core.djangolib.blockstore_cache import BundleCache
-from .keys import LibraryLocatorV2, LibraryUsageLocatorV2
 from .models import ContentLibrary, ContentLibraryPermission
 
 log = logging.getLogger(__name__)
@@ -275,7 +274,7 @@ def get_library_block(usage_key):
     def_key = lib_context.definition_for_usage(usage_key)
     if def_key is None:
         raise ContentLibraryBlockNotFound(usage_key)
-    lib_bundle = LibraryBundle(usage_key.library_slug, def_key.bundle_uuid, draft_name=DRAFT_NAME)
+    lib_bundle = LibraryBundle(usage_key.lib_key, def_key.bundle_uuid, draft_name=DRAFT_NAME)
     return LibraryXBlockMetadata(
         usage_key=usage_key,
         def_key=def_key,
@@ -337,8 +336,7 @@ def create_library_block(library_key, block_type, definition_id):
     # Make sure the new ID is not taken already:
     new_usage_id = definition_id  # Since this is a top level XBlock, usage_id == definition_id
     usage_key = LibraryUsageLocatorV2(
-        library_org=library_key.org,
-        library_slug=library_key.slug,
+        lib_key=library_key,
         block_type=block_type,
         usage_id=new_usage_id,
     )
diff --git a/openedx/core/djangoapps/content_libraries/keys.py b/openedx/core/djangoapps/content_libraries/keys.py
deleted file mode 100644
index afd35e538cd7d5c745c20f62cda7841982378a4c..0000000000000000000000000000000000000000
--- a/openedx/core/djangoapps/content_libraries/keys.py
+++ /dev/null
@@ -1,132 +0,0 @@
-"""
-Key/locator types for Blockstore-based content libraries
-"""
-# Disable warnings about _to_deprecated_string etc. which we don't want to implement:
-# pylint: disable=abstract-method, no-member
-from __future__ import absolute_import, division, print_function, unicode_literals
-
-from opaque_keys import InvalidKeyError
-
-from openedx.core.djangoapps.xblock.learning_context.keys import (
-    check_key_string_field,
-    BlockUsageKeyV2,
-    LearningContextKey,
-)
-
-
-class LibraryLocatorV2(LearningContextKey):
-    """
-    A key that represents a Blockstore-based content library.
-
-    When serialized, these keys look like:
-        lib:MITx:reallyhardproblems
-        lib:hogwarts:p300-potions-exercises
-    """
-    CANONICAL_NAMESPACE = 'lib'
-    KEY_FIELDS = ('org', 'slug')
-    __slots__ = KEY_FIELDS
-    CHECKED_INIT = False
-
-    def __init__(self, org, slug):
-        """
-        Construct a GlobalUsageLocator
-        """
-        check_key_string_field(org)
-        check_key_string_field(slug)
-        super(LibraryLocatorV2, self).__init__(org=org, slug=slug)
-
-    def _to_string(self):
-        """
-        Serialize this key as a string
-        """
-        return ":".join((self.org, self.slug))
-
-    @classmethod
-    def _from_string(cls, serialized):
-        """
-        Instantiate this key from a serialized string
-        """
-        try:
-            (org, slug) = serialized.split(':')
-        except ValueError:
-            raise InvalidKeyError(cls, serialized)
-        return cls(org=org, slug=slug)
-
-    def make_definition_usage(self, definition_key, usage_id=None):
-        """
-        Return a usage key, given the given the specified definition key and
-        usage_id.
-        """
-        return LibraryUsageLocatorV2(
-            library_org=self.org,
-            library_slug=self.slug,
-            block_type=definition_key.block_type,
-            usage_id=usage_id,
-        )
-
-    def for_branch(self, branch):
-        """
-        Compatibility helper.
-        Some code calls .for_branch(None) on course keys. By implementing this,
-        it improves backwards compatibility between library keys and course
-        keys.
-        """
-        if branch is not None:
-            raise ValueError("Cannot call for_branch on a content library key, except for_branch(None).")
-        return self
-
-
-class LibraryUsageLocatorV2(BlockUsageKeyV2):
-    """
-    An XBlock in a Blockstore-based content library.
-
-    When serialized, these keys look like:
-        lb:MITx:reallyhardproblems:problem:problem1
-    """
-    CANONICAL_NAMESPACE = 'lb'  # "Library Block"
-    KEY_FIELDS = ('library_org', 'library_slug', 'block_type', 'usage_id')
-    __slots__ = KEY_FIELDS
-    CHECKED_INIT = False
-
-    def __init__(self, library_org, library_slug, block_type, usage_id):
-        """
-        Construct a LibraryUsageLocatorV2
-        """
-        check_key_string_field(library_org)
-        check_key_string_field(library_slug)
-        check_key_string_field(block_type)
-        check_key_string_field(usage_id)
-        super(LibraryUsageLocatorV2, self).__init__(
-            library_org=library_org,
-            library_slug=library_slug,
-            block_type=block_type,
-            usage_id=usage_id,
-        )
-
-    @property
-    def context_key(self):
-        return LibraryLocatorV2(org=self.library_org, slug=self.library_slug)
-
-    @property
-    def block_id(self):
-        """
-        Get the 'block ID' which is another name for the usage ID.
-        """
-        return self.usage_id
-
-    def _to_string(self):
-        """
-        Serialize this key as a string
-        """
-        return ":".join((self.library_org, self.library_slug, self.block_type, self.usage_id))
-
-    @classmethod
-    def _from_string(cls, serialized):
-        """
-        Instantiate this key from a serialized string
-        """
-        try:
-            (library_org, library_slug, block_type, usage_id) = serialized.split(':')
-        except ValueError:
-            raise InvalidKeyError(cls, serialized)
-        return cls(library_org=library_org, library_slug=library_slug, block_type=block_type, usage_id=usage_id)
diff --git a/openedx/core/djangoapps/content_libraries/library_bundle.py b/openedx/core/djangoapps/content_libraries/library_bundle.py
index 1481f7c77d61a2a60d4b3d1c94f98392ec97d9b0..e0e3283e5eefe046c61d4cc67115fc921d8e0b8d 100644
--- a/openedx/core/djangoapps/content_libraries/library_bundle.py
+++ b/openedx/core/djangoapps/content_libraries/library_bundle.py
@@ -5,12 +5,11 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 import logging
 
 from django.utils.lru_cache import lru_cache
+from opaque_keys.edx.locator import BundleDefinitionLocator, LibraryUsageLocatorV2
 from xblock.core import XBlock
 from xblock.plugin import PluginMissingError
 
-from openedx.core.djangoapps.content_libraries.keys import LibraryUsageLocatorV2
 from openedx.core.djangoapps.content_libraries.models import ContentLibrary
-from openedx.core.djangoapps.xblock.learning_context.keys import BundleDefinitionLocator
 from openedx.core.djangoapps.xblock.runtime.blockstore_runtime import xml_for_definition
 from openedx.core.djangoapps.xblock.runtime.olx_parsing import (
     BundleFormatException,
@@ -85,8 +84,7 @@ def usage_for_child_include(parent_usage, parent_definition, parsed_include):
         # <xblock-include> but that requires much more complex logic.)
         usage_id = parent_usage.usage_id + "-" + usage_id
     return LibraryUsageLocatorV2(
-        library_org=parent_usage.library_org,
-        library_slug=parent_usage.library_slug,
+        lib_key=parent_usage.lib_key,
         block_type=parsed_include.block_type,
         usage_id=usage_id,
     )
@@ -169,7 +167,7 @@ class LibraryBundle(object):
         own_usage_keys = []
         for olx_file_path in self.get_olx_files():
             block_type, usage_id, _unused = olx_file_path.split('/')
-            usage_key = LibraryUsageLocatorV2(self.library_key.org, self.library_key.slug, block_type, usage_id)
+            usage_key = LibraryUsageLocatorV2(self.library_key, block_type, usage_id)
             own_usage_keys.append(usage_key)
 
         usage_keys_with_parents = self.get_bundle_includes().keys()
@@ -234,7 +232,7 @@ class LibraryBundle(object):
                 olx_path=bfile.path,
                 **version_arg
             )
-            usage_key = LibraryUsageLocatorV2(self.library_key.org, self.library_key.slug, block_type, usage_id)
+            usage_key = LibraryUsageLocatorV2(self.library_key, block_type, usage_id)
             add_definitions_children(usage_key, def_key)
 
         self.cache.set(cache_key, usages_found)
diff --git a/openedx/core/djangoapps/content_libraries/migrations/0001_initial.py b/openedx/core/djangoapps/content_libraries/migrations/0001_initial.py
index 354583ae598b9b15842492c0bf0b1cd3938d7223..8f2eb6761f191b574ebd8b1bcb87a7df3327cfee 100644
--- a/openedx/core/djangoapps/content_libraries/migrations/0001_initial.py
+++ b/openedx/core/djangoapps/content_libraries/migrations/0001_initial.py
@@ -21,7 +21,7 @@ class Migration(migrations.Migration):
             name='ContentLibrary',
             fields=[
                 ('id', models.AutoField(primary_key=True, serialize=False)),
-                ('slug', models.SlugField()),
+                ('slug', models.SlugField(allow_unicode=True)),
                 ('bundle_uuid', models.UUIDField(unique=True)),
                 ('allow_public_learning', models.BooleanField(default=False, help_text='\n            Allow any user (even unregistered users) to view and interact with\n            content in this library (in the LMS; not in Studio). If this is not\n            enabled, then the content in this library is not directly accessible\n            in the LMS, and learners will only ever see this content if it is\n            explicitly added to a course. If in doubt, leave this unchecked.\n        ')),
                 ('allow_public_read', models.BooleanField(default=False, help_text="\n            Allow any user with Studio access to view this library's content in\n            Studio, use it in their courses, and copy content out of this\n            library. If in doubt, leave this unchecked.\n        ")),
diff --git a/openedx/core/djangoapps/content_libraries/models.py b/openedx/core/djangoapps/content_libraries/models.py
index bb03c0748c3475fabcf5c86fc7af260df62f25d1..f1680c18d6e6369b0dd3f58efa24c85182c84f33 100644
--- a/openedx/core/djangoapps/content_libraries/models.py
+++ b/openedx/core/djangoapps/content_libraries/models.py
@@ -6,11 +6,10 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 from django.contrib.auth import get_user_model
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
+from opaque_keys.edx.locator import LibraryLocatorV2
 from organizations.models import Organization
 import six
 
-from openedx.core.djangoapps.content_libraries.keys import LibraryLocatorV2
-
 User = get_user_model()
 
 
@@ -45,7 +44,7 @@ class ContentLibrary(models.Model):
     # library's opaque key:
     # e.g. "lib:org:slug" is the opaque key for a library.
     org = models.ForeignKey(Organization, on_delete=models.PROTECT, null=False)
-    slug = models.SlugField()
+    slug = models.SlugField(allow_unicode=True)
     bundle_uuid = models.UUIDField(unique=True, null=False)
 
     # How is this library going to be used?
diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py
index a87fcfff3606e2cca1a135cef8f7ea37027d04cd..09190e554883bb655531978cac0aa09882700768 100644
--- a/openedx/core/djangoapps/content_libraries/serializers.py
+++ b/openedx/core/djangoapps/content_libraries/serializers.py
@@ -4,6 +4,7 @@ Serializers for the content libraries REST API
 # pylint: disable=abstract-method
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from django.core.validators import validate_unicode_slug
 from rest_framework import serializers
 
 
@@ -16,7 +17,7 @@ class ContentLibraryMetadataSerializer(serializers.Serializer):
     # is a reserved prop name in React
     id = serializers.CharField(source="key", read_only=True)
     org = serializers.SlugField(source="key.org")
-    slug = serializers.SlugField(source="key.slug")
+    slug = serializers.CharField(source="key.slug", validators=(validate_unicode_slug, ))
     bundle_uuid = serializers.UUIDField(format='hex_verbose', read_only=True)
     collection_uuid = serializers.UUIDField(format='hex_verbose', write_only=True)
     title = serializers.CharField()
diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py
index f4e3185be93f420da54fbc988eb79be45fd3ce00..cff56df075767d024721289b341fba41e70ce18a 100644
--- a/openedx/core/djangoapps/content_libraries/views.py
+++ b/openedx/core/djangoapps/content_libraries/views.py
@@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 from functools import wraps
 import logging
 
+from opaque_keys.edx.locator import LibraryLocatorV2, LibraryUsageLocatorV2
 from organizations.models import Organization
 from rest_framework.exceptions import NotFound, ValidationError
 from rest_framework.views import APIView
@@ -13,7 +14,6 @@ from rest_framework.response import Response
 
 from openedx.core.lib.api.view_utils import view_auth_classes
 from . import api
-from .keys import LibraryLocatorV2, LibraryUsageLocatorV2
 from .serializers import (
     ContentLibraryMetadataSerializer,
     ContentLibraryUpdateSerializer,
@@ -155,7 +155,7 @@ class LibraryCommitView(APIView):
     @convert_exceptions
     def delete(self, request, lib_key_str):  # pylint: disable=unused-argument
         """
-        Revent the draft changes made to the specified block and its
+        Revert the draft changes made to the specified block and its
         descendants. Restore it to the last published version
         """
         key = LibraryLocatorV2.from_string(lib_key_str)
diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py
index b9b24b30016cf5a4f9b68fe109e33564069bee5b..12890bf0ecf3e9222dc2c3fae64b810bf29e2fb3 100644
--- a/openedx/core/djangoapps/xblock/api.py
+++ b/openedx/core/djangoapps/xblock/api.py
@@ -12,13 +12,14 @@ import logging
 
 from django.urls import reverse
 from django.utils.translation import ugettext as _
+from opaque_keys.edx.keys import UsageKeyV2
+from opaque_keys.edx.locator import BundleDefinitionLocator
 from rest_framework.exceptions import NotFound
 import six
 from xblock.core import XBlock
 from xblock.exceptions import NoSuchViewError
 
 from openedx.core.djangoapps.xblock.apps import get_xblock_app_config
-from openedx.core.djangoapps.xblock.learning_context.keys import BundleDefinitionLocator, BlockUsageKeyV2
 from openedx.core.djangoapps.xblock.learning_context.manager import get_learning_context_impl
 from openedx.core.djangoapps.xblock.runtime.blockstore_runtime import BlockstoreXBlockRuntime, xml_for_definition
 from openedx.core.djangoapps.xblock.runtime.runtime import XBlockRuntimeSystem
@@ -100,7 +101,7 @@ def resolve_definition(block_or_key):
     """
     if isinstance(block_or_key, BundleDefinitionLocator):
         return block_or_key
-    elif isinstance(block_or_key, BlockUsageKeyV2):
+    elif isinstance(block_or_key, UsageKeyV2):
         context_impl = get_learning_context_impl(block_or_key)
         return context_impl.definition_for_usage(block_or_key)
     elif isinstance(block_or_key, XBlock):
diff --git a/openedx/core/djangoapps/xblock/learning_context/keys.py b/openedx/core/djangoapps/xblock/learning_context/keys.py
deleted file mode 100644
index f20ddbbac892fe4443ebdadba5c357b182de752a..0000000000000000000000000000000000000000
--- a/openedx/core/djangoapps/xblock/learning_context/keys.py
+++ /dev/null
@@ -1,226 +0,0 @@
-"""
-New key/locator types that work with Blockstore and the new "Learning Context"
-concept.
-
-We will probably move these key types into the "opaque-keys" repository once
-they are stable.
-"""
-# Disable warnings about _to_deprecated_string etc. which we don't want to implement.
-# And fix warnings about key fields, which pylint doesn't see as member variables.
-# pylint: disable=abstract-method, no-member
-from __future__ import absolute_import, division, print_function, unicode_literals
-import re
-from uuid import UUID
-import warnings
-
-from opaque_keys import InvalidKeyError, OpaqueKey
-from opaque_keys.edx.keys import DefinitionKey, UsageKey
-import six
-
-
-def check_key_string_field(value, regexp=r'^[\w\-.]+$'):
-    """
-    Helper method to verify that a key's string field(s) meet certain
-    requirements:
-        Are a non-empty string
-        Match the specified regular expression
-    """
-    if not isinstance(value, six.string_types):
-        raise TypeError("Expected a string")
-    if not value or not re.match(regexp, value):
-        raise ValueError("'{}' is not a valid field value for this key type.".format(value))
-
-
-def check_draft_name(value):
-    """
-    Check that the draft name is valid (unambiguously not a bundle version
-    nubmer).
-
-    Valid: studio_draft, foo-bar, import348975938
-    Invalid: 1, 15, 873452847357834
-    """
-    if not isinstance(value, six.string_types) or not value:
-        raise TypeError("Expected a non-empty string")
-    if value.isdigit():
-        raise ValueError("Cannot use an integer draft name as it conflicts with bundle version nubmers")
-
-
-class BundleDefinitionLocator(DefinitionKey):
-    """
-    Implementation of the DefinitionKey type, for XBlock content stored in
-    Blockstore bundles. This is a low-level identifier used within the Open edX
-    system for identifying and retrieving OLX.
-
-    A "Definition" is a specific OLX file in a specific BundleVersion
-    (or sometimes rather than a BundleVersion, it may point to a named draft.)
-    The OLX file, and thus the definition key, defines Scope.content fields as
-    well as defaults for Scope.settings and Scope.children fields. However the
-    definition has no parent and no position in any particular course or other
-    context - both of which require a *usage key* and not just a definition key.
-    The same block definition (.olx file) can be used in multiple places in a
-    course, each with a different usage key.
-
-    Example serialized definition keys follow.
-
-    The 'html' type OLX file "html/introduction/definition.xml" in bundle
-    11111111-1111-1111-1111-111111111111, bundle version 5:
-
-        bundle-olx:11111111-1111-1111-1111-111111111111:5:html:html/introduction/definition.xml
-
-    The 'problem' type OLX file "problem324234.xml" in bundle
-    22222222-2222-2222-2222-222222222222, draft 'studio-draft':
-
-        bundle-olx:22222222-2222-2222-2222-222222222222:studio-draft:problem:problem/324234.xml
-
-    (The serialized version is somewhat long and verbose because it should
-    rarely be used except for debugging - the in-memory python key instance will
-    be used most of the time, and users will rarely/never see definition keys.)
-
-    User state should never be stored using a BundleDefinitionLocator as the
-    key. State should always be stored against a usage locator, which refers to
-    a particular definition being used in a particular context.
-
-    Each BundleDefinitionLocator holds the following data
-        1. Bundle UUID and [bundle version OR draft name]
-        2. Block type (e.g. 'html', 'problem', etc.)
-        3. Path to OLX file
-
-    Note that since the data in an .olx file can only ever change in a bundle
-    draft (not in a specific bundle version), an XBlock that is actively making
-    changes to its Scope.content/Scope.settings field values must have a
-    BundleDefinitionLocator with a draft name (not a bundle version).
-    """
-    CANONICAL_NAMESPACE = 'bundle-olx'
-    KEY_FIELDS = ('bundle_uuid', 'block_type', 'olx_path', '_version_or_draft')
-    __slots__ = KEY_FIELDS
-    CHECKED_INIT = False
-
-    def __init__(self, bundle_uuid, block_type, olx_path, bundle_version=None, draft_name=None, _version_or_draft=None):
-        """
-        Instantiate a new BundleDefinitionLocator
-        """
-        if not isinstance(bundle_uuid, UUID):
-            bundle_uuid = UUID(bundle_uuid)
-        check_key_string_field(block_type)
-        check_key_string_field(olx_path, regexp=r'^[\w\-./]+$')
-        # For now the following is a convention; we could remove this restriction in the future given new use cases.
-        assert block_type + '/' in olx_path, 'path should contain block type, e.g. html/id/definition.xml for html'
-
-        if (bundle_version is not None) + (draft_name is not None) + (_version_or_draft is not None) != 1:
-            raise ValueError("Exactly one of [bundle_version, draft_name, _version_or_draft] must be specified")
-        if _version_or_draft is not None:
-            if isinstance(_version_or_draft, int):
-                pass  # This is a bundle version number.
-            else:
-                # This is a draft name, not a bundle version:
-                check_draft_name(_version_or_draft)
-        elif draft_name is not None:
-            check_draft_name(draft_name)
-            _version_or_draft = draft_name
-        else:
-            assert isinstance(bundle_version, int)
-            _version_or_draft = bundle_version
-
-        super(BundleDefinitionLocator, self).__init__(
-            bundle_uuid=bundle_uuid,
-            block_type=block_type,
-            olx_path=olx_path,
-            _version_or_draft=_version_or_draft,
-        )
-
-    @property
-    def bundle_version(self):
-        return self._version_or_draft if isinstance(self._version_or_draft, int) else None
-
-    @property
-    def draft_name(self):
-        return self._version_or_draft if not isinstance(self._version_or_draft, int) else None
-
-    def _to_string(self):
-        """
-        Return a string representing this BundleDefinitionLocator
-        """
-        return ":".join((
-            six.text_type(self.bundle_uuid), six.text_type(self._version_or_draft), self.block_type, self.olx_path,
-        ))
-
-    @classmethod
-    def _from_string(cls, serialized):
-        """
-        Return a BundleDefinitionLocator by parsing the given serialized string
-        """
-        try:
-            (bundle_uuid_str, _version_or_draft, block_type, olx_path) = serialized.split(':', 3)
-        except ValueError:
-            raise InvalidKeyError(cls, serialized)
-
-        bundle_uuid = UUID(bundle_uuid_str)
-        if not block_type or not olx_path:
-            raise InvalidKeyError(cls, serialized)
-
-        if _version_or_draft.isdigit():
-            _version_or_draft = int(_version_or_draft)
-
-        return cls(
-            bundle_uuid=bundle_uuid,
-            block_type=block_type,
-            olx_path=olx_path,
-            _version_or_draft=_version_or_draft,
-        )
-
-
-class LearningContextKey(OpaqueKey):
-    """
-    A key that idenitifies a course, a library, a program,
-    or some other collection of content where learning happens.
-    """
-    KEY_TYPE = 'context_key'
-    __slots__ = ()
-
-    def make_definition_usage(self, definition_key, usage_id=None):
-        """
-        Return a usage key, given the given the specified definition key and
-        usage_id.
-        """
-        raise NotImplementedError()
-
-
-class BlockUsageKeyV2(UsageKey):
-    """
-    Abstract base class that encodes an XBlock used in a specific learning
-    context (e.g. a course).
-
-    Definition + Learning Context = Usage
-    """
-    @property
-    def context_key(self):
-        raise NotImplementedError()
-
-    @property
-    def definition_key(self):
-        """
-        Returns the definition key for this usage.
-        """
-        # Because this key definition is likely going to be moved into the
-        # opaque-keys package, we cannot put the logic here for getting the
-        # definition.
-        raise NotImplementedError(
-            "To get the definition key, use: "
-            "get_learning_context_impl(usage_key).definition_for_usage(usage_key)"
-        )
-
-    @property
-    def course_key(self):
-        warnings.warn("Use .context_key instead of .course_key", DeprecationWarning, stacklevel=2)
-        return self.context_key
-
-    def html_id(self):
-        """
-        Return an id which can be used on an html page as an id attr of an html
-        element. This is only in here for backwards-compatibility with XModules;
-        don't use in new code.
-        """
-        warnings.warn(".html_id is deprecated", DeprecationWarning, stacklevel=2)
-        # HTML5 allows ID values to contain any characters at all other than spaces.
-        # These key types don't allow spaces either, so no transform is needed.
-        return six.text_type(self)
diff --git a/openedx/core/djangoapps/xblock/learning_context/learning_context.py b/openedx/core/djangoapps/xblock/learning_context/learning_context.py
index 49fa17e40c2b9ea6f930b27e447955af392fafad..457e7f222565fb5b75b9018908e9205c43ed3068 100644
--- a/openedx/core/djangoapps/xblock/learning_context/learning_context.py
+++ b/openedx/core/djangoapps/xblock/learning_context/learning_context.py
@@ -31,7 +31,7 @@ class LearningContext(object):
 
         user: a Django User object (may be an AnonymousUser)
 
-        usage_key: the BlockUsageKeyV2 subclass used for this learning context
+        usage_key: the UsageKeyV2 subclass used for this learning context
 
         Must return a boolean.
         """
@@ -45,7 +45,7 @@ class LearningContext(object):
 
         user: a Django User object (may be an AnonymousUser)
 
-        usage_key: the BlockUsageKeyV2 subclass used for this learning context
+        usage_key: the UsageKeyV2 subclass used for this learning context
 
         Must return a boolean.
         """
@@ -57,7 +57,7 @@ class LearningContext(object):
         BundleDefinitionLocator which specifies the actual XBlock definition
         (as a path to an OLX in a specific blockstore bundle).
 
-        usage_key: the BlockUsageKeyV2 subclass used for this learning context
+        usage_key: the UsageKeyV2 subclass used for this learning context
 
         Must return a BundleDefinitionLocator if the XBlock exists in this
         context, or None otherwise.
@@ -71,7 +71,7 @@ class LearningContext(object):
 
         The child is always from an <xblock-include /> element.
 
-        parent_usage: the BlockUsageKeyV2 subclass key of the parent
+        parent_usage: the UsageKeyV2 subclass key of the parent
 
         parent_definition: the BundleDefinitionLocator key of the parent (same
             as returned by definition_for_usage(parent_usage) but included here
@@ -80,7 +80,7 @@ class LearningContext(object):
         parsed_include: the XBlockInclude tuple containing the data from the
             parsed <xblock-include /> element. See xblock.runtime.olx_parsing.
 
-        Must return a BlockUsageKeyV2 subclass
+        Must return a UsageKeyV2 subclass
         """
         raise NotImplementedError
 
diff --git a/openedx/core/djangoapps/xblock/learning_context/manager.py b/openedx/core/djangoapps/xblock/learning_context/manager.py
index d354966ee4ae89cf654d329e8aa80ffb16218234..f6eb3c701f680beca2136537c22d547ceefedea9 100644
--- a/openedx/core/djangoapps/xblock/learning_context/manager.py
+++ b/openedx/core/djangoapps/xblock/learning_context/manager.py
@@ -3,9 +3,10 @@ Helper methods for working with learning contexts
 """
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from opaque_keys.edx.keys import LearningContextKey, UsageKeyV2
+
 from openedx.core.djangoapps.xblock.apps import get_xblock_app_config
 from openedx.core.lib.plugins import PluginManager
-from .keys import LearningContextKey, BlockUsageKeyV2
 
 
 class LearningContextPluginManager(PluginManager):
@@ -35,7 +36,7 @@ def get_learning_context_impl(key):
     """
     if isinstance(key, LearningContextKey):
         context_type = key.CANONICAL_NAMESPACE  # e.g. 'lib'
-    elif isinstance(key, BlockUsageKeyV2):
+    elif isinstance(key, UsageKeyV2):
         context_type = key.context_key.CANONICAL_NAMESPACE
     else:
         # Maybe this is an older modulestore key etc.
diff --git a/openedx/core/djangoapps/xblock/runtime/blockstore_runtime.py b/openedx/core/djangoapps/xblock/runtime/blockstore_runtime.py
index 7947577babe7df5351303a1908454d506aa0aa1d..a7a6a0224d232221700dd570d85e9bf57e493411 100644
--- a/openedx/core/djangoapps/xblock/runtime/blockstore_runtime.py
+++ b/openedx/core/djangoapps/xblock/runtime/blockstore_runtime.py
@@ -6,10 +6,10 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 import logging
 
 from lxml import etree
+from opaque_keys.edx.locator import BundleDefinitionLocator
 from xblock.exceptions import NoSuchDefinition, NoSuchUsage
 from xblock.fields import ScopeIds
 
-from openedx.core.djangoapps.xblock.learning_context.keys import BundleDefinitionLocator
 from openedx.core.djangoapps.xblock.learning_context.manager import get_learning_context_impl
 from openedx.core.djangoapps.xblock.runtime.runtime import XBlockRuntime
 from openedx.core.djangoapps.xblock.runtime.olx_parsing import parse_xblock_include
diff --git a/openedx/core/djangoapps/xblock/runtime/id_managers.py b/openedx/core/djangoapps/xblock/runtime/id_managers.py
index 9aae9afa3110f9f4a708b79449c50bb3510df24d..2ba498eef326083d7e80c95290258353290ff45b 100644
--- a/openedx/core/djangoapps/xblock/runtime/id_managers.py
+++ b/openedx/core/djangoapps/xblock/runtime/id_managers.py
@@ -4,9 +4,9 @@ our newer Open edX-specific opaque key formats.
 """
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from opaque_keys.edx.keys import UsageKeyV2
 from xblock.runtime import IdReader
 
-from openedx.core.djangoapps.xblock.learning_context.keys import BlockUsageKeyV2
 from openedx.core.djangoapps.xblock.learning_context.manager import get_learning_context_impl
 
 
@@ -23,7 +23,7 @@ class OpaqueKeyReader(IdReader):
         Returns:
             The `definition_id` the usage is derived from
         """
-        if isinstance(usage_id, BlockUsageKeyV2):
+        if isinstance(usage_id, UsageKeyV2):
             return get_learning_context_impl(usage_id).definition_for_usage(usage_id)
         raise TypeError("This version of get_definition_id doesn't support the given key type.")
 
diff --git a/openedx/core/djangoapps/xblock/runtime/olx_parsing.py b/openedx/core/djangoapps/xblock/runtime/olx_parsing.py
index 04de70232ca2affd129cd68d8a52323595408ae2..edb1e759639e317afb8c67c0fe36beac9030747b 100644
--- a/openedx/core/djangoapps/xblock/runtime/olx_parsing.py
+++ b/openedx/core/djangoapps/xblock/runtime/olx_parsing.py
@@ -4,14 +4,15 @@ Helpful methods to use when parsing OLX (XBlock XML)
 from __future__ import absolute_import, division, print_function, unicode_literals
 from collections import namedtuple
 
-from openedx.core.djangoapps.xblock.learning_context.keys import BundleDefinitionLocator
+from opaque_keys.edx.locator import BundleDefinitionLocator
+
 from openedx.core.djangolib.blockstore_cache import get_bundle_direct_links_with_cache
 
 
 class BundleFormatException(Exception):
     """
     Raised when certain errors are found when parsing the OLX in a content
-    libary bundle.
+    library bundle.
     """
 
 
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index fe15add5a2071838dd47ba97b452fdce124c2ec7..502a5043737808523ed458f89ccc94911f6e38f1 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -98,7 +98,7 @@ drf-yasg==1.16
 edx-ace==0.1.10
 edx-analytics-data-api-client==0.15.3
 edx-bulk-grades==0.6.0
-edx-ccx-keys==0.2.2
+edx-ccx-keys==1.0.0
 edx-celeryutils==0.3.0
 edx-completion==2.0.0
 edx-django-oauth2-provider==1.3.5
@@ -110,7 +110,7 @@ edx-enterprise==1.9.12
 edx-i18n-tools==0.4.8
 edx-milestones==0.2.3
 edx-oauth2-provider==1.3.0
-edx-opaque-keys[django]==1.0.1
+edx-opaque-keys[django]==2.0.0
 edx-organizations==2.1.0
 edx-proctoring-proctortrack==1.0.5
 edx-proctoring==2.0.8
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index c3658c75af599879ce0dd4189ef8953d7820814f..826adb84222b126b108303f943d577ea5c0fc918 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -121,7 +121,7 @@ drf-yasg==1.16
 edx-ace==0.1.10
 edx-analytics-data-api-client==0.15.3
 edx-bulk-grades==0.6.0
-edx-ccx-keys==0.2.2
+edx-ccx-keys==1.0.0
 edx-celeryutils==0.3.0
 edx-completion==2.0.0
 edx-django-oauth2-provider==1.3.5
@@ -134,7 +134,7 @@ edx-i18n-tools==0.4.8
 edx-lint==1.3.0
 edx-milestones==0.2.3
 edx-oauth2-provider==1.3.0
-edx-opaque-keys[django]==1.0.1
+edx-opaque-keys[django]==2.0.0
 edx-organizations==2.1.0
 edx-proctoring-proctortrack==1.0.5
 edx-proctoring==2.0.8
diff --git a/requirements/edx/paver.txt b/requirements/edx/paver.txt
index eef8f1fa12be2656c493de95ca46441aef1cce4a..a4c62d73b5d6feab2cbd5c102cbdc54e975aa785 100644
--- a/requirements/edx/paver.txt
+++ b/requirements/edx/paver.txt
@@ -7,7 +7,7 @@
 argh==0.26.2              # via watchdog
 certifi==2019.9.11        # via requests
 chardet==3.0.4            # via requests
-edx-opaque-keys==1.0.1
+edx-opaque-keys==2.0.0
 idna==2.8                 # via requests
 lazy==1.1
 libsass==0.10.0
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index 38f44b19026eead2fb71f3a6325e7bdeaf5abf4d..e4843a9fc24914f7df4abbcdcf1f5190bb0acf56 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -118,7 +118,7 @@ drf-yasg==1.16
 edx-ace==0.1.10
 edx-analytics-data-api-client==0.15.3
 edx-bulk-grades==0.6.0
-edx-ccx-keys==0.2.2
+edx-ccx-keys==1.0.0
 edx-celeryutils==0.3.0
 edx-completion==2.0.0
 edx-django-oauth2-provider==1.3.5
@@ -131,7 +131,7 @@ edx-i18n-tools==0.4.8
 edx-lint==1.3.0
 edx-milestones==0.2.3
 edx-oauth2-provider==1.3.0
-edx-opaque-keys[django]==1.0.1
+edx-opaque-keys[django]==2.0.0
 edx-organizations==2.1.0
 edx-proctoring-proctortrack==1.0.5
 edx-proctoring==2.0.8
diff --git a/setup.py b/setup.py
index 316ba828f59bffab803e2e697eff9d33ef5266ef..027ba4891d2a9b0ac2d18fd5089447269c51858e 100644
--- a/setup.py
+++ b/setup.py
@@ -103,15 +103,6 @@ setup(
             "user_authn = openedx.core.djangoapps.user_authn.apps:UserAuthnConfig",
             "instructor = lms.djangoapps.instructor.apps:InstructorConfig",
         ],
-        'definition_key': [
-            'bundle-olx = openedx.core.djangoapps.xblock.learning_context.keys:BundleDefinitionLocator',
-        ],
-        'context_key': [
-            'lib = openedx.core.djangoapps.content_libraries.keys:LibraryLocatorV2',
-        ],
-        'usage_key': [
-            'lb = openedx.core.djangoapps.content_libraries.keys:LibraryUsageLocatorV2',
-        ],
         'openedx.learning_context': [
             'lib = openedx.core.djangoapps.content_libraries.library_context:LibraryContextImpl',
         ],