diff --git a/config/install/views.view.scheduler_scheduled_content.yml b/config/install/views.view.scheduler_scheduled_content.yml
index fc964d5..995b782 100644
--- a/config/install/views.view.scheduler_scheduled_content.yml
+++ b/config/install/views.view.scheduler_scheduled_content.yml
@@ -16,9 +16,7 @@ display:
   default:
     display_options:
       access:
-        type: perm
-        options:
-          perm: 'access content overview'
+        type: scheduler
       cache:
         type: tag
       query:
diff --git a/scheduler.services.yml b/scheduler.services.yml
index 12fb233..6baa6bf 100644
--- a/scheduler.services.yml
+++ b/scheduler.services.yml
@@ -6,3 +6,8 @@ services:
     class: Drupal\Core\Logger\LoggerChannel
     factory: logger.factory:get
     arguments: ['scheduler']
+  access_checker.scheduler_content:
+    class: Drupal\scheduler\Access\ScheduledListAccess
+    arguments: ['@current_user']
+    tags:
+      - { name: access_check }
diff --git a/src/Access/ScheduledListAccess.php b/src/Access/ScheduledListAccess.php
new file mode 100644
index 0000000..706fe2f
--- /dev/null
+++ b/src/Access/ScheduledListAccess.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\scheduler\Access\ScheduledListAccess.
+ */
+
+namespace Drupal\scheduler\Access;
+
+use Drupal\Core\Access\AccessCheckInterface;
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Checks access for displaying the scheduler list of scheduled nodes.
+ */
+class ScheduledListAccess implements AccessCheckInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Route $route) {
+    return $route->hasRequirement('_access_scheduler_content');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(AccountInterface $account) {
+    // All Scheduler users can see their own scheduled content via their user
+    // page. In addition, if they have 'view scheduled content' permission they
+    // will be able to see all scheduled content by all authors.
+    return ($account->hasPermission('view scheduled content') || (\Drupal::currentUser()->id() == $account->id() && $account->hasPermission('schedule publishing of nodes'))) ? AccessResult::allowed(): AccessResult::forbidden() ;
+  }
+
+}
diff --git a/src/Plugin/views/access/Scheduler.php b/src/Plugin/views/access/Scheduler.php
new file mode 100644
index 0000000..d6f88ed
--- /dev/null
+++ b/src/Plugin/views/access/Scheduler.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\scheduler\Plugin\views\access;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheableDependencyInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\views\Plugin\views\access\AccessPluginBase;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Access plugin that provides access control for Scheduler.
+ *
+ * @ingroup views_access_plugins
+ *
+ * @ViewsAccess(
+ *   id = "scheduler",
+ *   title = @Translation("Scheduler list access"),
+ *   help = @Translation("All Scheduler users can see their own scheduled content via their user page. In addition, if they have 'view scheduled content' permission they will be able to see all scheduled content by all authors."),
+ * )
+ */
+class Scheduler extends AccessPluginBase implements CacheableDependencyInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(AccountInterface $account) {
+    return \Drupal::service('access_checker.scheduler_content')->access($account);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alterRouteDefinition(Route $route) {
+    $route->setRequirement('_access_scheduler_content', 'TRUE');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return ['user'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return Cache::PERMANENT;
+  }
+
+}
diff --git a/src/Tests/SchedulerScheduledContentListAccessTest.php b/src/Tests/SchedulerScheduledContentListAccessTest.php
new file mode 100644
index 0000000..a8397c0
--- /dev/null
+++ b/src/Tests/SchedulerScheduledContentListAccessTest.php
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\scheduler\Tests\SchedulerScheduledContentListAccessTest.
+ */
+
+namespace Drupal\scheduler\Tests;
+
+/**
+ * @group scheduler
+ */
+class SchedulerScheduledContentListAccessTest extends SchedulerTestBase {
+
+  public static $modules = ['node', 'scheduler', 'views'];
+
+  public function setUp() {
+    parent::setUp();
+
+    $type = $this->nodetype->get('type');
+    $base_permissions = [
+      'access content',
+      'administer nodes',
+      'create ' . $type . ' content',
+      'edit own ' . $type . ' content',
+      'delete own ' . $type . ' content',
+      'view own unpublished content',
+    ];
+
+    $this->userA = $this->drupalCreateUser($base_permissions);
+    $this->userB = $this->drupalCreateUser(array_merge($base_permissions, ['schedule publishing of nodes']));
+    $this->userC = $this->drupalCreateUser(array_merge($base_permissions, ['schedule publishing of nodes', 'view scheduled content']));
+
+    $this->nodeA = $this->drupalCreateNode(['title' => 'Scheduled by user B', 'uid' => $this->userB->id(), 'status' => false, 'type' => $type, 'publish_on' => strtotime('+1 week')]);
+    $this->nodeB = $this->drupalCreateNode(['title' => 'Scheduled by user C', 'uid' => $this->userC->id(), 'status' => false, 'type' => $type, 'publish_on' => strtotime('+1 week')]);
+  }
+
+  /**
+   * Tests the scheduled content tab on the user page.
+   */
+  public function testViewScheduledContentUser() {
+    // Try to access the scheduled content tab for a user as anonymous visitor.
+    $this->drupalGet("user/{$this->userA->id()}/scheduled");
+    $this->assertResponse(403, 'An anonymous visitor cannot access a user\'s scheduled content tab.');
+
+    // Try to access the scheduled content tab as a user without "schedule
+    // publishing of nodes" and "view scheduled content" permission.
+    $this->drupalLogin($this->userA);
+    $this->drupalGet("user/{$this->userA->id()}/scheduled");
+    $this->assertResponse(403, 'User A does not have permission to access the scheduled content tab.');
+
+    $this->drupalLogin($this->userB);
+    $this->drupalGet("user/{$this->userB->id()}/scheduled");
+    $this->assertResponse(200, 'User B has permission to access the scheduled content tab.');
+    $this->assertText('Scheduled by user B');
+    $this->assertNoText('Scheduled by user C');
+
+    $this->drupalLogin($this->userC);
+    $this->drupalGet("user/{$this->userC->id()}/scheduled");
+    $this->assertResponse(200, 'User C has permission to access the scheduled content tab.');
+    $this->assertText('Scheduled by user C');
+    $this->assertNoText('Scheduled by user B');
+
+    $this->drupalGet("user/{$this->userB->id()}/scheduled");
+    $this->assertResponse(200, 'User C has permission to access the scheduled content tab for user B');
+
+    // User C does not have the 'bypass node access' permission, so should still
+    // not see the content scheduled by user B.
+    $this->assertNoText('Scheduled by user B');
+
+    // Since we are looking at the scheduled content for user B, the content
+    // scheduled by user C should not be listed.
+    $this->assertNoText('Scheduled by user C');
+
+    $this->drupalGet("admin/content");
+    $this->drupalGet('node/' . $this->nodeB->id());
+  }
+
+  /**
+   * Tests the scheduled content overview.
+   */
+  public function testViewScheduledContentOverview() {
+    // Try to access the scheduled content overview as anonymous visitor.
+    $this->drupalGet("admin/content/scheduled");
+    $this->assertResponse(403, 'An anonymous visitor cannot access the scheduled content overview.');
+
+    // Try to access the scheduled content overview as a user without "schedule
+    // publishing of nodes" and "view scheduled content" permission.
+    $this->drupalLogin($this->userA);
+    $this->drupalGet("admin/content/scheduled");
+    $this->assertResponse(403, 'User A does not have permission to access the scheduled content overview.');
+
+    // Try to access the scheduled content overview as a user with "schedule
+    // publishing of nodes" permission. This user should not see the content
+    // scheduled by user C.
+    $this->drupalLogin($this->userB);
+    $this->drupalGet("admin/content/scheduled");
+    $this->assertResponse(200, 'User B does have permission to access the scheduled content overview.');
+    $this->assertText('Scheduled by user B');
+    $this->assertNoText('Scheduled by user C');
+
+    // Try to access the scheduled content overview as a user with "schedule
+    // publishing of nodes" and "view scheduled content" permission.
+    $this->drupalLogin($this->userC);
+    $this->drupalGet("admin/content/scheduled");
+    $this->assertResponse(200, 'User C does have permission to access the scheduled content overview.');
+    $this->assertNoText('Scheduled by user B');
+    $this->assertText('Scheduled by user C');
+  }
+
+}
\ No newline at end of file
