diff --git a/src/client/common.mk b/src/client/common.mk
index ad58f61e9c01b3b07702c3e1b9a49b87f22d13f3..7f34e2ee3aa909433eec9f6ec57c4254f73e98eb 100644
--- a/src/client/common.mk
+++ b/src/client/common.mk
@@ -56,7 +56,7 @@ build:
 	@echo "[Building for $(OS) $(ARCH)]" ;\
 	if [ $(OS) = "linux" ]; then \
 		GOARCH=$(ARCH) GOOS=$(OS) CGO_ENABLED=0 go $(build_flags) -o  build/$(ARCH)/$(OS)/ ;\
-		strip -s build/$(ARCH)/$(OS)/$(bin) ;\
+		#strip -s build/$(ARCH)/$(OS)/$(bin) ;\
 		#upx build/$(ARCH)/$(OS)/$(bin) ;\
 	else \
 		echo "GOARCH=$(ARCH) GOOS=$(OS) go $(build_flags) -o build/$(ARCH)/$(OS)/" ;\
@@ -76,7 +76,7 @@ build_all:
 				echo "[Building for $$os $$arch]" ;\
 				if [ $$os = "linux" ]; then \
 					GOARCH=$$arch GOOS=$$os CGO_ENABLED=0 go $(build_flags) -o  build/$$arch/$$os/ ;\
-					strip -s build/$$arch/$$os/$(bin) ;\
+					#strip -s build/$$arch/$$os/$(bin) ;\
 					#upx build/$$arch/$$os/$(bin) ;\
 				else \
 					echo "GOARCH=$$arch GOOS=$$os go $(build_flags) -o build/$$arch/$$os/" ;\
diff --git a/src/common/caps/caps.go b/src/common/caps/caps.go
index e59ca2f3bc33e6f9ae15678d20a9a9829409b8f5..ffc63580b7c791ceb1c4169a319095e13bb2dfc2 100644
--- a/src/common/caps/caps.go
+++ b/src/common/caps/caps.go
@@ -27,6 +27,7 @@ const (
     CAP_VM_EDIT              = "VM_EDIT"
     CAP_VM_EDIT_ANY          = "VM_EDIT_ANY"
     CAP_VM_SET_ACCESS        = "VM_SET_ACCESS"
+    CAP_VM_SET_ACCESS_ANY    = "VM_SET_ACCESS_ANY"
     CAP_VM_READFS            = "VM_READFS"
     CAP_VM_READFS_ANY        = "VM_READFS_ANY"
     CAP_VM_WRITEFS           = "VM_WRITEFS"
@@ -58,6 +59,7 @@ var userCaps = Capabilities {
     CAP_VM_REBOOT_ANY: 1,
     CAP_VM_LIST_ANY: 1,
     CAP_VM_SET_ACCESS: 1,
+    CAP_VM_SET_ACCESS_ANY: 1,
     CAP_VM_READFS_ANY: 1,
     CAP_VM_WRITEFS_ANY: 1,
 
diff --git a/src/server/router/router.go b/src/server/router/router.go
index 348ae345d1e0716898edc51be381f0c84b1dba7a..5941b102b860c04a83f56b7362fab83360a1f7e3 100644
--- a/src/server/router/router.go
+++ b/src/server/router/router.go
@@ -78,13 +78,13 @@ func (router *Router)Start(port int) {
     vmsGroup.GET("/stop", router.vms.GetStoppableVMs)
     vmsGroup.GET("/reboot", router.vms.GetRebootableVMs)
     vmsGroup.GET("/edit", router.vms.GetEditableVMs)
-    vmsGroup.GET("/editaccess", router.vms.GetEditableVMAccessVMs)
+    vmsGroup.GET("/editaccess", router.vms.GetModifiableVMAccessVMs)
     vmsGroup.GET("/exportdir", router.vms.GetDirExportableVMs)
     vmsGroup.GET("/importfiles", router.vms.GetFilesImportableVMs)
 
     vmsGroup.POST("", router.vms.CreateVM)
-    vmsGroup.DELETE("/:id", router.vms.DeleteVMByID)
-    vmsGroup.PUT("/:id", router.vms.EditVMByID)
+    vmsGroup.DELETE("/:id", router.vms.DeleteVM)
+    vmsGroup.PUT("/:id", router.vms.EditVM)
     vmsGroup.PUT("/:id/start", router.vms.StartVM)
     vmsGroup.PUT("/:id/startwithcreds", router.vms.StartVMWithCreds)
     vmsGroup.PUT("/:id/stop", router.vms.KillVM)
@@ -102,8 +102,8 @@ func (router *Router)Start(port int) {
     templatesGroup.POST("/vm", router.tpl.CreateTemplateFromVM)
     templatesGroup.POST("/qcow", router.tpl.CreateTemplateFromQCOW)
     templatesGroup.GET("/:id/disk", router.tpl.ExportDisk)
-    templatesGroup.DELETE("/:id", router.tpl.DeleteTemplateByID)
-    templatesGroup.PUT("/:id", router.tpl.EditTemplateByID)
+    templatesGroup.DELETE("/:id", router.tpl.DeleteTemplate)
+    templatesGroup.PUT("/:id", router.tpl.EditTemplate)
 
     // Starts server in a dedicated goroutine.
     go func() {
diff --git a/src/server/router/routerTemplates.go b/src/server/router/routerTemplates.go
index 2038ae72058721041d60f17f87b0c37e5dc5fb6d..af611957b884190d1c23d67f492c1ffe9bbcf3f4 100644
--- a/src/server/router/routerTemplates.go
+++ b/src/server/router/routerTemplates.go
@@ -186,7 +186,7 @@ func (r *RouterTemplates)CreateTemplateFromQCOW(c echo.Context) error {
 // CAP_TPL_DESTROY: only a template owned by the user can be deleted.
 // Remark: a template can only be deleted if no VM references it!
 // curl --cacert ca.pem -X DELETE https://localhost:1077/templates/4913a2bb-edfe-4dfe-af53-38197a44523b -H "Authorization: Bearer <AccessToken>"
-func (r *RouterTemplates)DeleteTemplateByID(c echo.Context) error {
+func (r *RouterTemplates)DeleteTemplate(c echo.Context) error {
     // Retrieves logged user from context.
     user, err := getLoggedUser(r.users, c)
     if err != nil {
@@ -226,7 +226,7 @@ func (r *RouterTemplates)DeleteTemplateByID(c echo.Context) error {
 // CAP_TPL_EDIT_ANY: any template can be edited.
 // CAP_TPL_EDIT: only a template owned by the user can be edited.
 // curl --cacert ca.pem -X PUT https://localhost:1077/templates/4913a2bb-edfe-4dfe-af53-38197a44523b -H "Authorization: Bearer <AccessToken>"
-func (r *RouterTemplates)EditTemplateByID(c echo.Context) error {
+func (r *RouterTemplates)EditTemplate(c echo.Context) error {
     // Retrieves logged user from context.
     user, err := getLoggedUser(r.users, c)
     if err != nil {
diff --git a/src/server/router/routerVMs.go b/src/server/router/routerVMs.go
index 018c56c4a9b7a2290b9a8cb61ba9063d4bf0c5b2..3f3670a411f876d9ed9b81c2d4483b4d7132f2d1 100644
--- a/src/server/router/routerVMs.go
+++ b/src/server/router/routerVMs.go
@@ -3,6 +3,7 @@ package router
 import (
     "io"
     "os"
+    // "errors"
     "net/http"
     "path/filepath"
     "nexus-common/caps"
@@ -35,7 +36,7 @@ func NewRouterVMs() *RouterVMs {
 // VM access cap: CAP_VM_LIST: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetListableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm *vms.VM) bool {
         return true
     })
 }
@@ -46,7 +47,7 @@ func (r *RouterVMs)GetListableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_LIST: returns all running VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/attach -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetAttachableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm *vms.VM) bool {
         return vm.IsRunning()
     })
 }
@@ -57,7 +58,7 @@ func (r *RouterVMs)GetAttachableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_DESTROY: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/del -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetDeletableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(vm *vms.VM) bool {
         return !vm.IsRunning()
     })
 }
@@ -68,7 +69,7 @@ func (r *RouterVMs)GetDeletableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_START: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/start -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetStartableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(vm *vms.VM) bool {
         return !vm.IsRunning()
     })
 }
@@ -79,7 +80,7 @@ func (r *RouterVMs)GetStartableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_STOP: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/stop -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetStoppableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(vm *vms.VM) bool {
         return vm.IsRunning()
     })
 }
@@ -90,7 +91,7 @@ func (r *RouterVMs)GetStoppableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_REBOOT: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/reboot -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(vm *vms.VM) bool {
         return vm.IsRunning()
     })
 }
@@ -101,36 +102,41 @@ func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_EDIT: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/edit -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetEditableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm *vms.VM) bool {
         return !vm.IsRunning()
     })
 }
 
-// Returns VMs that can have their access set or deleted.
-// Requires to be the VM's owner, or BOTH capabilities:
+// Returns VMs that can have their access modified (set or deleted).
+// REMARK: running VMs are filtered out, even if they can be modified!
+// Requires to be the VM's owner, or to have VM_SET_ACCESS_ANY capability, or to have BOTH capabilities:
 // User cap: CAP_VM_SET_ACCESS
 // VM access cap: CAP_VM_SET_ACCESS
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/editaccess -H "Authorization: Bearer <AccessToken>"
-func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
+func (r *RouterVMs)GetModifiableVMAccessVMs(c echo.Context) error {
     // Retrieves logged user from context.
     user, err := getLoggedUser(r.users, c)
     if err != nil {
         return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
     }
 
-    return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
-        func(vm *vms.VM) bool {
-            // First, checks if the user is the VM's owner
+    // Checks whether the logged user is allowed to modify (add/remove) a VM's VM access.
+    isModifyVMAccessAllowed := func(user *users.User, vm *vms.VM) bool {
+        // If user has VM_SET_ACCESS_ANY, modify is allowed.
+        if user.HasCapability(caps.CAP_VM_SET_ACCESS_ANY) {
+            return true
+        } else {
+            // If user is the VM's owner, modify is allowed.
             if vm.IsOwner(user.Email) {
-                return !vm.IsRunning()
+                return true
             } else {
-                // Then, checks that user has CAP_VM_SET_ACCESS and also that
-                // VM access has CAP_VM_SET_ACCESS set for the user
+                // If user has VM_SET_ACCESS and VM's VM access is present for the same user,
+                // modify is allowed.
                 if user.HasCapability(caps.CAP_VM_SET_ACCESS) {
                     capabilities, exists := vm.GetAccess()[user.Email]
                     if exists {
-                        _, visible := capabilities[caps.CAP_VM_SET_ACCESS]
-                        return visible && !vm.IsRunning()
+                        _, found := capabilities[caps.CAP_VM_SET_ACCESS]
+                        return found
                     } else {
                         return false
                     }
@@ -138,7 +144,14 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
                     return false
                 }
             }
-          }), "    ")
+        }
+    }
+
+    filterFunc := func(vm *vms.VM) bool {
+        return isModifyVMAccessAllowed(user, vm) && !vm.IsRunning()
+    }
+
+    return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(filterFunc), "    ")
 }
 
 // Returns VMs that can have a directory exported.
@@ -147,7 +160,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
 // VM access cap: VM_READFS: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/exportdir -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetDirExportableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(vm *vms.VM) bool {
         return true
     })
 }
@@ -158,7 +171,7 @@ func (r *RouterVMs)GetDirExportableVMs(c echo.Context) error {
 // VM access cap: VM_WRITEFS: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/importfiles -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetFilesImportableVMs(c echo.Context) error {
-    return r.performVMsList(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(vm *vms.VM) bool {
+    return r.getFilteredVMs(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(vm *vms.VM) bool {
         return true
     })
 }
@@ -202,8 +215,8 @@ func (r *RouterVMs)CreateVM(c echo.Context) error {
 // User cap: CAP_VM_DESTROY_ANY: any VM can be deleted.
 // VM access cap: CAP_VM_DESTROY: any of the VMs with this cap for the logged user can be deleted.
 // curl --cacert ca.pem -X DELETE https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59 -H "Authorization: Bearer <AccessToken>"
-func (r *RouterVMs)DeleteVMByID(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(c echo.Context, vm *vms.VM) error {
+func (r *RouterVMs)DeleteVM(c echo.Context) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(c echo.Context, vm *vms.VM) error {
         if err := r.vms.DeleteVM(vm.GetID()); err != nil {
             return echo.NewHTTPError(http.StatusNotFound, err.Error())
         }
@@ -217,7 +230,7 @@ func (r *RouterVMs)DeleteVMByID(c echo.Context) error {
 // VM access cap: CAP_VM_START: any of the VMs with this cap for the logged user can be started.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/start -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)StartVM(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(c echo.Context, vm *vms.VM) error {
         _, _, err := r.vms.StartVM(vm.GetID())
         if err != nil {
             return echo.NewHTTPError(http.StatusBadRequest, err.Error())
@@ -232,7 +245,7 @@ func (r *RouterVMs)StartVM(c echo.Context) error {
 // VM access cap: CAP_VM_START: any of the VMs with this cap for the logged user can be started.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/startwithcreds -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)StartVMWithCreds(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(c echo.Context, vm *vms.VM) error {
 
         // Deserializes and validates client's parameters.
         p := new(params.VMStartWithCreds)
@@ -253,7 +266,7 @@ func (r *RouterVMs)StartVMWithCreds(c echo.Context) error {
 // VM access cap: CAP_VM_STOP: any of the VMs with this cap for the logged user can be killed.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/stop -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)KillVM(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
         if err := r.vms.KillVM(vm.GetID()); err != nil {
             return echo.NewHTTPError(http.StatusNotFound, err.Error())
         }
@@ -267,7 +280,7 @@ func (r *RouterVMs)KillVM(c echo.Context) error {
 // VM access cap: CAP_VM_STOP: any of the VMs with this cap for the logged user can be shutdown.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/shutdown -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)ShutdownVM(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
         if err := r.vms.ShutdownVM(vm.GetID()); err != nil {
             return echo.NewHTTPError(http.StatusNotFound, err.Error())
         }
@@ -281,7 +294,7 @@ func (r *RouterVMs)ShutdownVM(c echo.Context) error {
 // VM access cap: CAP_VM_REBOOT: any of the VMs with this cap for the logged user can be rebooted.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/stop -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)RebootVM(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(c echo.Context, vm *vms.VM) error {
         if err := r.vms.RebootVM(vm.GetID()); err != nil {
             return echo.NewHTTPError(http.StatusNotFound, err.Error())
         }
@@ -294,8 +307,8 @@ func (r *RouterVMs)RebootVM(c echo.Context) error {
 // User cap: CAP_VM_EDIT_ANY: any VM can be edited.
 // VM access cap: CAP_VM_EDIT: any of the VMs with this cap for the logged user can be edited.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59 -H 'Content-Type: application/json' -d '{"name":"Edited VM","cpus":1,"ram":2048,"nic":"user","usbDevs":["1307:0165","1234:abcd"]}' -H "Authorization: Bearer <AccessToken>"
-func (r *RouterVMs)EditVMByID(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(c echo.Context, vm *vms.VM) error {
+func (r *RouterVMs)EditVM(c echo.Context) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(c echo.Context, vm *vms.VM) error {
         // Deserializes and validates client's parameters.
         // Given these parameters are optional, we can't use a validator on them.
         // Validation is performed in vm.EditVM() instead.
@@ -311,7 +324,7 @@ func (r *RouterVMs)EditVMByID(c echo.Context) error {
 }
 
 // Set a VM access for a given user.
-// Requires to be the VM's owner, or BOTH capabilities:
+// Requires to be the VM's owner, or to have VM_SET_ACCESS_ANY capability, or to have BOTH capabilities:
 // User cap: CAP_VM_SET_ACCESS
 // VM access cap: CAP_VM_SET_ACCESS
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/caps/janedoes@nexus.org -H 'Content-Type: application/json' -d '{"caps":{"VM_LIST":1,"VM_START":1,"VM_STOP":1}}' -H "Authorization: Bearer <AccessToken>"
@@ -335,20 +348,6 @@ func (r *RouterVMs)SetVMAccessForUser(c echo.Context) error {
         return echo.NewHTTPError(http.StatusBadRequest, err.Error())
     }
 
-    // Retrieves the VM to modify.
-    vm, err := r.vms.GetVM(vmID)
-    if err != nil {
-        return echo.NewHTTPError(http.StatusNotFound, err.Error())
-    }
-
-    // First, check that the logged user is the VM's owner.
-    if !vm.IsOwner(user.Email) {
-        // Next, checks the logged user has the VM_SET_ACCESS capability.
-        if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-            return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-        }
-    }
-
     // Deserializes and validates client's parameters.
     p := new(params.VMAddAccess)
     if err := decodeJson(c, &p); err != nil {
@@ -358,7 +357,7 @@ func (r *RouterVMs)SetVMAccessForUser(c echo.Context) error {
         return echo.NewHTTPError(http.StatusBadRequest, err.Error())
     }
 
-    if err = r.vms.SetVMAccess(vmID, user.Email, email, p.Access); err != nil {
+    if err = r.vms.SetVMAccess(vmID, user, email, p.Access); err != nil {
         return echo.NewHTTPError(http.StatusBadRequest, err.Error())
     }
 
@@ -383,25 +382,11 @@ func (r *RouterVMs)DeleteVMAccessForUser(c echo.Context) error {
         return echo.NewHTTPError(http.StatusBadRequest, err.Error())
     }
 
-    // Retrieves the VM to modify.
-    vm, err := r.vms.GetVM(vmID)
-    if err != nil {
-        return echo.NewHTTPError(http.StatusNotFound, err.Error())
-    }
-
-    // Does not check that the user to remove the VM access for actually exists.
-    // Indeed, it might have been deleted.
+    // Purposedly does not check that the user to remove the VM access for actually
+    // exists as it might have been deleted.
     email := c.Param("email")
 
-    // First, check that the logged user is the VM's owner.
-    if !vm.IsOwner(user.Email) {
-        // Next, checks the logged user has the VM_SET_ACCESS capability.
-        if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-            return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-        }
-    }
-
-    if err = r.vms.DeleteVMAccess(vmID, user.Email, email); err != nil {
+    if err = r.vms.DeleteVMAccess(vmID, user, email); err != nil {
         return echo.NewHTTPError(http.StatusBadRequest, err.Error())
     }
 
@@ -414,7 +399,7 @@ func (r *RouterVMs)DeleteVMAccessForUser(c echo.Context) error {
 // VM access cap: VM_READFS: any of the VMs with this cap for the logged user can have their filesystem read.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/exportdir -H 'Content-Type: application/json' -d '{"dir":"absolute_path_to_dir"}' -H "Authorization: Bearer <AccessToken>" --output dir.tar
 func (r *RouterVMs)ExportVMDir(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(c echo.Context, vm *vms.VM) error {
         // Deserializes and validates the client's parameter.
         p := new(params.VMExportDir)
         if err := decodeJson(c, &p); err != nil {
@@ -446,7 +431,7 @@ func (r *RouterVMs)ExportVMDir(c echo.Context) error {
 // VM access cap: VM_WRITEFS: any of the VMs with this cap for the logged user can import the file tree.
 // curl --cacert ca.pem -X POST https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/importfiles -H 'Content-Type: multipart/form-data' -F dir="/home/nexus" -F file=@files.tar -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
-    return r.performVMAction(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(c echo.Context, vm *vms.VM) error {
+    return r.applyOnFilteredVMs(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(c echo.Context, vm *vms.VM) error {
         // Retrieves the various client arguments.
         vmDir := c.FormValue("vmDir")
 
@@ -490,48 +475,47 @@ func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
     })
 }
 
-// Helper function that returns a list of serialized VMs that match either:
+// Helper function that returns a list of serialized VMs if either condition is true:
 // - the logged user has the userCapabilityAny capability.
 // - the logged user is the VM's owner.
 // - the VM access for the logged user matches the vmAccessCapability capability.
-// Also, VMs for which cond is false are filtered out.
-func (r *RouterVMs)performVMsList(c echo.Context, userCapabilityAny, vmAccessCapability string, cond vms.VMKeeperFn) error {
+// Additionally, VMs for which the cond function returns false are filtered out.
+func (r *RouterVMs)getFilteredVMs(c echo.Context, userCapabilityAny, vmAccessCapability string, cond vms.VMKeeperFn) error {
     // Retrieves logged user from context.
     user, err := getLoggedUser(r.users, c)
     if err != nil {
         return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
     }
 
-    // If the logged user has the XX_ANY capability (userCapabilityAny), returns all VMs.
+    // If user has the XX_ANY capability, returns all VMs.
     if user.HasCapability(userCapabilityAny) {
         // Returns all VMs that pass the condition.
         return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(cond), "    ")
     } else {
         // Returns all VMs:
-        // - owned by the logged user
-        // - for which the logged user has the specified capability (vmAccessCapability) in the VM's access
-        return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
-            func(vm *vms.VM) bool {
-                if vm.IsOwner(user.Email) {
-                    return cond(vm)
+        // - owned by the user
+        // - for which the user has the specified capability (vmAccessCapability) in the VM's access
+        return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(func(vm *vms.VM) bool {
+            if vm.IsOwner(user.Email) {
+                return cond(vm)
+            } else {
+                capabilities, exists := vm.GetAccess()[user.Email]
+                if exists {
+                    _, found := capabilities[vmAccessCapability]
+                    return found && cond(vm)
                 } else {
-                    capabilities, exists := vm.GetAccess()[user.Email]
-                    if exists {
-                        _, visible := capabilities[vmAccessCapability]
-                        return visible && cond(vm)
-                    } else {
-                        return false
-                    }
+                    return false
                 }
-              }), "    ")
+            }
+        }), "    ")
     }
 }
 
-// Helper function that performs an action on a VM based either on:
+// Helper function that executes an action on a VM if either condition is true:
 // - the logged user is the VM's owner (in this case, user has all VM access capabilities).
 // - the logged user has the userCapabilityAny capability.
 // - the VM access for the logged user matches the vmAccessCapability capability.
-func (r *RouterVMs)performVMAction(c echo.Context, userCapabilityAny, vmAccessCapability string, action vmActionFn) error {
+func (r *RouterVMs)applyOnFilteredVMs(c echo.Context, userCapabilityAny, vmAccessCapability string, action vmActionFn) error {
     // Retrieves the VM on which to perform the action.
     id, err := uuid.Parse(c.Param("id"))
     if err != nil {
@@ -548,24 +532,23 @@ func (r *RouterVMs)performVMAction(c echo.Context, userCapabilityAny, vmAccessCa
         return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
     }
 
-    // First, checks if the user is the VM's owner
+    // If user is the VM's owner, executes the action.
     if vm.IsOwner(user.Email) {
         return action(c, vm)
+    // If user has the XX_ANY capability, executes the action.
     } else if user.HasCapability(userCapabilityAny) {
-        // Next, checks if the user has the XX_ANY capability
         return action(c, vm)
+    // Finally, if VM access for the logged user matches the required capability, executes the action.
     } else {
-        // Finally, check if the VM access for the logged user matches the required capability
         userCaps, exists := vm.GetAccess()[user.Email]
         if !exists {
             return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
         }
-
         _, hasAccess := userCaps[vmAccessCapability]
         if !hasAccess {
             return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
         }
-
         return action(c, vm)
     }
 }
+
diff --git a/src/server/version/version.go b/src/server/version/version.go
index c8835ed0c38f478d2f365745e15c79fdfca06eda..befa71c8753c57cbf22cdac701b130c2f0d0b56f 100644
--- a/src/server/version/version.go
+++ b/src/server/version/version.go
@@ -7,7 +7,7 @@ import (
 const (
     major  = 1
     minor  = 8
-    bugfix = 2
+    bugfix = 3
 )
 
 type Version struct {
diff --git a/src/server/vms/vms.go b/src/server/vms/vms.go
index 9b80bdc5cad7434d710d08c9751a3f4535b56074..cd5ef711b89d925b3c14c408bd4b3239caf8e1eb 100644
--- a/src/server/vms/vms.go
+++ b/src/server/vms/vms.go
@@ -12,6 +12,7 @@ import (
     "nexus-server/exec"
     "nexus-server/paths"
     "nexus-server/utils"
+    "nexus-server/users"
     "nexus-server/logger"
     c "nexus-server/consts"
     "github.com/google/uuid"
@@ -404,9 +405,9 @@ func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic vm.NicType
 }
 
 // Set a VM's Access for a given user (email).
-// loggedUserEmail is the email of the currently logged user
-// userMail is the email of the user for which to modify the access
-func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, newAccess caps.Capabilities) error {
+// user is the currently logged user
+// destUserEmail is the email of the user for which to modify the access
+func (vms *VMs)SetVMAccess(vmID uuid.UUID, user *users.User, destUserEmail string, newAccess caps.Capabilities) error {
     if err := caps.ValidateVMAccessCaps(newAccess); err != nil {
         return err
     }
@@ -427,17 +428,20 @@ func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, ne
         return errors.New("VM must be stopped")
     }
 
-    // First, check that the logged user is the VM's owner.
-    if !vm.IsOwner(loggedUserEmail) {
-        // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
-        userCaps := vm.v.Access[loggedUserEmail]
-        _, exists := userCaps[caps.CAP_VM_SET_ACCESS]
-        if !exists {
-            return errors.New("Insufficient capability")
+    // If user has VM_SET_ACCESS_ANY, modify is allowed.
+    if !user.HasCapability(caps.CAP_VM_SET_ACCESS_ANY) {
+        // If user is the VM's owner, modify is allowed.
+        if !vm.IsOwner(user.Email) {
+            // If user has VM_SET_ACCESS and VM's VM access is present for the same user, modify is allowed.
+            userCaps := vm.v.Access[user.Email]
+            _, exists := userCaps[caps.CAP_VM_SET_ACCESS]
+            if !exists {
+                return errors.New("Insufficient capability")
+            }
         }
     }
 
-    vm.v.Access[userEmail] = newAccess
+    vm.v.Access[destUserEmail] = newAccess
 
     if err = vm.writeConfig(); err != nil {
         return err
@@ -447,9 +451,9 @@ func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, ne
 }
 
 // Remove a VM's Access for a given user (email).
-// loggedUserEmail is the email of the currently logged user
-// userMail is the email of the user for which to remove the access
-func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string) error {
+// user is the currently logged user
+// destUserEmail is the email of the user for which to modify the access
+func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, user *users.User, destUserEmail string) error {
     vms.rwlock.Lock()
     defer vms.rwlock.Unlock()
 
@@ -466,21 +470,24 @@ func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string)
         return errors.New("VM must be stopped")
     }
 
-    // First, check that the logged user is the VM's owner.
-    if !vm.IsOwner(loggedUserEmail) {
-        // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
-        userCaps := vm.v.Access[loggedUserEmail]
-        _, exists := userCaps[caps.CAP_VM_SET_ACCESS]
-        if !exists {
-            return errors.New("Insufficient capability")
+    // If user has VM_SET_ACCESS_ANY, modify is allowed.
+    if !user.HasCapability(caps.CAP_VM_SET_ACCESS_ANY) {
+        // If user is the VM's owner, modify is allowed.
+        if !vm.IsOwner(user.Email) {
+            // If user has VM_SET_ACCESS and VM's VM access is present for the same user, modify is allowed.
+            userCaps := vm.v.Access[user.Email]
+            _, exists := userCaps[caps.CAP_VM_SET_ACCESS]
+            if !exists {
+                return errors.New("Insufficient capability")
+            }
         }
     }
 
     // Only removes the user from the Access map if it actually had an access.
-    if _, exists := vm.v.Access[userEmail]; exists {
-        delete(vm.v.Access, userEmail)
+    if _, exists := vm.v.Access[destUserEmail]; exists {
+        delete(vm.v.Access, destUserEmail)
     } else {
-        return errors.New("User "+userEmail+" has no VM access")
+        return errors.New("User "+destUserEmail+" has no VM access")
     }
 
     if err = vm.writeConfig(); err != nil {