diff --git a/app/Auth/Permissions/PermissionApplicator.php b/app/Auth/Permissions/PermissionApplicator.php
index cf95f2854..e73db5157 100644
--- a/app/Auth/Permissions/PermissionApplicator.php
+++ b/app/Auth/Permissions/PermissionApplicator.php
@@ -4,6 +4,7 @@ namespace BookStack\Auth\Permissions;
 
 use BookStack\Auth\Role;
 use BookStack\Auth\User;
+use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\Page;
 use BookStack\Model;
@@ -23,32 +24,59 @@ class PermissionApplicator
     public function checkOwnableUserAccess(Model $ownable, string $permission): bool
     {
         $explodedPermission = explode('-', $permission);
-
-        $baseQuery = $ownable->newQuery()->where('id', '=', $ownable->id);
-        $action = end($explodedPermission);
+        $action = $explodedPermission[1] ?? $explodedPermission[0];
         $user = $this->currentUser();
+        $userRoleIds = $this->getCurrentUserRoleIds();
 
+        $allRolePermission = $user->can($permission . '-all');
+        $ownRolePermission = $user->can($permission . '-own');
         $nonJointPermissions = ['restrictions', 'image', 'attachment', 'comment'];
+        $ownerField = ($ownable instanceof Entity) ? 'owned_by' : 'created_by';
+        $isOwner = $user->id === $ownable->getAttribute($ownerField);
+        $hasRolePermission = $allRolePermission || ($isOwner && $ownRolePermission);
 
         // Handle non entity specific jointPermissions
         if (in_array($explodedPermission[0], $nonJointPermissions)) {
-            $allPermission = $user && $user->can($permission . '-all');
-            $ownPermission = $user && $user->can($permission . '-own');
-            $ownerField = ($ownable instanceof Entity) ? 'owned_by' : 'created_by';
-            $isOwner = $user && $user->id === $ownable->$ownerField;
-
-            return $allPermission || ($isOwner && $ownPermission);
+            return $hasRolePermission;
         }
 
-        // Handle abnormal create jointPermissions
-        if ($action === 'create') {
-            $action = $permission;
+        $entityPermissions = $this->getApplicableEntityPermissions($ownable, $userRoleIds, $action);
+        if (is_null($entityPermissions)) {
+            return $hasRolePermission;
         }
 
-        // TODO - Use a non-query based check
-        $hasAccess = $this->entityRestrictionQuery($baseQuery, $action)->count() > 0;
+        return count($entityPermissions) > 0;
+    }
 
-        return $hasAccess;
+    /**
+     * Get the permissions that are applicable for the given entity item.
+     * Returns null when no entity permissions apply otherwise entity permissions
+     * are active, even if the returned array is empty.
+     *
+     * @returns EntityPermission[]
+     */
+    protected function getApplicableEntityPermissions(Entity $entity, array $userRoleIds, string $action): ?array
+    {
+        $chain = [$entity];
+        if ($entity instanceof Page && $entity->chapter_id) {
+            $chain[] = $entity->chapter;
+        }
+
+        if ($entity instanceof Page || $entity instanceof Chapter) {
+            $chain[] = $entity->book;
+        }
+
+        foreach ($chain as $currentEntity) {
+            if ($currentEntity->restricted) {
+                return $currentEntity->permissions()
+                    ->whereIn('role_id', $userRoleIds)
+                    ->where('action', '=', $action)
+                    ->get()
+                    ->all();
+            }
+        }
+
+        return null;
     }
 
     /**
@@ -76,26 +104,6 @@ class PermissionApplicator
         return $hasPermission;
     }
 
-    /**
-     * The general query filter to remove all entities
-     * that the current user does not have access to.
-     */
-    protected function entityRestrictionQuery(Builder $query, string $action): Builder
-    {
-        $q = $query->where(function ($parentQuery) use ($action) {
-            $parentQuery->whereHas('jointPermissions', function ($permissionQuery) use ($action) {
-                $permissionQuery->whereIn('role_id', $this->getCurrentUserRoleIds())
-                    // TODO - Delete line once only views
-                    ->where('action', '=', $action)
-                    ->where(function (Builder $query) {
-                        $this->addJointHasPermissionCheck($query, $this->currentUser()->id);
-                    });
-            });
-        });
-
-        return $q;
-    }
-
     /**
      * Limited the given entity query so that the query will only
      * return items that the user has view permission for.
@@ -139,7 +147,27 @@ class PermissionApplicator
             $this->enforceDraftVisibilityOnQuery($query);
         }
 
-        return $this->entityRestrictionQuery($query, 'view');
+        return $this->entityRestrictionQuery($query);
+    }
+
+    /**
+     * The general query filter to remove all entities
+     * that the current user does not have access to.
+     */
+    protected function entityRestrictionQuery(Builder $query): Builder
+    {
+        $q = $query->where(function ($parentQuery) {
+            $parentQuery->whereHas('jointPermissions', function ($permissionQuery) {
+                $permissionQuery->whereIn('role_id', $this->getCurrentUserRoleIds())
+                    // TODO - Delete line once only views
+                    ->where('action', '=', 'view')
+                    ->where(function (Builder $query) {
+                        $this->addJointHasPermissionCheck($query, $this->currentUser()->id);
+                    });
+            });
+        });
+
+        return $q;
     }
 
     /**