diff --git a/src/router/routerTemplates.go b/src/router/routerTemplates.go
index 5a38d6f655a2d1fe159a9b4f0e9fdc2bec3fd14c..33c7d4c9f80e31eaaf9f5fc4679edc128dbed83a 100644
--- a/src/router/routerTemplates.go
+++ b/src/router/routerTemplates.go
@@ -83,16 +83,20 @@ func (r *RouterTemplates)CreateTemplateFromVM(c echo.Context) error {
 		return echo.NewHTTPError(http.StatusNotFound, err.Error())
 	}
 
-	// Check the user has the required capabilities: either VM_LIST_ANY or VM_LIST in the VM access
-	if !user.HasCapability(caps.CAP_VM_LIST_ANY) {
-		userCaps, exists := vm.Access[user.Email]
-		if !exists {
-			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-		}
+	// If the user isn't the VM's owner, checks that the required capabilities are met:
+	// either VM_LIST_ANY or VM_LIST in the VM access
+	if !vm.IsOwner(user.Email) {
+		// Check the user has the required capabilities: either VM_LIST_ANY or VM_LIST in the VM access
+		if !user.HasCapability(caps.CAP_VM_LIST_ANY) {
+			userCaps, exists := vm.Access[user.Email]
+			if !exists {
+				return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+			}
 
-		_, hasAccess := userCaps[caps.CAP_VM_LIST]
-		if !hasAccess {
-			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+			_, hasAccess := userCaps[caps.CAP_VM_LIST]
+			if !hasAccess {
+				return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+			}
 		}
 	}
 
diff --git a/src/router/routerVMs.go b/src/router/routerVMs.go
index bd94f5cd8d03274ddcef34aca2b700b4fc3152d2..09d7cc9aee76960e399cf85552871d1bdde9b8f5 100644
--- a/src/router/routerVMs.go
+++ b/src/router/routerVMs.go
@@ -29,7 +29,7 @@ func NewRouterVMs() *RouterVMs {
 }
 
 // Returns VMs that can be listed.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_LIST_ANY: returns all VMs.
 // 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>"
@@ -40,7 +40,7 @@ func (r *RouterVMs)GetListableVMs(c echo.Context) error {
 }
 
 // Returns VMs that are running and that can be attached to.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_LIST_ANY: returns all running VMs.
 // 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>"
@@ -51,7 +51,7 @@ func (r *RouterVMs)GetAttachableVMs(c echo.Context) error {
 }
 
 // Returns VMs that are stopped and that can be deleted.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_DESTROY_ANY: returns all VMs.
 // 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>"
@@ -62,7 +62,7 @@ func (r *RouterVMs)GetDeletableVMs(c echo.Context) error {
 }
 
 // Returns VMs that are stopped and that can be started.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_START_ANY: returns all VMs.
 // 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>"
@@ -73,7 +73,7 @@ func (r *RouterVMs)GetStartableVMs(c echo.Context) error {
 }
 
 // Returns VMs that are running and that can be stopped.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_STOP_ANY: returns all VMs.
 // 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>"
@@ -84,7 +84,7 @@ func (r *RouterVMs)GetStoppableVMs(c echo.Context) error {
 }
 
 // Returns VMs that are running and that can be rebooted.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_REBOOT_ANY: returns all VMs.
 // 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>"
@@ -95,7 +95,7 @@ func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
 }
 
 // Returns VMs that can be edited.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_EDIT_ANY: returns all VMs.
 // 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>"
@@ -106,7 +106,7 @@ func (r *RouterVMs)GetEditableVMs(c echo.Context) error {
 }
 
 // Returns VMs that can have their access set or deleted.
-// Requires BOTH capabilities:
+// Requires to be the VM's owner, or 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>"
@@ -117,25 +117,31 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
 		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
 	}
 
-	if user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-		// Returns all VMs for which VM access for the logged user matches CAP_VM_SET_ACCESS.
-		return c.JSONPretty(http.StatusOK, r.vms.GetVMs(
-			func(vm vms.VM) bool {
-				capabilities, exists := vm.Access[user.Email]
-				if exists {
-					_, visible := capabilities[caps.CAP_VM_SET_ACCESS]
-					return visible
+	return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
+		func(vm vms.VM) bool {
+			// First, checks if the user is the VM's owner
+			if vm.IsOwner(user.Email) {
+				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.HasCapability(caps.CAP_VM_SET_ACCESS) {
+					capabilities, exists := vm.Access[user.Email]
+					if exists {
+						_, visible := capabilities[caps.CAP_VM_SET_ACCESS]
+						return visible
+					} else {
+						return false
+					}
 				} else {
 					return false
 				}
-			  }), "    ")
-	} else {
-		return c.JSONPretty(http.StatusOK, []vms.VM{}, "    ")
-	}
+			}
+		  }), "    ")
 }
 
 // Returns VMs that can have a directory exported.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: VM_READFS_ANY: returns all VMs.
 // 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>"
@@ -146,7 +152,7 @@ func (r *RouterVMs)GetDirExportableVMs(c echo.Context) error {
 }
 
 // Returns VMs that can have files imported (i.e. copied) into their filesystem.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: VM_WRITEFS_ANY: returns all VMs.
 // 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>"
@@ -185,8 +191,7 @@ func (r *RouterVMs)CreateVM(c echo.Context) error {
 	}
 
 	// Creates a new VM from the client's parameters.
-	// The user creating the VM automatically gets all the VM access capabilities (see caps.VMAccessCaps for the list).
-	vm, err := vms.NewVM(user.Email, caps.VMAccessCaps, p.Name, p.Cpus, p.Ram, p.Nic, p.TemplateID)
+	vm, err := vms.NewVM(user.Email, p.Name, p.Cpus, p.Ram, p.Nic, p.TemplateID, user.Email)
 	if err != nil {
 		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
 	}
@@ -195,11 +200,11 @@ func (r *RouterVMs)CreateVM(c echo.Context) error {
 		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
 	}
 
-	return c.JSONPretty(http.StatusCreated, vm, "    ")
+	return c.JSONPretty(http.StatusCreated, vm.SerializeToNetwork(), "    ")
 }
 
 // Deletes a VM based on its ID.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // 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>"
@@ -213,7 +218,7 @@ func (r *RouterVMs)DeleteVMByID(c echo.Context) error {
 }
 
 // Starts a VM based on its ID.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_START_ANY: any VM can be started.
 // 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>"
@@ -228,7 +233,7 @@ func (r *RouterVMs)StartVM(c echo.Context) error {
 }
 
 // Kills a VM based on its ID.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_STOP_ANY: any VM can be killed.
 // 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>"
@@ -242,7 +247,7 @@ func (r *RouterVMs)KillVM(c echo.Context) error {
 }
 
 // Gracefully shutdown a VM based on its ID.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_STOP_ANY: any VM can be shutdown.
 // 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>"
@@ -256,7 +261,7 @@ func (r *RouterVMs)ShutdownVM(c echo.Context) error {
 }
 
 // Reboot a VM based on its ID.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: CAP_VM_REBOOT_ANY: any VM can be rebooted.
 // 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>"
@@ -270,7 +275,7 @@ func (r *RouterVMs)RebootVM(c echo.Context) error {
 }
 
 // Edit a VM' specs: name, cpus, ram, nic
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // 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"}' -H "Authorization: Bearer <AccessToken>"
@@ -297,7 +302,7 @@ func (r *RouterVMs)EditVMByID(c echo.Context) error {
 }
 
 // Set a VM access for a given user.
-// Requires BOTH capabilities:
+// Requires to be the VM's owner, or 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>"
@@ -307,11 +312,8 @@ func (r *RouterVMs)SetVMAccessForUser(c echo.Context) error {
 	if err != nil {
 		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
 	}
-	if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
 
-	// Checks the user for which to modify the VM Access actually exists.
+	// Checks the user for which to set the VM Access actually exists.
 	email := c.Param("email")
 	_, err = r.users.GetUserByEmail(email)
 	if err != nil {
@@ -324,6 +326,20 @@ 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 the client's parameters.
 	type Parameters struct {
 		Access caps.Capabilities `json:"access"  validate:"required"`
@@ -344,7 +360,7 @@ func (r *RouterVMs)SetVMAccessForUser(c echo.Context) error {
 }
 
 // Delete a VM Access for a given user.
-// Requires BOTH capabilities:
+// Requires to be the VM's owner, or BOTH capabilities:
 // User cap: CAP_VM_SET_ACCESS
 // VM access cap: CAP_VM_SET_ACCESS
 // curl --cacert ca.pem -X DELETE https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/caps/janedoes@nexus.org -H 'Content-Type: application/json' -H "Authorization: Bearer <AccessToken>"
@@ -354,18 +370,29 @@ func (r *RouterVMs)DeleteVMAccessForUser(c echo.Context) error {
 	if err != nil {
 		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
 	}
-	if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+
+	// Retrieves the vmID of the VM to modify.
+	vmID, err := uuid.Parse(c.Param("id"))
+	if err != nil {
+		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.
 	email := c.Param("email")
 
-	// Retrieves the vmID of the VM to modify.
-	vmID, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, 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)
+		}
 	}
 
 	if err = r.vms.DeleteVMAccess(vmID, user.Email, email); err != nil {
@@ -376,7 +403,7 @@ func (r *RouterVMs)DeleteVMAccessForUser(c echo.Context) error {
 }
 
 // Exports a VM's directory into a compressed archive.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: VM_READFS_ANY: any VM can have their filesystem read.
 // 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
@@ -411,7 +438,7 @@ func (r *RouterVMs)ExportVMDir(c echo.Context) error {
 }
 
 // Import files into a VM's filesystem, in a specified directory. The file tree is received in a tar.gz archive.
-// Requires either capability:
+// Requires to be the VM's owner, or either capability:
 // User cap: VM_WRITEFS_ANY: any VM can import the file tree.
 // 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>"
@@ -460,8 +487,9 @@ func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
 	})
 }
 
-// Helper function that returns a list of VMs that match either:
+// Helper function that returns a list of serialized VMs that match either:
 // - 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 {
@@ -474,23 +502,30 @@ func (r *RouterVMs)performVMsList(c echo.Context, userCapabilityAny, vmAccessCap
 	// If the logged user has the XX_ANY capability (userCapabilityAny), returns all VMs.
 	if user.HasCapability(userCapabilityAny) {
 		// Returns all VMs that pass the condition.
-		return c.JSONPretty(http.StatusOK, r.vms.GetVMs(cond), "    ")
+		return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(cond), "    ")
 	} else {
-		// Returns all VMs for which VM access for the logged user matches the specified the VM Access capability (vmAccessCapability).
-		return c.JSONPretty(http.StatusOK, r.vms.GetVMs(
+		// 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 {
-				capabilities, exists := vm.Access[user.Email]
-				if exists {
-					_, visible := capabilities[vmAccessCapability]
-					return visible && cond(vm)
+				if vm.IsOwner(user.Email) {
+					return true
 				} else {
-					return false
+					capabilities, exists := vm.Access[user.Email]
+					if exists {
+						_, visible := capabilities[vmAccessCapability]
+						return visible && cond(vm)
+					} else {
+						return false
+					}
 				}
 			  }), "    ")
 	}
 }
 
 // Helper function that performs an action on a VM based either on:
+// - 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 {
@@ -510,11 +545,14 @@ func (r *RouterVMs)performVMAction(c echo.Context, userCapabilityAny, vmAccessCa
 		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
 	}
 
-	// First, checks if the user has the XX_ANY capability
-	if user.HasCapability(userCapabilityAny) {
+	// First, checks if the user is the VM's owner
+	if vm.IsOwner(user.Email) {
+		return action(c, &vm)
+	} else if user.HasCapability(userCapabilityAny) {
+		// Next, checks if the user has the XX_ANY capability
 		return action(c, &vm)
 	} else {
-		// Check if the VM access for the logged user matches the required capability
+		// Finally, check if the VM access for the logged user matches the required capability
 		userCaps, exists := vm.Access[user.Email]
 		if !exists {
 			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
diff --git a/src/version/version.go b/src/version/version.go
index 50f6dee85d9cc6e98d6a1547e2e4c70732e6fe8a..804b0773863e7d8dc074c99231acaa433a71bffd 100644
--- a/src/version/version.go
+++ b/src/version/version.go
@@ -6,8 +6,8 @@ import (
 
 const (
 	major  = 1
-	minor  = 4
-	bugfix = 2
+	minor  = 5
+	bugfix = 0
 )
 
 type Version struct {
diff --git a/src/vms/template.go b/src/vms/template.go
index e330b7415cc9c3981d4a1a30d7bc58fedb665aeb..52b4584d632551c2975f030abe717d03a42681e7 100644
--- a/src/vms/template.go
+++ b/src/vms/template.go
@@ -13,9 +13,9 @@ import (
 )
 
 type Template struct {
-	ID     uuid.UUID       `json:"id"           validate:"required"`
-	Name   string          `json:"name"         validate:"required,min=2,max=256"`
-	Owner  string          `json:"owner"        validate:"required,email"`
+	ID uuid.UUID           `json:"id"           validate:"required"`
+	Name string            `json:"name"         validate:"required,min=2,max=256"`
+	Owner string           `json:"owner"        validate:"required,email"`
 	Access string          `json:"access"       validate:"required,min=4,max=16"` // private or public
 	CreationTime time.Time `json:"creationTime" validate:"required"`
 }
diff --git a/src/vms/vm.go b/src/vms/vm.go
index bd693d2b85dd7d07136a4a0f390f1417846870f8..0e555e0e52bec772cce331e62a94c6ced9888e57 100644
--- a/src/vms/vm.go
+++ b/src/vms/vm.go
@@ -21,8 +21,10 @@ import (
 )
 
 type (
+	// Internal VM structure.
 	VM struct {
 		ID uuid.UUID          `json:"id"         validate:"required"`
+		Owner string          `json:"owner"      validate:"required,email"`
 		Name string           `json:"name"       validate:"required,min=2,max=256"`
 		Cpus int              `json:"cpus"       validate:"required,gte=1,lte=16"`
 		Ram int               `json:"ram"        validate:"required,gte=512,lte=32768"`
@@ -48,6 +50,34 @@ type (
 	VMState string
 	NicType string
 
+	// VM fields to be serialized to disk.
+	VMDiskSerialized struct {
+		ID uuid.UUID           `json:"id"`
+		Owner string           `json:"owner"`
+		Name string            `json:"name"`
+		Cpus int               `json:"cpus"`
+		Ram int                `json:"ram"`
+		Nic NicType            `json:"nic"`
+		TemplateID uuid.UUID   `json:"templateID"`
+		Access map[string]caps.Capabilities `json:"access"`
+	}
+
+	// VM fields to be serialized over the network (sent to the client).
+	VMNetworkSerialized struct {
+		ID uuid.UUID
+		Owner string
+		Name string
+		Cpus int
+		Ram int
+		Nic NicType
+		TemplateID uuid.UUID
+		Access map[string]caps.Capabilities
+		State VMState
+		Port int
+		Pwd string
+		DiskBusy bool          // If true the VM's disk is busy (cannot be modified or deleted)
+	}
+
 	endOfExecCallback func(vm *VM)
 )
 
@@ -74,14 +104,16 @@ var passwordGen, _ = password.NewGenerator(&password.GeneratorInput{
 })
 
 // Creates a VM.
-func NewVM(creatorEmail string, caps caps.Capabilities, name string, cpus, ram int, nic NicType, templateID uuid.UUID) (*VM, error) {
+func NewVM(creatorEmail string, name string, cpus, ram int, nic NicType, templateID uuid.UUID, owner string) (*VM, error) {
 	vmID, err := uuid.NewRandom()
+
 	if err != nil {
 		log.Error("Failed creating VM: "+err.Error())
 		return nil, err
 	}
 	vm := newEmptyVM()
 	vm.ID = vmID
+	vm.Owner = owner
 	vm.Name = name
 	vm.Cpus = cpus
 	vm.Ram = ram
@@ -90,7 +122,7 @@ func NewVM(creatorEmail string, caps caps.Capabilities, name string, cpus, ram i
 	id := vmID.String()
 	vm.dir = filepath.Join(vms.dir, id[0:3], id[3:6], id)
 	vm.qgaSock = filepath.Join(vm.dir, vmQGASockFile)
-	vm.Access[creatorEmail] = caps
+	vm.Access = make(map[string]caps.Capabilities)
 
 	if err = vm.validate(); err != nil {
 		return nil, errors.New("Failed validating VM: "+err.Error())
@@ -99,15 +131,51 @@ func NewVM(creatorEmail string, caps caps.Capabilities, name string, cpus, ram i
 	return vm, nil
 }
 
+func (vm *VM)SerializeToDisk() VMDiskSerialized {
+	return VMDiskSerialized {
+		ID: vm.ID,
+		Owner: vm.Owner,
+		Name: vm.Name,
+		Cpus: vm.Cpus,
+		Ram: vm.Ram,
+		Nic: vm.Nic,
+		TemplateID: vm.TemplateID,
+		Access: vm.Access,
+	}
+}
+
+func (vm *VM)SerializeToNetwork() VMNetworkSerialized {
+	return VMNetworkSerialized {
+		ID: vm.ID,
+		Owner: vm.Owner,
+		Name: vm.Name,
+		Cpus: vm.Cpus,
+		Ram: vm.Ram,
+		Nic: vm.Nic,
+		TemplateID: vm.TemplateID,
+		Access: vm.Access,
+		State: vm.Run.State,
+		Port: vm.Run.Port,
+		Pwd: vm.Run.Pwd,
+		DiskBusy: vm.DiskBusy,
+	}
+}
+
 func (vm *VM)getDiskPath() string {
 	vmDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, vmDiskFile))
 	return vmDiskFile
 }
 
+// Returns true if the specified email is the VM's owner.
+func (vm *VM)IsOwner(email string) bool {
+	return email == vm.Owner
+}
+
 // Creates an empty VM.
 func newEmptyVM() *VM {
 	return &VM {
 		ID: uuid.Nil,
+		Owner: "",
 		Name: "",
 		Cpus: 0,
 		Ram: 0,
@@ -229,18 +297,7 @@ func (vm *VM)writeConfig() error {
 	encoder := json.NewEncoder(file)
 	encoder.SetIndent("", "    ")
 
-	// Only serializes the following fields.
-	type VMConf struct {
-		ID uuid.UUID           `json:"id"`
-		Name string            `json:"name"`
-		Cpus int               `json:"cpus"`
-		Ram int                `json:"ram"`
-		Nic NicType            `json:"nic"`
-		TemplateID uuid.UUID   `json:"templateID"`
-		Access map[string]caps.Capabilities `json:"access"`
-	}
-	vmConf := VMConf{ vm.ID, vm.Name, vm.Cpus, vm.Ram, vm.Nic, vm.TemplateID, vm.Access }
-	if err = encoder.Encode(vmConf); err != nil {
+	if err = encoder.Encode(vm.SerializeToDisk()); err != nil {
 		log.Error("Failed encoding VM config file: "+err.Error())
 		return errors.New("Failed encoding VM config file: "+err.Error())
 	}
diff --git a/src/vms/vms.go b/src/vms/vms.go
index 7a1dc0124604552d7b3de8472bf291c2cf25e1fa..03a001611e03afa9a38fba360c423acb894cba0f 100644
--- a/src/vms/vms.go
+++ b/src/vms/vms.go
@@ -86,13 +86,13 @@ func InitVMs() error {
 	return nil
 }
 
-// Returns the list of VMs for which VMKeeperFn returns true.
-func (vms *VMs)GetVMs(keepFn VMKeeperFn) []VM {
+// Returns the list of serialized VMs for which VMKeeperFn returns true.
+func (vms *VMs)GetNetworkSerializedVMs(keepFn VMKeeperFn) []VMNetworkSerialized {
 	vms.rwlock.RLock()
-	list := []VM{}
+	list := []VMNetworkSerialized{}
 	for _, vm := range vms.m {
 		if keepFn(vm) {
-			list = append(list, vm)
+			list = append(list, vm.SerializeToNetwork())
 		}
 	}
 	vms.rwlock.RUnlock()
@@ -340,11 +340,14 @@ func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, ne
 	vm.mutex.Lock()
 	defer vm.mutex.Unlock()
 
-	// Checks the logged user has VM_SET_ACCESS set in her/his VM access.
-	userCaps := vm.Access[loggedUserEmail]
-	_, exists := userCaps[caps.CAP_VM_SET_ACCESS]
-	if !exists {
-		return errors.New("Insufficient capability")
+	// 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.Access[loggedUserEmail]
+		_, exists := userCaps[caps.CAP_VM_SET_ACCESS]
+		if !exists {
+			return errors.New("Insufficient capability")
+		}
 	}
 
 	vm.Access[userEmail] = newAccess
@@ -372,11 +375,14 @@ func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string)
 	vm.mutex.Lock()
 	defer vm.mutex.Unlock()
 
-	// Checks the user has VM_SET_ACCESS set in her/his VM access.
-	userCaps := vm.Access[loggedUserEmail]
-	_, exists := userCaps[caps.CAP_VM_SET_ACCESS]
-	if !exists {
-		return errors.New("Insufficient capability")
+	// 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.Access[loggedUserEmail]
+		_, 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.