diff --git a/private_content/private_content.module b/private_content/private_content.module
index fb76c7e..f46309e 100644
--- a/private_content/private_content.module
+++ b/private_content/private_content.module
@@ -77,15 +77,18 @@ function private_content_entity_base_field_info(EntityTypeInterface $entity_type
  * Implements hook_node_grants().
  */
 function private_content_node_grants(AccountInterface $account, $op) {
-  // First grant a grant to the author for own content.
-  $grants['private_author'] = array($account->id());
+  $grants = array();
 
-  if ($op == 'view' && $account->hasPermission('access private content')) {
-    $grants['private_view'] = array(PRIVATE_GRANT_ALL);
-  }
+  if ($op == 'view') {
+    if ($account->uid != 0) {
+      // Grant to the author for own content.
+      $grants['private_author'] = array($account->uid);
+    }
 
-  if (($op == 'update' || $op == 'delete') && $account->hasPermission('edit private content')) {
-    $grants['private_edit'] = array(PRIVATE_GRANT_ALL);
+    // Grant for private content.
+    if ($account->hasPermission('access private content')) {
+      $grants['private_view'] = array(PRIVATE_GRANT_ALL);
+    }
   }
 
   return $grants;
@@ -103,10 +106,18 @@ function private_content_node_access_records(NodeInterface $node) {
     return;
   }
 
-  // We only care about the node if it's been marked private. If not, it is
-  // treated just like any other node and we completely ignore it.
-  if (isset($node->private) && $node->private->value == 1) {
-    $grants = array();
+  // This code typically runs when something has changed, so make sure the database entry is up to date.
+//  private_node_update($node); - we don't have this function in the d8 version?
+
+  // See the README.txt file and the comment "STRATEGY" at the top of this file for background explanation.
+  // 1) Ignore update permissions here as they are handled in hook_access.
+  //    It's not safe to grant update access here to a private node because we cannot be sure the user is entitled.
+  // 2) Ignore any nodes where we don't wish to alter the default access; other modules may grants access,
+  //    or else core provides the correct default access.
+  $grants = array();
+
+  if ($node->status && $node->private) {
+    // Grant read access to users with 'access private content'.    $grants = array();
     $grants[] = array(
       'realm' => 'private_view',
       'gid' => PRIVATE_GRANT_ALL,
@@ -115,75 +126,95 @@ function private_content_node_access_records(NodeInterface $node) {
       'grant_delete' => 0,
       'priority' => 0,
     );
-    $grants[] = array(
-      'realm' => 'private_edit',
-      'gid' => PRIVATE_GRANT_ALL,
-      'grant_view' => 1,
-      'grant_update' => 1,
-      'grant_delete' => 1,
-      'priority' => 0,
-    );
-    $grants[] = array(
-      'realm' => 'private_author',
-      'gid' => $node->getOwnerId(),
-      'grant_view' => 1,
-      'grant_update' => 1,
-      'grant_delete' => 1,
-      'priority' => 0,
-    );
 
-    return $grants;
+    // Grant read access to the owner, but not ANONYMOUS user.
+    if ($node->uid != 0) {
+      $grants[] = array(
+        'realm' => 'private_author',
+        'gid' => $node->uid,
+        'grant_view' => 1,
+        'grant_update' => 0,
+        'grant_delete' => 0,
+        'priority' => 0,
+      );
+    }
+
+    // Otherwise, deny read access for private nodes.
+   }
+
+  return $grants;
+}
+
+/**
+ * Implements hook_node_access().
+ */
+function private_content_node_access($node, $op, $account) {
+  if (is_string($node)) {
+    return AccessResult::neutral();
   }
+
+  // Apply restrictions on private nodes, except for the owner.
+  $owner = ($account->uid != 0) && ($node->uid == $account->uid);
+  if ($node->private && !$owner) {
+    if (($op == 'update') || ($op == 'delete')) {
+      if (!$account->hasPermission('edit private content')) {
+        // Missing access for write.
+        return AccessResult::forbidden();
+      }
+    }
+    elseif ($op == 'view') {
+      if (!$account->hasPermission('access private content')) {
+        // Missing access for view.
+        return AccessResult::forbidden();
+      }
+    }
+  }
+
+  // Otherwise, fall back to the pre-existing access rules in core/modules.
+  // Note that this module never grants extra access, it only removes it.
+  return AccessResult::neutral();
 }
 
 /**
  * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
  *
- * This module adds a simple checkbox to the node form labeled private. If the
- * checkbox is labelled, only the node author and users with
- * 'access private content' privileges may see it.
+ * This module adds a simple checkbox to the node to edit the private setting.
  */
 function private_content_form_node_form_alter(&$form, &$form_state) {
   /** @var \Drupal\Node\NodeInterface $node */
   $node = $form_state->getFormObject()->getEntity();
-  /** @var \Drupal\node\NodeTypeInterface $node_type */
-  $node_type = $node->type->entity;
-  $default = $node_type->getThirdPartySetting('private_content', 'private', PRIVATE_ALLOWED);
 
-  if ($default != PRIVATE_DISABLED || !empty($node->private->value)) {
-    if ($node->isNew()) {
-      $privacy = ($default > PRIVATE_ALLOWED);
-    }
-    else {
-      $privacy = isset($node->private) ? $node->private->value : 0;
-    }
+  // Won't have the ->private field set when creating a new node.
+  private_get_default($node);
 
-    if (\Drupal::currentUser()->hasPermission('mark content as private') && $default != PRIVATE_ALWAYS) {
-      if (\Drupal::currentUser()->hasPermission('administer nodes')) {
-        $form['options']['private'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Make this post private'),
-          '#attributes' => array('title' => t('When checked, only users with proper access permissions will be able to see this post.')),
-          '#default_value' => $privacy,
-        );
-      }
-      else {
-        $form['private'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Make this post private'),
-          '#attributes' => array('title' => t('When checked, only users with proper access permissions will be able to see this post.')),
-          '#default_value' => $privacy,
-          '#weight' => 99,
-        );
-      }
+  if (\Drupal::currentUser()->hasPermission('mark content as private') && $default != PRIVATE_ALWAYS) {
+    if (\Drupal::currentUser()->hasPermission('administer nodes')) {
+      $form['options']['private'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Make this post private'),
+        '#attributes' => array('title' => t('When checked, only users with proper access permissions will be able to see this post.')),
+        '#default_value' => $node->private,
+        '#disabled' => $node->privateLocked,
+      );
     }
     else {
       $form['private'] = array(
-        '#type' => 'value',
-        '#value' => $privacy,
+        '#type' => 'checkbox',
+        '#title' => t('Make this post private'),
+        '#attributes' => array('title' => t('When checked, only users with proper access permissions will be able to see this post.')),
+        '#default_value' => $node->private,
+        '#weight' => 99,
+        '#disabled' => $node->privateLocked,
       );
     }
   }
+  else {
+    $form['private'] = array(
+      '#type' => 'value',
+      '#value' => $node->private,
+        '#disabled' => $node->privateLocked,
+    );
+  }
 }
 
 /**
@@ -196,6 +227,7 @@ function private_content_form_node_type_form_alter(&$form, FormStateInterface $f
   $form['workflow']['private'] = array(
     '#type' => 'radios',
     '#title' => t('Privacy'),
+    '#description' => t('Privacy settings for nodes of this content type.  Changing this value will update all existing nodes and rebuild access permissions.'),
     '#options' => array(
       PRIVATE_DISABLED => t('Disabled (always public)'),
       PRIVATE_ALLOWED => t('Enabled (public by default)'),
@@ -206,6 +238,8 @@ function private_content_form_node_type_form_alter(&$form, FormStateInterface $f
   );
 
   $form['#entity_builders'][] = 'private_content_form_node_type_form_builder';
+
+  $form['#submit'][] = 'private_node_type_submit';
 }
 
 /**
@@ -216,3 +250,27 @@ function private_content_form_node_type_form_alter(&$form, FormStateInterface $f
 function private_content_form_node_type_form_builder($entity_type, NodeTypeInterface $type, &$form, FormStateInterface $form_state) {
   $type->setThirdPartySetting('private_content', 'private', $form_state->getValue('private'));
 }
+
+
+/**
+ * Submit handler for node type edit form.
+ */
+function private_node_type_submit($form, &$form_state) {
+  if ($form_state['values']['private'] != $form['workflow']['private']['#default_value']) {
+    node_access_needs_rebuild(TRUE);
+  }
+}
+
+/**
+ * Apply default private settings to node based on the content type.
+ */
+function private_content_get_default($node) {
+  if (!isset($node->private)) {
+    /** @var \Drupal\node\NodeTypeInterface $node_type */
+    $node_type = $node->type->entity;
+    $typeSetting = $node_type->getThirdPartySetting('private_content', 'private', PRIVATE_ALLOWED);
+
+    $node->private = ($typeSetting == PRIVATE_ALWAYS) || ($typeSetting == PRIVATE_AUTOMATIC);
+    $node->privateLocked = ($typeSetting == PRIVATE_ALWAYS) || ($typeSetting == PRIVATE_DISABLED);
+   }
+ }
