diff --git a/src/cas.rs b/src/cas.rs
index 297b7d28e17ba6b6ea6ea9030644e972fee93ff8..facfd485bf1577d4aa72c4788e576eb942d4b972 100644
--- a/src/cas.rs
+++ b/src/cas.rs
@@ -198,6 +198,14 @@ fn proc_cas_local(req: Request) -> Result<Response> {
         .into());
     }
 
+    // Check that sender is allowed to apply this operation.
+    // Executed as one of the first checks to prevent spending time on
+    // expensive range checks if the sender has no permissions for this operation.
+    //
+    // Note: audit log record is automatically emmitted in case there is an error,
+    // because it is hooked into AccessDenied error creation (on_access_denied) trigger
+    access_control::access_check_op(storage, &req.op, req.as_user)?;
+
     let last_persisted = raft::Storage::last_index(raft_storage)?;
     assert!(last_persisted <= last);
 
@@ -266,10 +274,6 @@ fn proc_cas_local(req: Request) -> Result<Response> {
         req.predicate.check_entry(entry.index, &op, storage)?;
     }
 
-    // Note: audit log record is automatically emmitted in case there is an error,
-    // because it is hooked into AccessDenied error creation (on_access_denied) trigger
-    access_control::access_check_op(storage, &req.op, req.as_user)?;
-
     if let Op::Dml(dml) = &req.op {
         // Check if the requested dml is applicable to the local storage.
         // This will run the required on_replace triggers which will check among