diff --git a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
index 1aa35b9..91d4314 100644
--- a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
@@ -69,6 +69,7 @@ protected function alterRoutes(RouteCollection $collection) {
           'entity_type_id' => $entity_type_id,
         ),
         array(
+          '_entity_access' =>  $entity_type_id . '.view',
           '_access_content_translation_overview' => $entity_type_id,
         ),
         array(
@@ -94,6 +95,7 @@ protected function alterRoutes(RouteCollection $collection) {
 
         ),
         array(
+          '_entity_access' =>  $entity_type_id . '.view',
           '_access_content_translation_manage' => 'create',
         ),
         array(
diff --git a/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php b/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php
index bb7597c..9a11238 100644
--- a/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php
+++ b/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php
@@ -35,11 +35,13 @@ protected function setUp() {
     parent::setUp();
   }
 
+
+
   /**
    * Overrides \Drupal\content_translation\Tests\ContentTranslationUITestBase::getTranslatorPermission().
    */
   protected function getTranslatorPermissions() {
-    return array_merge(parent::getTranslatorPermissions(), array('administer entity_test content'));
+    return array_merge(parent::getTranslatorPermissions(), array('administer entity_test content', 'view test entity'));
   }
 
 }
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php
index 8d0c063..a77c7c9 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Tests\NodeTestBase;
+use Drupal\user\Entity\Role;
 
 /**
  * Tests the content translation operations available in the content listing.
@@ -75,6 +76,20 @@ function testOperationTranslateLink() {
     $this->drupalLogin($this->baseUser2);
     $this->drupalGet('admin/content');
     $this->assertLinkByHref('node/' . $node->id() . '/translations');
+
+    // Ensure that an unintended misconfiguration of permissions does not open
+    // access to the translation form. @see https://www.drupal.org/node/2558905
+    $this->drupalLogout();
+    user_role_change_permissions(
+      Role::AUTHENTICATED_ID,
+      [
+        'create content translations' => TRUE,
+        'access content' => FALSE,
+      ]
+    );
+    $this->drupalLogin($this->baseUser1);
+    $this->drupalGet('node/' . $node->id() . '/translations');
+    $this->assertResponse(403);
   }
 
 }
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
index 223bb81..b602be0 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
@@ -39,6 +39,16 @@ protected function setUp() {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  protected function getTranslatorPermissions() {
+    $permissions = parent::getTranslatorPermissions();
+    $permissions[] = 'view test entity';
+
+    return $permissions;
+  }
+
+  /**
    * Overrides \Drupal\content_translation\Tests\ContentTranslationTestBase::getEditorPermissions().
    */
   protected function getEditorPermissions() {
@@ -109,7 +119,7 @@ function testWorkflows() {
     $ops = array('create' => t('Add'), 'update' => t('Edit'), 'delete' => t('Delete'));
     $translations_url = $this->entity->urlInfo('drupal:content-translation-overview');
     foreach ($ops as $current_op => $item) {
-      $user = $this->drupalCreateUser(array($this->getTranslatePermission(), "$current_op content translations"));
+      $user = $this->drupalCreateUser(array($this->getTranslatePermission(), "$current_op content translations", 'view test entity'));
       $this->drupalLogin($user);
       $this->drupalGet($translations_url);
 
diff --git a/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php b/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php
index 485f6f5..bb349e2 100644
--- a/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php
+++ b/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php
@@ -55,6 +55,15 @@ protected function setUp() {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  protected function getTranslatorPermissions() {
+    $permissions = parent::getTranslatorPermissions();
+    $permissions[] = 'access user profiles';
+    return $permissions;
+  }
+
+  /**
    * Tests the content translation overview link field handler.
    */
   public function testTranslationLink() {
diff --git a/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php b/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php
index e3b1087..1947114 100644
--- a/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php
+++ b/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php
@@ -54,8 +54,9 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
     switch ($operation) {
       case 'view':
-        // There is no direct view.
-        return AccessResult::neutral();
+        // There is no direct viewing of a menu link, but still for purposes of
+        // content_translation we need a generic way to check access.
+        return AccessResult::allowedIfHasPermission($account, 'administer menu');
 
       case 'update':
         if (!$account->hasPermission('administer menu')) {
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
index 630f715..4759947 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
+++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
@@ -4,7 +4,7 @@ entity.entity_test.canonical:
     _entity_view: 'entity_test.full'
     _title: 'Test full view mode'
   requirements:
-    _access: 'TRUE'
+    _entity_access: 'entity_test.view'
 
 entity.entity_test.render_options:
   path: '/entity_test_converter/{foo}'
@@ -15,7 +15,7 @@ entity.entity_test.render_options:
   defaults:
     _entity_view: 'entity_test.full'
   requirements:
-    _access: 'TRUE'
+    _entity_access: 'entity_test.view'
 
 entity.entity_test.render_no_view_mode:
   path: '/entity_test_no_view_mode/{entity_test}'
