diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/UpdateSampleProjectExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/UpdateSampleProjectExecutor.java
index abf213c0bac031bcd2b455e56252c38f59bb397a..1f307682b7874b807858c85042488cc605287643 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/UpdateSampleProjectExecutor.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/sample/UpdateSampleProjectExecutor.java
@@ -98,7 +98,7 @@ public class UpdateSampleProjectExecutor extends AbstractUpdateEntityToOneRelati
             relationshipService.unassignSampleFromProject(context.getSession(), entity);
         } else
         {
-            relationshipService.assignSampleToProject(context.getSession(), entity, related);
+            relationshipService.reassignSampleToProject(context.getSession(), entity, related);
         }
     }
 
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/IRelationshipService.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/IRelationshipService.java
index 36dcaf5c7ad941c14a70c0cc35639d38a6bb2de7..f4cb21cbdeeaa58bf1744f5760c97508f78ea575 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/IRelationshipService.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/IRelationshipService.java
@@ -54,12 +54,19 @@ public interface IRelationshipService
             @AuthorizationGuard(guardClass = ProjectPEPredicate.class) ProjectPE project);
 
     @Transactional(propagation = Propagation.MANDATORY)
-    @RolesAllowed(value = { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.PROJECT_POWER_USER })
+    @RolesAllowed(value = { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.PROJECT_USER })
     @Capability("ASSIGN_SAMPLE_TO_PROJECT")
     public void assignSampleToProject(IAuthSession session,
             @AuthorizationGuard(guardClass = SamplePEPredicate.class) SamplePE sample,
             @AuthorizationGuard(guardClass = ProjectPEPredicate.class) ProjectPE project);
 
+    @Transactional(propagation = Propagation.MANDATORY)
+    @RolesAllowed(value = { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.PROJECT_POWER_USER })
+    @Capability("REASSIGN_SAMPLE_TO_PROJECT")
+    public void reassignSampleToProject(IAuthSession session,
+            @AuthorizationGuard(guardClass = SamplePEPredicate.class) SamplePE sample,
+            @AuthorizationGuard(guardClass = ProjectPEPredicate.class) ProjectPE project);
+
     @Transactional(propagation = Propagation.MANDATORY)
     @RolesAllowed(value = { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER })
     @Capability("ASSIGN_PROJECT_TO_SPACE")
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java
index 22b2a62b7c6169af77943bcd09a4a0c7bfe6df70..84a5effaa9ed175d209fa8e478a4df36d643d90d 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java
@@ -97,6 +97,11 @@ public class RelationshipService implements IRelationshipService, ApplicationCon
 
     @Override
     public void assignSampleToProject(IAuthSession session, SamplePE sample, ProjectPE project)
+    {
+        reassignSampleToProject(session, sample, project);
+    }
+
+    @Override public void reassignSampleToProject(final IAuthSession session, final SamplePE sample, final ProjectPE project)
     {
         if (SamplePE.projectSamplesEnabled)
         {
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
index 55bd2616071c259179279b63c139588f00a7a6d5..78eb2d9ede901e00d4f7d4f9034ad724db6bda78 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
@@ -879,7 +879,7 @@ abstract class AbstractBusinessObject implements IDAOFactory
     {
         if (project != null)
         {
-            relationshipService.assignSampleToProject(session, sample, project);
+            relationshipService.reassignSampleToProject(session, sample, project);
         } else
         {
             relationshipService.unassignSampleFromProject(session, sample);
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
index 651b1fefda58fd9b9f60261d23e6ec8445076c83..68497c088b8b155918dd64c8990205bb81dcf882 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
@@ -53,6 +53,7 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.create.AttachmentCreation;
@@ -79,7 +80,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISemanticAnnot
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISpaceHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ITagsHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IValidationPluginHolder;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.update.ListUpdateValue;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetKind;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
@@ -114,8 +114,13 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.pat.id.IPersonalAccessTokenId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.pat.id.PersonalAccessTokenPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.pat.update.PersonalAccessTokenUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.create.PersonCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.PersonPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.create.ProjectCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.IProjectId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.DataType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.PropertyAssignment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.PropertyType;
@@ -125,13 +130,17 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.delete.PropertyTypeDele
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.IPropertyTypeId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.PropertyTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.Query;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.RoleAssignmentCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleTypeCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.delete.SampleTypeDeletionOptions;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.update.SampleTypeUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.SemanticAnnotation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
@@ -154,6 +163,7 @@ import ch.systemsx.cisd.common.logging.BufferedAppender;
 import ch.systemsx.cisd.common.test.AssertionUtil;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE.EntityType;
@@ -181,6 +191,8 @@ public class AbstractTest extends SystemTestCase
         }
     };
 
+    protected static final String USER_ROLES_PROVIDER = "provideUserRoles";
+
     protected BufferedAppender logRecorder;
 
     @Autowired
@@ -1328,10 +1340,15 @@ public class AbstractTest extends SystemTestCase
 
     protected Object[][] createTestUsersProvider(String... users)
     {
-        Object[][] objects = new Object[users.length][];
-        for (int i = 0; i < users.length; i++)
+        return createProvider(users);
+    }
+
+    protected <T> Object[][] createProvider(T... values)
+    {
+        Object[][] objects = new Object[values.length][];
+        for (int i = 0; i < values.length; i++)
         {
-            objects[i] = new Object[] { users[i] };
+            objects[i] = new Object[] { values[i] };
         }
         return objects;
     }
@@ -1814,4 +1831,110 @@ public class AbstractTest extends SystemTestCase
         return map.get(tokenId);
     }
 
+    @DataProvider
+    protected Object[][] provideUserRoles()
+    {
+        return createProvider(RoleWithHierarchy.INSTANCE_ADMIN, RoleWithHierarchy.INSTANCE_OBSERVER, RoleWithHierarchy.SPACE_ADMIN,
+                RoleWithHierarchy.SPACE_POWER_USER, RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.PROJECT_ADMIN,
+                RoleWithHierarchy.PROJECT_POWER_USER, RoleWithHierarchy.PROJECT_USER, RoleWithHierarchy.PROJECT_OBSERVER);
+    }
+
+    protected void testWithUserRole(RoleWithHierarchy role, TestWithUserRole action)
+    {
+        final String adminSessionToken = v3api.login(TEST_USER, PASSWORD);
+
+        // userId needs to end with "_pa_on" for the user's project roles to be taken into consideration (see project authorization settings in service.properties)
+
+        final PersonCreation personCreation = new PersonCreation();
+        personCreation.setUserId("test_user_with_role_" + role + "_pa_on");
+        final PersonPermId personId = v3api.createPersons(adminSessionToken, List.of(personCreation)).get(0);
+
+        final SpaceCreation space1Creation = new SpaceCreation();
+        space1Creation.setCode("TEST_SPACE_1_" + UUID.randomUUID());
+
+        final SpaceCreation space2Creation = new SpaceCreation();
+        space2Creation.setCode("TEST_SPACE_2_" + UUID.randomUUID());
+
+        List<SpacePermId> spaceIds = v3api.createSpaces(adminSessionToken, List.of(space1Creation, space2Creation));
+        SpacePermId space1Id = spaceIds.get(0);
+        SpacePermId space2Id = spaceIds.get(1);
+
+        final ProjectCreation space1Project1Creation = new ProjectCreation();
+        space1Project1Creation.setCode("TEST_SPACE_1_PROJECT_1_" + UUID.randomUUID());
+        space1Project1Creation.setSpaceId(new SpacePermId(space1Creation.getCode()));
+
+        final ProjectCreation space1Project2Creation = new ProjectCreation();
+        space1Project2Creation.setCode("TEST_SPACE_1_PROJECT_2_" + UUID.randomUUID());
+        space1Project2Creation.setSpaceId(new SpacePermId(space1Creation.getCode()));
+
+        List<ProjectPermId> projectIds = v3api.createProjects(adminSessionToken, List.of(space1Project1Creation, space1Project2Creation));
+        ProjectPermId space1Project1Id = projectIds.get(0);
+        ProjectPermId space1Project2Id = projectIds.get(1);
+
+        if (role.isInstanceLevel())
+        {
+            final RoleAssignmentCreation roleCreation = new RoleAssignmentCreation();
+            roleCreation.setUserId(new PersonPermId(personCreation.getUserId()));
+            roleCreation.setRole(Role.valueOf(role.getRoleCode().name()));
+
+            v3api.createRoleAssignments(adminSessionToken, List.of(roleCreation));
+        } else if (role.isSpaceLevel() || role.isProjectLevel())
+        {
+            final RoleAssignmentCreation roleCreation = new RoleAssignmentCreation();
+            roleCreation.setUserId(new PersonPermId(personCreation.getUserId()));
+            roleCreation.setRole(Role.valueOf(role.getRoleCode().name()));
+
+            final RoleAssignmentCreation roleCreation2 = new RoleAssignmentCreation();
+            roleCreation2.setUserId(new PersonPermId(personCreation.getUserId()));
+            roleCreation2.setRole(Role.valueOf(role.getRoleCode().name()));
+
+            if (role.isSpaceLevel())
+            {
+                roleCreation.setSpaceId(space1Id);
+                roleCreation2.setSpaceId(space2Id);
+            } else if (role.isProjectLevel())
+            {
+                roleCreation.setProjectId(space1Project1Id);
+                roleCreation2.setProjectId(space1Project2Id);
+            }
+
+            v3api.createRoleAssignments(adminSessionToken, List.of(roleCreation, roleCreation2));
+        }
+
+        final String userSessionToken = v3api.login(personCreation.getUserId(), PASSWORD);
+
+        final TestWithUserRoleParams params = new TestWithUserRoleParams();
+        params.adminSessionToken = adminSessionToken;
+        params.userSessionToken = userSessionToken;
+        params.userId = personId.getPermId();
+        params.space1Id = space1Id;
+        params.space2Id = space2Id;
+        params.space1Project1Id = space1Project1Id;
+        params.space1Project2Id = space1Project2Id;
+
+        action.execute(params);
+    }
+
+    protected static class TestWithUserRoleParams
+    {
+        public String adminSessionToken;
+
+        public String userSessionToken;
+
+        public String userId;
+
+        public ISpaceId space1Id;
+
+        public ISpaceId space2Id;
+
+        public IProjectId space1Project1Id;
+
+        public IProjectId space1Project2Id;
+    }
+
+    protected static interface TestWithUserRole
+    {
+        void execute(TestWithUserRoleParams params);
+    }
+
 }
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateDataSetTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateDataSetTest.java
index fb968fdfce9341b57d6154d3745f1f34f4bb25f0..cf22ff7d4902156ec27c7ec18bd63e52d4ca2ece 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateDataSetTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateDataSetTest.java
@@ -75,6 +75,7 @@ import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.test.AssertionUtil;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewETPTAssignment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.systemtest.authorization.ProjectAuthorizationUser;
 
 /**
@@ -2269,6 +2270,162 @@ public class CreateDataSetTest extends AbstractDataSetTest
         assertEquals(dataSet.getMetaData(), Map.of("key", "value"));
     }
 
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesExperimentDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+            final ExperimentPermId experimentId = v3api.createExperiments(params.adminSessionToken, List.of(experimentCreation)).get(0);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(experimentId);
+            dataSetCreation.setSampleId(null);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesInstanceSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_INSTANCE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sampleId);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (RoleWithHierarchy.INSTANCE_ADMIN.equals(role))
+            {
+                // shared samples cannot have data sets
+                assertUserFailureException(() -> v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation)),
+                        "shared sample");
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesSpaceSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_SPACE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sampleId);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleLevel.INSTANCE, RoleWithHierarchy.RoleLevel.SPACE).contains(role.getRoleLevel()) && List.of(
+                            RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesProjectSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_PROJECT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setProjectId(params.space1Project1Id);
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sampleId);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesExperimentSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+            final ExperimentPermId experimentId = v3api.createExperiments(params.adminSessionToken, List.of(experimentCreation)).get(0);
+
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_EXPERIMENT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setExperimentId(experimentId);
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sampleId);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetCreation)));
+            }
+        });
+    }
+
     private DataSetCreation containerDataSetCreation()
     {
         String code = UUID.randomUUID().toString();
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateExperimentTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateExperimentTest.java
index f4441dbd80690239743e8ec753bfdfeb8fee5f17..67c1c6ad6570d4765145cbaef1ed91a00980eeea 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateExperimentTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateExperimentTest.java
@@ -27,6 +27,7 @@ import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import org.testng.annotations.Test;
 
@@ -46,12 +47,14 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.DataType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.PropertyTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
 import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewETPTAssignment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.systemtest.authorization.ProjectAuthorizationUser;
 import junit.framework.Assert;
 
@@ -1004,8 +1007,31 @@ public class CreateExperimentTest extends AbstractExperimentTest
         fetchOptions.withSampleProperties();
         Experiment experiment2 = v3api.getExperiments(sessionToken, experimentIds, fetchOptions).get(experimentIds.get(0));
         assertEquals(experiment2.getProperties().get(PLATE_GEOMETRY.getPermId()), "384_WELLS_16X24");
-        assertEquals(experiment2.getTimestampArrayProperty(propertyType.getPermId()), new ZonedDateTime[]{time1, time2});
+        assertEquals(experiment2.getTimestampArrayProperty(propertyType.getPermId()), new ZonedDateTime[] { time1, time2 });
         assertEquals(experiment2.getProperties().size(), 2);
     }
 
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRoles(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createExperiments(params.userSessionToken, Collections.singletonList(experimentCreation));
+            } else
+            {
+                assertAnyAuthorizationException(
+                        () -> v3api.createExperiments(params.userSessionToken, Collections.singletonList(experimentCreation)));
+            }
+        });
+    }
+
 }
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateSampleTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateSampleTest.java
index 14986088455748c537d5b0fb4c52465ff01217dc..ca2c7b5302dc19ff0a52eed187a3ac68db8d69aa 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateSampleTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateSampleTest.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -36,6 +37,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.CreationId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.IEntityTypeId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentIdentifier;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
@@ -56,6 +58,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.batch.Batch;
 import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.test.AssertionUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.systemtest.authorization.ProjectAuthorizationUser;
 import junit.framework.Assert;
@@ -2019,6 +2022,130 @@ public class CreateSampleTest extends AbstractSampleTest
         }
     }
 
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesInstanceSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_INSTANCE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+
+            if (RoleWithHierarchy.INSTANCE_ADMIN.equals(role))
+            {
+                v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesSpaceSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_SPACE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+
+            if (List.of(RoleWithHierarchy.RoleLevel.INSTANCE, RoleWithHierarchy.RoleLevel.SPACE).contains(role.getRoleLevel()) && List.of(
+                            RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesProjectSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_PROJECT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setProjectId(params.space1Project1Id);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesExperimentSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+            final ExperimentPermId experimentId = v3api.createExperiments(params.adminSessionToken, List.of(experimentCreation)).get(0);
+
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_EXPERIMENT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setExperimentId(experimentId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createSamples(params.userSessionToken, Collections.singletonList(sampleCreation)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testCreateWithDifferentRolesParentChildSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation parentCreation = new SampleCreation();
+            parentCreation.setCreationId(new CreationId(UUID.randomUUID().toString()));
+            parentCreation.setCode("TEST_PARENT_SAMPLE_" + UUID.randomUUID());
+            parentCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            parentCreation.setSpaceId(params.space1Id);
+
+            final SampleCreation childCreation = new SampleCreation();
+            childCreation.setCreationId(new CreationId(UUID.randomUUID().toString()));
+            childCreation.setCode("TEST_CHILD_" + UUID.randomUUID());
+            childCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            childCreation.setSpaceId(params.space1Id);
+
+            parentCreation.setChildIds(List.of(childCreation.getCreationId()));
+            childCreation.setParentIds(List.of(parentCreation.getCreationId()));
+
+            if (List.of(RoleWithHierarchy.RoleLevel.INSTANCE, RoleWithHierarchy.RoleLevel.SPACE).contains(role.getRoleLevel()) && List.of(
+                            RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER, RoleWithHierarchy.RoleCode.USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.createSamples(params.userSessionToken, List.of(parentCreation, childCreation));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.createSamples(params.userSessionToken, Collections.singletonList(parentCreation)));
+            }
+        });
+    }
+
     @Test
     public void testLogging()
     {
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateDataSetTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateDataSetTest.java
index 87ce4f06f8c6d5746c3c0f361aeb5b1a4d775949..2d70380580d262e0f8f6e183c6f61bec46a62780 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateDataSetTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateDataSetTest.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -43,6 +44,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.PhysicalDataUpdat
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.datastore.id.DataStorePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentIdentifier;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
@@ -51,6 +53,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.PersonPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.PropertyTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.RoleAssignmentCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SamplePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
@@ -59,6 +62,7 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.FreezingFlags;
 import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.test.AssertionUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE.EntityType;
 import ch.systemsx.cisd.openbis.systemtest.authorization.ProjectAuthorizationUser;
 
@@ -1344,6 +1348,201 @@ public class UpdateDataSetTest extends AbstractDataSetTest
         assertEquals(dataSet.getMetaData(), Map.of("key_modify", "new_value", "key_add", "value_add"));
     }
 
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesExperimentDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+
+            final ExperimentCreation experimentCreation2 = new ExperimentCreation();
+            experimentCreation2.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation2.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation2.setProjectId(params.space1Project2Id);
+            experimentCreation2.setProperty("DESCRIPTION", "test description");
+
+            final List<ExperimentPermId> experimentIds =
+                    v3api.createExperiments(params.adminSessionToken, List.of(experimentCreation, experimentCreation2));
+            ExperimentPermId experiment1Id = experimentIds.get(0);
+            ExperimentPermId experiment2Id = experimentIds.get(1);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(experiment1Id);
+            dataSetCreation.setSampleId(null);
+
+            final DataSetPermId dataSetId = v3api.createDataSets(params.adminSessionToken, Collections.singletonList(dataSetCreation)).get(0);
+
+            final DataSetUpdate dataSetUpdate = new DataSetUpdate();
+            dataSetUpdate.setDataSetId(dataSetId);
+            dataSetUpdate.setExperimentId(experiment2Id);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesSpaceSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_SPACE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+
+            final SampleCreation sampleCreation2 = new SampleCreation();
+            sampleCreation2.setCode("TEST_SPACE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation2.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation2.setSpaceId(params.space2Id);
+
+            final List<SamplePermId> sampleIds = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation, sampleCreation2));
+            SamplePermId sample1Id = sampleIds.get(0);
+            SamplePermId sample2Id = sampleIds.get(1);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sample1Id);
+
+            final DataSetPermId dataSetId = v3api.createDataSets(params.adminSessionToken, Collections.singletonList(dataSetCreation)).get(0);
+
+            final DataSetUpdate dataSetUpdate = new DataSetUpdate();
+            dataSetUpdate.setDataSetId(dataSetId);
+            dataSetUpdate.setSampleId(sample2Id);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleLevel.INSTANCE, RoleWithHierarchy.RoleLevel.SPACE).contains(role.getRoleLevel()) && List.of(
+                            RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesProjectSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_PROJECT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setProjectId(params.space1Project1Id);
+
+            final SampleCreation sampleCreation2 = new SampleCreation();
+            sampleCreation2.setCode("TEST_PROJECT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation2.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation2.setSpaceId(params.space1Id);
+            sampleCreation2.setProjectId(params.space1Project2Id);
+
+            final List<SamplePermId> sampleIds = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation, sampleCreation2));
+            SamplePermId sample1Id = sampleIds.get(0);
+            SamplePermId sample2Id = sampleIds.get(1);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sample1Id);
+
+            final DataSetPermId dataSetId = v3api.createDataSets(params.adminSessionToken, Collections.singletonList(dataSetCreation)).get(0);
+
+            final DataSetUpdate dataSetUpdate = new DataSetUpdate();
+            dataSetUpdate.setDataSetId(dataSetId);
+            dataSetUpdate.setSampleId(sample2Id);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER).contains(role.getRoleCode()))
+            {
+                v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesExperimentSampleDataSet(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+
+            final ExperimentCreation experimentCreation2 = new ExperimentCreation();
+            experimentCreation2.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation2.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation2.setProjectId(params.space1Project2Id);
+            experimentCreation2.setProperty("DESCRIPTION", "test description");
+
+            final List<ExperimentPermId> experimentIds =
+                    v3api.createExperiments(params.adminSessionToken, List.of(experimentCreation, experimentCreation2));
+            ExperimentPermId experiment1Id = experimentIds.get(0);
+            ExperimentPermId experiment2Id = experimentIds.get(1);
+
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_EXPERIMENT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setExperimentId(experiment1Id);
+
+            final SampleCreation sampleCreation2 = new SampleCreation();
+            sampleCreation2.setCode("TEST_EXPERIMENT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation2.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation2.setSpaceId(params.space1Id);
+            sampleCreation2.setExperimentId(experiment2Id);
+
+            final List<SamplePermId> sampleIds = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation, sampleCreation2));
+            SamplePermId sample1Id = sampleIds.get(0);
+            SamplePermId sample2Id = sampleIds.get(1);
+
+            final DataSetCreation dataSetCreation = physicalDataSetCreation();
+            dataSetCreation.setExperimentId(null);
+            dataSetCreation.setSampleId(sample1Id);
+
+            final DataSetPermId dataSetId = v3api.createDataSets(params.adminSessionToken, Collections.singletonList(dataSetCreation)).get(0);
+
+            final DataSetUpdate dataSetUpdate = new DataSetUpdate();
+            dataSetUpdate.setDataSetId(dataSetId);
+            dataSetUpdate.setSampleId(sample2Id);
+
+            // use instance admin to login on behalf of the user
+            final String onBehalfOfSessionToken = v3api.loginAs(TEST_USER, PASSWORD, params.userId);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER).contains(role.getRoleCode()))
+            {
+                v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateDataSets(onBehalfOfSessionToken, Collections.singletonList(dataSetUpdate)));
+            }
+        });
+    }
+
     private Collection<String> dataSetCodes(Collection<? extends DataSet> list)
     {
         LinkedList<String> result = new LinkedList<String>();
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateExperimentTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateExperimentTest.java
index 6fb9e07619c8e86c1813a7329142eec9c8fc47a6..6a820cc676701caa7d0fc3df924e2af60984499c 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateExperimentTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateExperimentTest.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -65,6 +66,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.FreezingFlags;
 import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.test.AssertionUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE.EntityType;
 import ch.systemsx.cisd.openbis.systemtest.authorization.ProjectAuthorizationUser;
 
@@ -1315,6 +1317,36 @@ public class UpdateExperimentTest extends AbstractExperimentTest
                 Map.of("key_modify", "new_value", "key_add", "value_add"));
     }
 
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRoles(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+
+            final ExperimentPermId experimentId =
+                    v3api.createExperiments(params.adminSessionToken, Collections.singletonList(experimentCreation)).get(0);
+
+            final ExperimentUpdate experimentUpdate = new ExperimentUpdate();
+            experimentUpdate.setExperimentId(experimentId);
+            experimentUpdate.setProjectId(params.space1Project2Id);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.updateExperiments(params.userSessionToken, Collections.singletonList(experimentUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(
+                        () -> v3api.updateExperiments(params.userSessionToken, Collections.singletonList(experimentUpdate)));
+            }
+        });
+    }
+
     @Test
     private ExperimentPermId createExperimentWithoutAttachments()
     {
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java
index 047c68f7c51e059b525593e9a352e1c2dde10efa..f5b1797792af476bae52a9ff4c024cbb0bb2cee1 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java
@@ -26,6 +26,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -43,6 +44,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.datastore.id.DataStorePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentIdentifier;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
@@ -73,6 +75,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagCode;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.FreezingFlags;
 import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.test.AssertionUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE.EntityType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.systemtest.authorization.ProjectAuthorizationUser;
@@ -2600,4 +2603,170 @@ public class UpdateSampleTest extends AbstractSampleTest
         }
     }
 
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesInstanceSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_INSTANCE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final SampleUpdate sampleUpdate = new SampleUpdate();
+            sampleUpdate.setSampleId(sampleId);
+            sampleUpdate.setProperty("COMMENT", "test comment");
+
+            if (RoleWithHierarchy.INSTANCE_ADMIN.equals(role))
+            {
+                v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate));
+            } else
+            {
+                assertUnauthorizedObjectAccessException(() -> v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate)),
+                        null);
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesSpaceSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_SPACE_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final SampleUpdate sampleUpdate = new SampleUpdate();
+            sampleUpdate.setSampleId(sampleId);
+            sampleUpdate.setSpaceId(params.space2Id);
+
+            if (List.of(RoleWithHierarchy.RoleLevel.INSTANCE, RoleWithHierarchy.RoleLevel.SPACE).contains(role.getRoleLevel()) && List.of(
+                    RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER).contains(role.getRoleCode()))
+            {
+                v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesProjectSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_PROJECT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setProjectId(params.space1Project1Id);
+
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final SampleUpdate sampleUpdate = new SampleUpdate();
+            sampleUpdate.setSampleId(sampleId);
+            sampleUpdate.setProjectId(params.space1Project2Id);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER).contains(role.getRoleCode()))
+            {
+                v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesExperimentSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final ExperimentCreation experimentCreation = new ExperimentCreation();
+            experimentCreation.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation.setProjectId(params.space1Project1Id);
+            experimentCreation.setProperty("DESCRIPTION", "test description");
+
+            final ExperimentCreation experimentCreation2 = new ExperimentCreation();
+            experimentCreation2.setTypeId(new EntityTypePermId("SIRNA_HCS"));
+            experimentCreation2.setCode("TEST_EXPERIMENT_" + UUID.randomUUID());
+            experimentCreation2.setProjectId(params.space1Project2Id);
+            experimentCreation2.setProperty("DESCRIPTION", "test description");
+
+            final List<ExperimentPermId> experimentIds =
+                    v3api.createExperiments(params.adminSessionToken, List.of(experimentCreation, experimentCreation2));
+            ExperimentPermId experiment1Id = experimentIds.get(0);
+            ExperimentPermId experiment2Id = experimentIds.get(1);
+
+            final SampleCreation sampleCreation = new SampleCreation();
+            sampleCreation.setCode("TEST_EXPERIMENT_SAMPLE_" + UUID.randomUUID());
+            sampleCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            sampleCreation.setSpaceId(params.space1Id);
+            sampleCreation.setExperimentId(experiment1Id);
+
+            final SamplePermId sampleId = v3api.createSamples(params.adminSessionToken, List.of(sampleCreation)).get(0);
+
+            final SampleUpdate sampleUpdate = new SampleUpdate();
+            sampleUpdate.setSampleId(sampleId);
+            sampleUpdate.setExperimentId(experiment2Id);
+
+            if (List.of(RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER).contains(role.getRoleCode()))
+            {
+                v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateSamples(params.userSessionToken, Collections.singletonList(sampleUpdate)));
+            }
+        });
+    }
+
+    @Test(dataProvider = USER_ROLES_PROVIDER)
+    public void testUpdateWithDifferentRolesParentChildSample(RoleWithHierarchy role)
+    {
+        testWithUserRole(role, params ->
+        {
+            final SampleCreation parentCreation = new SampleCreation();
+            parentCreation.setCreationId(new CreationId(UUID.randomUUID().toString()));
+            parentCreation.setCode("TEST_PARENT_SAMPLE_" + UUID.randomUUID());
+            parentCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            parentCreation.setSpaceId(params.space1Id);
+
+            final SampleCreation childCreation = new SampleCreation();
+            childCreation.setCreationId(new CreationId(UUID.randomUUID().toString()));
+            childCreation.setCode("TEST_CHILD_" + UUID.randomUUID());
+            childCreation.setTypeId(new EntityTypePermId("CELL_PLATE"));
+            childCreation.setSpaceId(params.space1Id);
+
+            parentCreation.setChildIds(List.of(childCreation.getCreationId()));
+            childCreation.setParentIds(List.of(parentCreation.getCreationId()));
+
+            List<SamplePermId> sampleIds = v3api.createSamples(params.adminSessionToken, List.of(parentCreation, childCreation));
+            SamplePermId parentId = sampleIds.get(0);
+            SamplePermId childId = sampleIds.get(1);
+
+            SampleUpdate parentUpdate = new SampleUpdate();
+            parentUpdate.setSampleId(parentId);
+            parentUpdate.getChildIds().remove(childId);
+
+            SampleUpdate childUpdate = new SampleUpdate();
+            childUpdate.setSampleId(childId);
+            childUpdate.getParentIds().remove(parentId);
+
+            if (List.of(RoleWithHierarchy.RoleLevel.INSTANCE, RoleWithHierarchy.RoleLevel.SPACE).contains(role.getRoleLevel()) && List.of(
+                            RoleWithHierarchy.RoleCode.ADMIN, RoleWithHierarchy.RoleCode.POWER_USER)
+                    .contains(role.getRoleCode()))
+            {
+                v3api.updateSamples(params.userSessionToken, List.of(parentUpdate, childUpdate));
+            } else
+            {
+                assertAnyAuthorizationException(() -> v3api.updateSamples(params.userSessionToken, List.of(parentUpdate, childUpdate)));
+            }
+        });
+    }
+
 }
diff --git a/server-application-server/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java b/server-application-server/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java
index 5404f0ebd5d0468ba5708ed49cacde5fa34f9008..75cf5ae068ddaee04934c7feda4aa67844a64672 100644
--- a/server-application-server/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java
+++ b/server-application-server/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java
@@ -140,6 +140,12 @@ public class RelationshipServiceStub implements IRelationshipService
 
     }
 
+    @Override
+    public void reassignSampleToProject(final IAuthSession session, final SamplePE sample, final ProjectPE project)
+    {
+
+    }
+
     @Override
     public void unassignSampleFromProject(IAuthSession session, SamplePE sample)
     {