 core/modules/content_moderation/content_moderation.module | 10 ----------
 .../src/Entity/ContentModerationState.php                 |  1 +
 .../src/Kernel/ContentModerationStateResourceTest.php     |  2 +-
 core/modules/rest/src/Plugin/Deriver/EntityDeriver.php    |  4 ++++
 .../EntityResource/EntityResourceRestTestCoverageTest.php | 15 ++++++---------
 5 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module
index 985f91f..99578fb 100644
--- a/core/modules/content_moderation/content_moderation.module
+++ b/core/modules/content_moderation/content_moderation.module
@@ -301,13 +301,3 @@ function content_moderation_workflow_update(WorkflowInterface $entity) {
   // Clear field cache so extra field is added or removed.
   \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
 }
-
-/**
- * Implements hook_rest_resource_alter().
- */
-function content_moderation_rest_resource_alter(&$definitions) {
-  // ContentModerationState is an internal entity type. Therefore it should not
-  // be exposed via REST.
-  // @see \Drupal\content_moderation\ContentModerationStateAccessControlHandler
-  unset($definitions['entity:content_moderation_state']);
-}
diff --git a/core/modules/content_moderation/src/Entity/ContentModerationState.php b/core/modules/content_moderation/src/Entity/ContentModerationState.php
index e54fbbe..02cecfb 100644
--- a/core/modules/content_moderation/src/Entity/ContentModerationState.php
+++ b/core/modules/content_moderation/src/Entity/ContentModerationState.php
@@ -31,6 +31,7 @@
  *   data_table = "content_moderation_state_field_data",
  *   revision_data_table = "content_moderation_state_field_revision",
  *   translatable = TRUE,
+ *   internal = TRUE,
  *   entity_keys = {
  *     "id" = "id",
  *     "revision" = "revision_id",
diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateResourceTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateResourceTest.php
index cc09e59..2ea1d8f 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateResourceTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateResourceTest.php
@@ -18,7 +18,7 @@ class ContentModerationStateResourceTest extends KernelTestBase {
   public static $modules = ['serialization', 'rest', 'content_moderation'];
 
   /**
-   * @see content_moderation_rest_resource_alter()
+   * @see \Drupal\content_moderation\Entity\ContentModerationState
    */
   public function testCreateContentModerationStateResource() {
     $this->setExpectedException(PluginNotFoundException::class, 'The "entity:content_moderation_state" plugin does not exist.');
diff --git a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
index a74e8b2..e631f5d 100644
--- a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
+++ b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
@@ -65,6 +65,10 @@ public function getDerivativeDefinitions($base_plugin_definition) {
     if (!isset($this->derivatives)) {
       // Add in the default plugin configuration and the resource type.
       foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
+        if ($entity_type->isInternal()) {
+          continue;
+        }
+
         $this->derivatives[$entity_type_id] = [
           'id' => 'entity:' . $entity_type_id,
           'entity_type' => $entity_type_id,
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
index d10d55c..6421472 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\rest\Functional\EntityResource;
 
+use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -45,15 +46,11 @@ protected function setUp() {
 
     $this->definitions = $this->container->get('entity_type.manager')->getDefinitions();
 
-    // Remove definitions for which the REST resource plugin definition was
-    // removed via hook_rest_resource_alter(). Entity types which are never
-    // exposed via REST also don't need test coverage.
-    $resource_plugin_ids = array_keys($this->container->get('plugin.manager.rest')->getDefinitions());
-    foreach (array_keys($this->definitions) as $entity_type_id) {
-      if (!in_array("entity:$entity_type_id", $resource_plugin_ids, TRUE)) {
-        unset($this->definitions[$entity_type_id]);
-      }
-    }
+    // Entity types marked as "internal" are not exposed by the entity REST
+    // resource plugin and hence also don't need test coverage.
+    $this->definitions = array_filter($this->definitions, function (EntityTypeInterface $entity_type) {
+      return !$entity_type->isInternal();
+    });
   }
 
   /**
