diff --git a/src/main/java/it/inaf/oats/vospace/CreateNodeController.java b/src/main/java/it/inaf/oats/vospace/CreateNodeController.java
index b3250614ff98a092b6ec8a2ea6b63e27c92d5c6c..3110cecc1b1150ac889800c102574dad9ac1301a 100644
--- a/src/main/java/it/inaf/oats/vospace/CreateNodeController.java
+++ b/src/main/java/it/inaf/oats/vospace/CreateNodeController.java
@@ -1,6 +1,7 @@
 package it.inaf.oats.vospace;
 
 import it.inaf.ia2.aa.data.User;
+import it.inaf.oats.vospace.datamodel.NodeProperties;
 import it.inaf.oats.vospace.datamodel.NodeUtils;
 import net.ivoa.xml.vospace.v2.Node;
 import org.springframework.http.MediaType;
@@ -13,6 +14,8 @@ import org.springframework.web.bind.annotation.PutMapping;
 import it.inaf.oats.vospace.exception.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import net.ivoa.xml.vospace.v2.Property;
+import java.util.List;
 
 @RestController
 public class CreateNodeController extends BaseNodeController {
@@ -67,6 +70,25 @@ public class CreateNodeController extends BaseNodeController {
         if(!NodeUtils.checkIfWritable(parentNode, principal.getName(), principal.getGroups())) {
             throw new PermissionDeniedException(path);
         }
+        
+        // Check if node creator property is set. If not set it according to 
+        // token. In case of creator mistmatch between node and token throw
+        // exception
+        
+        String creator = NodeProperties.getNodePropertyByURI(
+                node, NodeProperties.CREATOR_URI);
+        
+        if(creator == null)
+        {
+            Property creatorProperty = new Property();
+            creatorProperty.setUri(NodeProperties.CREATOR_URI);
+            creatorProperty.setValue(principal.getName());
+            node.getProperties().add(creatorProperty);
+        } else {
+            if(!creator.equals(principal.getName()))
+                // maybe a more specific exception would be more appropriate?
+                throw new PermissionDeniedException(path);
+        }       
 
         nodeDao.createNode(node);
 
diff --git a/src/main/java/it/inaf/oats/vospace/ListNodeController.java b/src/main/java/it/inaf/oats/vospace/ListNodeController.java
index 4ac5fc58da6b04966162f337894361797793db9b..7dd303f42c02a101c3334d6bf8604c8798434326 100644
--- a/src/main/java/it/inaf/oats/vospace/ListNodeController.java
+++ b/src/main/java/it/inaf/oats/vospace/ListNodeController.java
@@ -13,21 +13,36 @@ import javax.servlet.http.HttpServletRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.MediaType;
+import it.inaf.ia2.aa.data.User;
+import it.inaf.oats.vospace.datamodel.NodeUtils;
+import java.util.Optional;
+import it.inaf.oats.vospace.exception.PermissionDeniedException;
 
 @RestController
 public class ListNodeController extends BaseNodeController {
 
     private static final Logger LOG = LoggerFactory.getLogger(ListNodeController.class);
-    
+
     @Autowired
     private NodeDAO nodeDAO;
 
     @GetMapping(value = {"/nodes", "/nodes/**"},
             produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE})
-    public ResponseEntity<Node> listNode(HttpServletRequest request) {
+    public ResponseEntity<Node> listNode(HttpServletRequest request, User principal) {
         String path = getPath();
         LOG.debug("listNode called for path {}", path);
-        return ResponseEntity.ok(nodeDAO.listNode(path)
-                .orElseThrow(() -> new NodeNotFoundException(path)));
+
+        Optional<Node> optNode = nodeDAO.listNode(path);
+
+        if (optNode.isEmpty()) {
+            throw new NodeNotFoundException(path);
+        } else {
+            if (!NodeUtils.checkIfReadable(
+                    optNode.get(), principal.getName(), principal.getGroups())) {
+                throw new PermissionDeniedException(path);
+            }
+        }
+
+        return ResponseEntity.ok(optNode.get());
     }
 }
diff --git a/src/test/java/it/inaf/oats/vospace/CreateNodeControllerTest.java b/src/test/java/it/inaf/oats/vospace/CreateNodeControllerTest.java
index 27058b09be18a34e4ee6fd68f38cfc8fb4567e73..baeef5d3ab6eea039951c222448ff44e8e9f4c7f 100644
--- a/src/test/java/it/inaf/oats/vospace/CreateNodeControllerTest.java
+++ b/src/test/java/it/inaf/oats/vospace/CreateNodeControllerTest.java
@@ -5,6 +5,7 @@ import java.io.InputStream;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
 import net.ivoa.xml.vospace.v2.Property;
+import it.inaf.oats.vospace.datamodel.NodeProperties;
 import net.ivoa.xml.vospace.v2.UnstructuredDataNode;
 import org.junit.jupiter.api.Test;
 import static org.mockito.ArgumentMatchers.argThat;
@@ -271,6 +272,57 @@ public class CreateNodeControllerTest {
         verifyArguments();
         verify(nodeDao, times(1)).createNode(any());
     }
+    
+    @Test
+    public void testWriteOwnerAbsent() throws Exception {
+         String requestBody = 
+                 getResourceFileContent("create-unstructured-data-node.xml");
+         
+         when(nodeDao.listNode(eq("/")))
+                .thenReturn(Optional.of(getContainerParentNodeWithCreator("/")));
+         
+         // no node creator specified in xml file
+         
+         mockMvc.perform(put("/nodes/mydata1")
+                .header("Authorization", "Bearer user2_token")
+                .content(requestBody)
+                .contentType(MediaType.APPLICATION_XML)
+                .accept(MediaType.APPLICATION_XML))
+                .andDo(print())
+                .andExpect(status().is2xxSuccessful());
+         
+        // assert creator properties now matches user2
+         verify(nodeDao, times(1)).createNode(argThat(node->{
+             UnstructuredDataNode udn = (UnstructuredDataNode) node;
+             String creator = NodeProperties.getNodePropertyByURI(
+                udn, NodeProperties.CREATOR_URI);
+             return (creator != null && creator.equals("user2"));         
+         }
+         ));
+        
+    }
+    
+    @Test
+    public void testWriteOwnerMismatch() throws Exception {
+         String requestBody = 
+                 getResourceFileContent("create-unstructured-data-node-user1.xml");
+         
+         when(nodeDao.listNode(eq("/")))
+                .thenReturn(Optional.of(getContainerParentNodeWithCreator("/")));
+         
+         // no node creator specified in xml file
+         
+         mockMvc.perform(put("/nodes/mydata1")
+                .header("Authorization", "Bearer user2_token")
+                .content(requestBody)
+                .contentType(MediaType.APPLICATION_XML)
+                .accept(MediaType.APPLICATION_XML))
+                .andDo(print())
+                .andExpect(status().is4xxClientError());
+         
+        // assert createNode is not called
+         verify(nodeDao, times(0)).createNode(any());        
+    }
 
     @Test
     public void testSubPath() throws Exception {
diff --git a/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java b/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java
index 47988ca6b974c7c28c1c72e1ee9180b67c270d62..26c390a0ca9f835a015c9a059631fed5766ac834 100644
--- a/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java
+++ b/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java
@@ -1,11 +1,13 @@
 package it.inaf.oats.vospace;
 
 import static it.inaf.oats.vospace.VOSpaceXmlTestUtil.loadDocument;
+import it.inaf.oats.vospace.datamodel.NodeProperties;
 import it.inaf.oats.vospace.persistence.NodeDAO;
 import java.util.Optional;
 import net.ivoa.xml.vospace.v2.ContainerNode;
 import net.ivoa.xml.vospace.v2.DataNode;
 import net.ivoa.xml.vospace.v2.Node;
+import net.ivoa.xml.vospace.v2.Property;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import org.junit.jupiter.api.Test;
 import static org.mockito.ArgumentMatchers.eq;
@@ -16,7 +18,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.web.servlet.MockMvc;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@@ -25,6 +30,8 @@ import org.w3c.dom.Document;
 
 @SpringBootTest
 @AutoConfigureMockMvc
+@ContextConfiguration(classes = {TokenFilterConfig.class})
+@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
 public class ListNodeControllerTest {
 
     private static final String URI_PREFIX = "vos://example.com!vospace";
@@ -77,10 +84,39 @@ public class ListNodeControllerTest {
                 .accept(MediaType.APPLICATION_XML))
                 .andExpect(status().isNotFound());
     }
+    
+    @Test
+    public void testPermissionDeniedUser() throws Exception {
+        Node node = getDataNodeByOwnership("user2","group1");
+        
+        when(dao.listNode(eq("/mynode"))).thenReturn(Optional.of(node));
+        
+        mockMvc.perform(get("/nodes/mynode")
+                .header("Authorization", "Bearer user1_token")
+                .accept(MediaType.APPLICATION_XML))
+                .andExpect(status().is4xxClientError());       
+    }
+    
+    @Test
+    public void testGrantedByGroup() throws Exception {
+        Node node = getDataNodeByOwnership("user1","group1");
+        
+        when(dao.listNode(eq("/mynode"))).thenReturn(Optional.of(node));
+        
+        mockMvc.perform(get("/nodes/mynode")
+                .header("Authorization", "Bearer user2_token")
+                .accept(MediaType.APPLICATION_XML))
+                .andExpect(status().is2xxSuccessful());       
+    }
 
     private Optional<Node> getRootNode() {
         ContainerNode root = new ContainerNode();
         root.setUri(URI_PREFIX + "/");
+        Property publicProperty = new Property();
+        publicProperty.setUri(NodeProperties.PUBLIC_READ_URI);
+        publicProperty.setValue("true");
+        root.getProperties().add(publicProperty);       
+        
         root.getNodes().add(getDataNode());
         return Optional.of(root);
     }
@@ -88,6 +124,29 @@ public class ListNodeControllerTest {
     private Node getDataNode() {
         DataNode node = new DataNode();
         node.setUri(URI_PREFIX + "/mynode");
+        Property publicProperty = new Property();
+        publicProperty.setUri(NodeProperties.PUBLIC_READ_URI);
+        publicProperty.setValue("true");
+        node.getProperties().add(publicProperty);
+
         return node;
     }
+    
+    private Node getDataNodeByOwnership(String ownerID, String group)
+    {
+        DataNode node = new DataNode();
+        node.setUri(URI_PREFIX + "/mynode");
+        // Set owner
+        Property creatorProperty = new Property();
+        creatorProperty.setUri(NodeProperties.CREATOR_URI);
+        creatorProperty.setValue(ownerID);
+        node.getProperties().add(creatorProperty);
+        // set group  
+        Property readGroupProperty = new Property();
+        readGroupProperty.setUri(NodeProperties.GROUP_READ_URI);
+        readGroupProperty.setValue(group);
+        node.getProperties().add(readGroupProperty);
+        
+        return node;       
+    }
 }
diff --git a/src/test/resources/create-unstructured-data-node-user1.xml b/src/test/resources/create-unstructured-data-node-user1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..82d50ca847b3d3d16d47beba0412c57e18959521
--- /dev/null
+++ b/src/test/resources/create-unstructured-data-node-user1.xml
@@ -0,0 +1,11 @@
+<vos:node xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xsi:type="vos:UnstructuredDataNode" uri="vos://example.com!vospace/mydata1">
+    <vos:properties>
+        <vos:property uri="ivo://ivoa.net/vospace/core#description">test value</vos:property>        
+        <vos:property uri="ivo://ivoa.net/vospace/core#creator">user1</vos:property>
+    </vos:properties>
+    <vos:accepts/>
+    <vos:provides/>
+    <vos:capabilities/>
+</vos:node>
\ No newline at end of file
diff --git a/src/test/resources/create-unstructured-data-node.xml b/src/test/resources/create-unstructured-data-node.xml
index 1c8e8e6fe08c12300d9ddcc6daa3b6cbedba65da..11f10fcfa9f85d3fece0d30f7e457238e11062c4 100644
--- a/src/test/resources/create-unstructured-data-node.xml
+++ b/src/test/resources/create-unstructured-data-node.xml
@@ -2,7 +2,7 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xsi:type="vos:UnstructuredDataNode" uri="vos://example.com!vospace/mydata1">
     <vos:properties>
-        <vos:property uri="ivo://ivoa.net/vospace/core#description">test value</vos:property>
+        <vos:property uri="ivo://ivoa.net/vospace/core#description">test value</vos:property>        
     </vos:properties>
     <vos:accepts/>
     <vos:provides/>