diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index 944baa1c5b5939825801798cacd7df10004f2df8..edf69412cfdff493ff89647a00738a5a726ba8d6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -88,6 +88,27 @@ import ch.systemsx.cisd.openbis.generic.shared.IServer;
 import ch.systemsx.cisd.openbis.generic.shared.LogMessagePrefixGenerator;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchableEntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AtomicOperationsPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodeCollectionPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodePredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetUpdatesPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ExistingSampleOwnerIdentifierPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ExistingSpaceIdentifierPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ListSampleCriteriaPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ListSamplesByPropertyPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExperimentPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplePredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplesWithTypePredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleOwnerIdentifierPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleTechIdPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleUpdatesPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SpaceIdentifierPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ProjectValidator;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.SampleValidator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.EntityOperationsState;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria;
@@ -121,6 +142,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyTypeWithVocabulary;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
@@ -304,7 +326,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public DatabaseInstance getHomeDatabaseInstance(String sessionToken)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public DatabaseInstance getHomeDatabaseInstance(final String sessionToken)
     {
         return DatabaseInstanceTranslator.translate(getHomeDatabaseInstance());
     }
@@ -315,6 +338,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void registerDataStoreServer(String sessionToken, DataStoreServerInfo info)
     {
         Session session = getSession(sessionToken);
@@ -374,13 +398,15 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public String createPermId(String sessionToken) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public String createPermId(final String sessionToken) throws UserFailureException
     {
         checkSession(sessionToken); // throws exception if invalid sessionToken
         return daoFactory.getPermIdDAO().createPermId();
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public long drawANewUniqueID(String sessionToken) throws UserFailureException
     {
         checkSession(sessionToken);
@@ -397,9 +423,12 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Experiment> listExperiments(String sessionToken,
+            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
             List<ExperimentIdentifier> experimentIdentifiers,
-            ExperimentFetchOptions experimentFetchOptions) throws UserFailureException
+            ExperimentFetchOptions experimentFetchOptions)
     {
         if (sessionToken == null)
         {
@@ -438,7 +467,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Experiment> listExperimentsForProjects(String sessionToken,
+            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
             List<ProjectIdentifier> projectIdentifiers,
             ExperimentFetchOptions experimentFetchOptions)
     {
@@ -486,7 +518,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public Experiment tryToGetExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class)
             ExperimentIdentifier experimentIdentifier) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
@@ -504,7 +539,12 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public List<Sample> listSamples(String sessionToken, ListSampleCriteria criteria)
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @ReturnValueFilter(validatorClass = SampleValidator.class)
+    public List<Sample> listSamples(final String sessionToken,
+            @AuthorizationGuard(guardClass = ListSampleCriteriaPredicate.class)
+            final ListSampleCriteria criteria)
     {
         final Session session = getSession(sessionToken);
         final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session);
@@ -512,8 +552,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public Sample tryGetSampleWithExperiment(String sessionToken, SampleIdentifier sampleIdentifier)
-            throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public Sample tryGetSampleWithExperiment(final String sessionToken,
+            @AuthorizationGuard(guardClass = ExistingSampleOwnerIdentifierPredicate.class)
+            final SampleIdentifier sampleIdentifier) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert sampleIdentifier != null : "Unspecified sample identifier.";
@@ -529,6 +571,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public SampleIdentifier tryToGetSampleIdentifier(String sessionToken, String samplePermID)
             throws UserFailureException
     {
@@ -578,6 +621,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public ExperimentType getExperimentType(String sessionToken, String experimentTypeCode)
             throws UserFailureException
     {
@@ -597,6 +641,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public SampleType getSampleType(String sessionToken, String sampleTypeCode)
             throws UserFailureException
     {
@@ -614,6 +659,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public DataSetTypeWithVocabularyTerms getDataSetType(String sessionToken, String dataSetTypeCode)
             throws UserFailureException
     {
@@ -649,8 +695,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public List<ExternalData> listDataSetsByExperimentID(String sessionToken, TechId experimentID)
-            throws UserFailureException
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public List<ExternalData> listDataSetsByExperimentID(final String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
+            final TechId experimentID) throws UserFailureException
     {
         Session session = getSession(sessionToken);
         IDatasetLister datasetLister = createDatasetLister(session);
@@ -660,8 +709,12 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<ExternalData> listDataSetsBySampleID(final String sessionToken,
+            @AuthorizationGuard(guardClass = SampleTechIdPredicate.class)
             final TechId sampleId, final boolean showOnlyDirectlyConnected)
+            throws UserFailureException
     {
         final Session session = getSession(sessionToken);
         final IDatasetLister datasetLister = createDatasetLister(session);
@@ -672,7 +725,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public List<ExternalData> listDataSetsByCode(String sessionToken, List<String> dataSetCodes)
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public List<ExternalData> listDataSetsByCode(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
+            List<String> dataSetCodes) throws UserFailureException
     {
         final Session session = getSession(sessionToken);
         final IDatasetLister datasetLister = createDatasetLister(session);
@@ -680,6 +737,9 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @ReturnValueFilter(validatorClass = ProjectValidator.class)
     public List<Project> listProjects(String sessionToken)
     {
         checkSession(sessionToken);
@@ -689,7 +749,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public List<Experiment> listExperiments(String sessionToken, ProjectIdentifier projectIdentifier)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public List<Experiment> listExperiments(String sessionToken,
+            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
+            ProjectIdentifier projectIdentifier)
     {
         final Session session = getSession(sessionToken);
         final IExperimentTable experimentTable =
@@ -701,8 +765,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public IEntityProperty[] tryToGetPropertiesOfTopSampleRegisteredFor(String sessionToken,
-            SampleIdentifier sampleIdentifier) throws UserFailureException
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public IEntityProperty[] tryToGetPropertiesOfTopSampleRegisteredFor(final String sessionToken,
+            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
+            final SampleIdentifier sampleIdentifier) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert sampleIdentifier != null : "Unspecified sample identifier.";
@@ -727,6 +794,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void registerEntities(String sessionToken, EntityCollectionForCreationOrUpdate collection)
             throws UserFailureException
     {
@@ -750,8 +818,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public long registerExperiment(String sessionToken, NewExperiment experiment)
-            throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public long registerExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = NewExperimentPredicate.class)
+            NewExperiment experiment) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert experiment != null : "Unspecified new example.";
@@ -769,7 +839,9 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void registerSamples(String sessionToken,
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void registerSamples(final String sessionToken,
+            @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class)
             final List<NewSamplesWithTypes> newSamplesWithType, String userIDOrNull)
             throws UserFailureException
     {
@@ -784,8 +856,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public long registerSample(String sessionToken, NewSample newSample, String userIDOrNull)
-            throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public long registerSample(final String sessionToken,
+            @AuthorizationGuard(guardClass = NewSamplePredicate.class)
+            final NewSample newSample, String userIDOrNull) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert newSample != null : "Unspecified new sample.";
@@ -807,15 +881,21 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void updateSample(String sessionToken, SampleUpdatesDTO updates)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void updateSample(String sessionToken,
+            @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class)
+            SampleUpdatesDTO updates)
     {
         final Session session = getSession(sessionToken);
         updateSampleInternal(updates, session);
     }
 
     @Override
-    public void registerDataSet(String sessionToken, SampleIdentifier sampleIdentifier,
-            NewExternalData externalData) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void registerDataSet(final String sessionToken,
+            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
+            final SampleIdentifier sampleIdentifier, final NewExternalData externalData)
+            throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert sampleIdentifier != null : "Unspecified sample identifier.";
@@ -825,8 +905,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void registerDataSet(String sessionToken, ExperimentIdentifier experimentIdentifier,
-            NewExternalData externalData) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void registerDataSet(final String sessionToken,
+            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
+            final ExperimentIdentifier experimentIdentifier, final NewExternalData externalData)
+            throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert experimentIdentifier != null : "Unspecified experiment identifier.";
@@ -836,8 +919,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void addPropertiesToDataSet(String sessionToken, List<NewProperty> properties,
-            String dataSetCode, SpaceIdentifier space) throws UserFailureException
+            String dataSetCode, @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
+            final SpaceIdentifier identifier) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         final Session session = getSession(sessionToken);
@@ -846,8 +931,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void updateShareIdAndSize(String sessionToken, String dataSetCode, String shareId,
-            long size)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void updateShareIdAndSize(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
+            String dataSetCode, String shareId, long size) throws UserFailureException
     {
         final Session session = getSession(sessionToken);
 
@@ -872,8 +959,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void updateDataSetStatuses(String sessionToken, List<String> dataSetCodes,
-            DataSetArchivingStatus newStatus, boolean presentInArchive) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void updateDataSetStatuses(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
+            List<String> dataSetCodes, final DataSetArchivingStatus newStatus,
+            boolean presentInArchive) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         final Session session = getSession(sessionToken);
@@ -882,6 +972,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public boolean compareAndSetDataSetStatus(String sessionToken, String dataSetCode,
             DataSetArchivingStatus oldStatus, DataSetArchivingStatus newStatus,
             boolean newPresentInArchive) throws UserFailureException
@@ -894,8 +985,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public ExternalData tryGetDataSet(String sessionToken, String dataSetCode)
-            throws UserFailureException
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public ExternalData tryGetDataSet(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
+            String dataSetCode) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert dataSetCode != null : "Unspecified data set code.";
@@ -915,6 +1009,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN)
     public void checkInstanceAdminAuthorization(String sessionToken) throws UserFailureException
     {
         checkSession(sessionToken);
@@ -922,6 +1017,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER)
     public void checkSpacePowerUserAuthorization(String sessionToken) throws UserFailureException
     {
         checkSession(sessionToken);
@@ -929,31 +1025,41 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void checkDataSetAccess(String sessionToken, String dataSetCode)
-            throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public void checkDataSetAccess(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
+            String dataSetCode) throws UserFailureException
     {
         checkSession(sessionToken);
         // do nothing, the access rights specified in method annotations are checked by a proxy
     }
 
     @Override
-    public void checkDataSetCollectionAccess(String sessionToken, List<String> dataSetCodes)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public void checkDataSetCollectionAccess(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
+            List<String> dataSetCodes)
     {
         checkSession(sessionToken);
         // do nothing, the access rights specified in method annotations are checked by a proxy
     }
 
     @Override
-    public void checkSpaceAccess(String sessionToken, SpaceIdentifier spaceId)
-            throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
+    public void checkSpaceAccess(String sessionToken,
+            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
+            SpaceIdentifier spaceId)
     {
         checkSession(sessionToken);
         // do nothing, the access rights specified in method annotations are checked by a proxy
     }
 
     @Override
-    public List<Sample> listSamplesByCriteria(String sessionToken,
-            ListSamplesByPropertyCriteria criteria) throws UserFailureException
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    public List<Sample> listSamplesByCriteria(final String sessionToken,
+            @AuthorizationGuard(guardClass = ListSamplesByPropertyPredicate.class)
+            final ListSamplesByPropertyCriteria criteria) throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert criteria != null : "Unspecified criteria.";
@@ -965,7 +1071,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public List<DataSetShareId> listShareIds(String sessionToken, String dataStoreCode)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public List<DataSetShareId> listShareIds(final String sessionToken, String dataStoreCode)
             throws UserFailureException
     {
         Session session = getSession(sessionToken);
@@ -975,7 +1082,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public List<SimpleDataSetInformationDTO> listFileDataSets(String sessionToken,
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public List<SimpleDataSetInformationDTO> listFileDataSets(final String sessionToken,
             String dataStoreCode) throws UserFailureException
     {
         List<ExternalData> dataSets = loadDataSets(sessionToken, dataStoreCode);
@@ -983,6 +1091,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> listAvailableDataSets(String sessionToken, String dataStoreCode,
             ArchiverDataSetCriteria criteria)
     {
@@ -992,6 +1101,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> listDataSets(String sessionToken, String dataStoreCode,
             TrackingDataSetCriteria criteria)
     {
@@ -1036,6 +1146,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<DeletedDataSet> listDeletedDataSets(String sessionToken,
             Long lastSeenDeletionEventIdOrNull, Date maxDeletionDataOrNull)
     {
@@ -1045,6 +1156,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Collection<VocabularyTerm> listVocabularyTerms(String sessionToken, String vocabularyCode)
             throws UserFailureException
     {
@@ -1073,6 +1185,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<Person> listAdministrators(String sessionToken)
     {
         checkSession(sessionToken);
@@ -1097,6 +1210,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Person tryPersonWithUserIdOrEmail(String sessionToken, String useridOrEmail)
     {
         checkSession(sessionToken);
@@ -1124,8 +1238,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public Sample registerSampleAndDataSet(String sessionToken, NewSample newSample,
-            NewExternalData externalData, String userIdOrNull) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public Sample registerSampleAndDataSet(final String sessionToken,
+            @AuthorizationGuard(guardClass = NewSamplePredicate.class)
+            final NewSample newSample, final NewExternalData externalData, String userIdOrNull)
+            throws UserFailureException
     {
         assert sessionToken != null : "Unspecified session token.";
         assert newSample != null : "Unspecified new sample.";
@@ -1143,8 +1260,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public Sample updateSampleAndRegisterDataSet(String sessionToken, SampleUpdatesDTO updates,
-            NewExternalData externalData)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public Sample updateSampleAndRegisterDataSet(String sessionToken,
+            @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class)
+            SampleUpdatesDTO updates, NewExternalData externalData)
     {
         final Session session = getSession(sessionToken);
 
@@ -1214,7 +1333,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public Space tryGetSpace(String sessionToken, SpaceIdentifier spaceIdentifier)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_ETL_SERVER })
+    public Space tryGetSpace(String sessionToken,
+            @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class)
+            SpaceIdentifier spaceIdentifier)
     {
 
         Session session = getSession(sessionToken);
@@ -1234,7 +1357,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public Project tryGetProject(String sessionToken, ProjectIdentifier projectIdentifier)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_ETL_SERVER })
+    public Project tryGetProject(String sessionToken,
+            @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class)
+            ProjectIdentifier projectIdentifier)
     {
         final Session session = getSession(sessionToken);
         final IProjectBO bo = businessObjectFactory.createProjectBO(session);
@@ -1251,6 +1378,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Material tryGetMaterial(String sessionToken, MaterialIdentifier materialIdentifier)
     {
         final Session session = getSession(sessionToken);
@@ -1268,7 +1396,9 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public AtomicEntityOperationResult performEntityOperations(String sessionToken,
+            @AuthorizationGuard(guardClass = AtomicOperationsPredicate.class)
             AtomicEntityOperationDetails operationDetails)
     {
         return this.performEntityOperations(sessionToken, operationDetails, new IProgressListener()
@@ -1356,6 +1486,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public EntityOperationsState didEntityOperationsSucceed(String token, TechId registrationId)
     {
         if (registrationId == null)
@@ -1840,6 +1971,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<Sample> searchForSamples(String sessionToken, SearchCriteria searchCriteria)
     {
         Session session = getSession(sessionToken);
@@ -1852,6 +1984,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> searchForDataSets(String sessionToken, SearchCriteria searchCriteria)
     {
         Session session = getSession(sessionToken);
@@ -1864,6 +1997,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Material> listMaterials(String sessionToken, ListMaterialCriteria criteria,
             boolean withProperties)
     {
@@ -1901,8 +2036,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
 
     @Override
     @SuppressWarnings("deprecation")
-    public void removeDataSetsPermanently(String sessionToken, List<String> dataSetCodes,
-            String reason)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void removeDataSetsPermanently(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
+            List<String> dataSetCodes, String reason)
     {
         Session session = getSession(sessionToken);
         IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session);
@@ -1910,7 +2047,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
-    public void updateDataSet(String sessionToken, DataSetUpdatesDTO dataSetUpdates)
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
+    public void updateDataSet(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetUpdatesPredicate.class)
+            DataSetUpdatesDTO dataSetUpdates)
     {
         final Session session = getSession(sessionToken);
         final IDataBO dataSetBO = businessObjectFactory.createDataBO(session);
@@ -1918,12 +2058,14 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> getTrustedCrossOriginDomains(String sessionToken)
     {
         return trustedOriginDomainProvider.getTrustedDomains();
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void setStorageConfirmed(String sessionToken, String dataSetCode)
     {
         assert sessionToken != null : "Unspecified session token.";
@@ -1942,6 +2084,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void markSuccessfulPostRegistration(String sessionToken, String dataSetCode)
     {
         assert sessionToken != null : "Unspecified session token.";
@@ -1959,6 +2102,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> listDataSetsForPostRegistration(String sessionToken,
             String dataStoreCode)
     {
@@ -1992,12 +2136,14 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void heartbeat(String token)
     {
         // do nothing
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public boolean doesUserHaveRole(String token, String user, String roleCode, String spaceOrNull)
     {
         return new AuthorizationServiceUtils(daoFactory).doesUserHaveRole(user, roleCode,
@@ -2005,12 +2151,14 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> filterToVisibleDataSets(String token, String user, List<String> dataSetCodes)
     {
         return new AuthorizationServiceUtils(daoFactory).filterDataSetCodes(user, dataSetCodes);
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> filterToVisibleExperiments(String token, String user,
             List<String> experimentIds)
     {
@@ -2018,12 +2166,14 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> filterToVisibleSamples(String token, String user, List<String> sampleIds)
     {
         return new AuthorizationServiceUtils(daoFactory).filterSampleIds(user, sampleIds);
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public ExternalDataManagementSystem tryGetExternalDataManagementSystem(String token,
             String externalDataManagementSystemCode)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java
index 580a7709871d06f7f172553ae8f0a043659c10e8..5090be09adfd7666dabd0e8d7c3f076167b174a9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java
@@ -26,27 +26,6 @@ import ch.systemsx.cisd.common.conversation.IConversationalRmiServer;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.ISessionProvider;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AtomicOperationsPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodeCollectionPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodePredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ExistingSampleOwnerIdentifierPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ExistingSpaceIdentifierPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ListSampleCriteriaPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ListSamplesByPropertyPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExperimentPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplePredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplesWithTypePredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleOwnerIdentifierPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleTechIdPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SpaceIdentifierPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ProjectValidator;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.SampleValidator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.EntityOperationsState;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria;
@@ -71,7 +50,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSamplesWithTypes;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
@@ -105,14 +83,12 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Returns the home database instance.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public DatabaseInstance getHomeDatabaseInstance(final String sessionToken);
 
     /**
      * Registers a Data Store Server for the specified info.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void registerDataStoreServer(String sessionToken, DataStoreServerInfo dataStoreServerInfo);
 
     /**
@@ -122,17 +98,13 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @param experimentIdentifier an identifier which uniquely identifies the experiment.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public Experiment tryToGetExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class)
             ExperimentIdentifier experimentIdentifier) throws UserFailureException;
 
     /**
      * For given {@link MaterialIdentifier} returns the corresponding {@link Material}.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Material tryGetMaterial(String sessionToken, MaterialIdentifier materialIdentifier);
 
     /**
@@ -141,7 +113,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return <code>null</code> if nothing found.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public SampleIdentifier tryToGetSampleIdentifier(String sessionToken, String samplePermID)
             throws UserFailureException;
 
@@ -150,7 +121,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * type code.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public ExperimentType getExperimentType(String sessionToken, String experimentTypeCode)
             throws UserFailureException;
 
@@ -164,16 +134,13 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *         <var>sampleIdentifier</var>.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Sample tryGetSampleWithExperiment(final String sessionToken,
-            @AuthorizationGuard(guardClass = ExistingSampleOwnerIdentifierPredicate.class)
             final SampleIdentifier sampleIdentifier) throws UserFailureException;
 
     /**
      * Returns a list of terms belonging to given vocabulary.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Collection<VocabularyTerm> listVocabularyTerms(String sessionToken, String vocabulary)
             throws UserFailureException;
 
@@ -181,7 +148,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Returns the SampleType together with assigned property types for specified sample type code.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public SampleType getSampleType(String sessionToken, String sampleTypeCode)
             throws UserFailureException;
 
@@ -190,7 +156,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * code.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public DataSetTypeWithVocabularyTerms getDataSetType(String sessionToken, String dataSetTypeCode)
             throws UserFailureException;
 
@@ -200,10 +165,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return a sorted list of {@link ExternalData}.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<ExternalData> listDataSetsByExperimentID(final String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
             final TechId experimentID) throws UserFailureException;
 
     /**
@@ -212,10 +174,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return a sorted list of {@link ExternalData}.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<ExternalData> listDataSetsBySampleID(final String sessionToken,
-            @AuthorizationGuard(guardClass = SampleTechIdPredicate.class)
             final TechId sampleId, final boolean showOnlyDirectlyConnected)
             throws UserFailureException;
 
@@ -225,11 +184,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return plain data sets without properties, samples, and experiments.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
-    public List<ExternalData> listDataSetsByCode(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
-            List<String> dataSetCodes) throws UserFailureException;
+    public List<ExternalData> listDataSetsByCode(String sessionToken, List<String> dataSetCodes)
+            throws UserFailureException;
 
     /**
      * Lists samples using given configuration.
@@ -237,12 +193,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return a sorted list of {@link Sample}.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
-    @ReturnValueFilter(validatorClass = SampleValidator.class)
-    public List<Sample> listSamples(final String sessionToken,
-            @AuthorizationGuard(guardClass = ListSampleCriteriaPredicate.class)
-            final ListSampleCriteria criteria);
+    public List<Sample> listSamples(final String sessionToken, final ListSampleCriteria criteria);
 
     /**
      * Tries to return the properties of the top sample (e.g. master plate) registered for the
@@ -254,17 +205,13 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *         sample found with no properties.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public IEntityProperty[] tryToGetPropertiesOfTopSampleRegisteredFor(final String sessionToken,
-            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
             final SampleIdentifier sampleIdentifier) throws UserFailureException;
 
     /**
      * Registers/updates various entities in one transaction.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value =
         { ObjectKind.EXPERIMENT, ObjectKind.SAMPLE, ObjectKind.DATA_SET })
     public void registerEntities(String sessionToken, EntityCollectionForCreationOrUpdate collection)
@@ -274,20 +221,16 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Registers experiment.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value = ObjectKind.EXPERIMENT)
-    public long registerExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = NewExperimentPredicate.class)
-            NewExperiment experiment) throws UserFailureException;
+    public long registerExperiment(String sessionToken, NewExperiment experiment)
+            throws UserFailureException;
 
     /**
      * Registers samples in batches.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.SAMPLE)
     public void registerSamples(final String sessionToken,
-            @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class)
             final List<NewSamplesWithTypes> newSamplesWithType, String userIdOrNull)
             throws UserFailureException;
 
@@ -295,21 +238,16 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Registers a new sample.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value = ObjectKind.SAMPLE)
-    public long registerSample(final String sessionToken,
-            @AuthorizationGuard(guardClass = NewSamplePredicate.class)
-            final NewSample newSample, String userIDOrNull) throws UserFailureException;
+    public long registerSample(final String sessionToken, final NewSample newSample,
+            String userIDOrNull) throws UserFailureException;
 
     /**
      * Saves changed sample.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.SAMPLE)
-    public void updateSample(String sessionToken,
-            @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class)
-            SampleUpdatesDTO updates);
+    public void updateSample(String sessionToken, SampleUpdatesDTO updates);
 
     /**
      * Registers the specified data connected to a sample.
@@ -323,12 +261,9 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *             layer.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value = ObjectKind.DATA_SET)
-    public void registerDataSet(final String sessionToken,
-            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
-            final SampleIdentifier sampleIdentifier, final NewExternalData externalData)
-            throws UserFailureException;
+    public void registerDataSet(final String sessionToken, final SampleIdentifier sampleIdentifier,
+            final NewExternalData externalData) throws UserFailureException;
 
     /**
      * Registers the specified data connected to an experiment.
@@ -342,10 +277,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *             layer.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value = ObjectKind.DATA_SET)
     public void registerDataSet(final String sessionToken,
-            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
             final ExperimentIdentifier experimentIdentifier, final NewExternalData externalData)
             throws UserFailureException;
 
@@ -353,14 +286,12 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Checks that the user of specified session has INSTANCE_ADMIN access rights.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN)
     public void checkInstanceAdminAuthorization(String sessionToken) throws UserFailureException;
 
     /**
      * Checks that the user of specified session has SPACE_POWER_USER access rights.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER)
     public void checkSpacePowerUserAuthorization(String sessionToken) throws UserFailureException;
 
     /**
@@ -368,10 +299,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * dataset.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public void checkDataSetAccess(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
-            String dataSetCode) throws UserFailureException;
+    public void checkDataSetAccess(String sessionToken, String dataSetCode)
+            throws UserFailureException;
 
     /**
      * Check if the current user can access all the data sets in the list
@@ -380,34 +309,26 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @param dataSetCodes The data set codes the user wants to access.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public void checkDataSetCollectionAccess(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
-            List<String> dataSetCodes);
+    public void checkDataSetCollectionAccess(String sessionToken, List<String> dataSetCodes);
 
     /**
      * Tries to return the data set specified by its code.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(value =
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
-    public ExternalData tryGetDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
-            String dataSetCode) throws UserFailureException;
+    public ExternalData tryGetDataSet(String sessionToken, String dataSetCode)
+            throws UserFailureException;
 
     /**
      * Create and return a new permanent id that can be used to identify samples, experiments and
      * datasets.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public String createPermId(final String sessionToken) throws UserFailureException;
 
     /**
      * Draw a new unique ID. The returned value is guaranteed to be unique.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public long drawANewUniqueID(String sessionToken) throws UserFailureException;
 
     /**
@@ -415,7 +336,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * unique.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public long drawANewUniqueID(String sessionToken, EntityKind entityKind)
             throws UserFailureException;
 
@@ -424,17 +344,13 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * to see the details.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Sample> listSamplesByCriteria(final String sessionToken,
-            @AuthorizationGuard(guardClass = ListSamplesByPropertyPredicate.class)
             final ListSamplesByPropertyCriteria criteria) throws UserFailureException;
 
     /**
      * Lists share ids of all data sets belonging to chosen data store (even the ones in trash!).
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<DataSetShareId> listShareIds(final String sessionToken, String dataStore)
             throws UserFailureException;
 
@@ -442,7 +358,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Lists file-content data sets belonging to chosen data store.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<SimpleDataSetInformationDTO> listFileDataSets(final String sessionToken,
             String dataStore) throws UserFailureException;
 
@@ -450,7 +365,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * List data sets deleted after specified date.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<DeletedDataSet> listDeletedDataSets(String sessionToken,
             Long lastSeenDeletionEventIdOrNull, Date maxDeletionDataOrNull);
 
@@ -458,7 +372,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * List 'AVAILABLE' data sets (not locked) that match given criteria.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> listAvailableDataSets(String sessionToken, String dataStoreCode,
             ArchiverDataSetCriteria criteria);
 
@@ -466,7 +379,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * List data sets from specified store which are younger then the specified one.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> listDataSets(String sessionToken, String dataStoreCode,
             TrackingDataSetCriteria criteria);
 
@@ -474,20 +386,13 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * List all experiments for a given project identifier.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(value =
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
-    public List<Experiment> listExperiments(String sessionToken,
-            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
-            ProjectIdentifier projectIdentifier);
+    public List<Experiment> listExperiments(String sessionToken, ProjectIdentifier projectIdentifier);
 
     /**
      * List experiments for a given list of experiment identifiers.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Experiment> listExperiments(String sessionToken,
-            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
             List<ExperimentIdentifier> experimentIdentifiers,
             ExperimentFetchOptions experimentFetchOptions);
 
@@ -495,10 +400,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * List experiments for a given list of project identifiers.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Experiment> listExperimentsForProjects(String sessionToken,
-            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
             List<ProjectIdentifier> projectIdentifiers,
             ExperimentFetchOptions experimentFetchOptions);
 
@@ -506,9 +408,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * List all projects that the user can see.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(value =
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
-    @ReturnValueFilter(validatorClass = ProjectValidator.class)
     public List<Project> listProjects(String sessionToken);
 
     /**
@@ -517,8 +416,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return a sorted list of {@link Material}.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(value =
-        { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Material> listMaterials(String sessionToken, ListMaterialCriteria criteria,
             boolean withProperties);
 
@@ -526,32 +423,26 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Adds specified properties of given data set. Properties defined before will not be updated.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
     public void addPropertiesToDataSet(String sessionToken, List<NewProperty> properties,
-            String dataSetCode, @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
-            final SpaceIdentifier identifier) throws UserFailureException;
+            String dataSetCode, final SpaceIdentifier identifier) throws UserFailureException;
 
     /**
      * Updates share id and size of specified data set.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
-    public void updateShareIdAndSize(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
-            String dataSetCode, String shareId, long size) throws UserFailureException;
+    public void updateShareIdAndSize(String sessionToken, String dataSetCode, String shareId,
+            long size) throws UserFailureException;
 
     /**
      * Updates status of given data sets.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
-    public void updateDataSetStatuses(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
-            List<String> dataSetCodes, final DataSetArchivingStatus newStatus,
-            boolean presentInArchive) throws UserFailureException;
+    public void updateDataSetStatuses(String sessionToken, List<String> dataSetCodes,
+            final DataSetArchivingStatus newStatus, boolean presentInArchive)
+            throws UserFailureException;
 
     /**
      * Set the status for a given dataset to the given new status value if the current status equals
@@ -561,7 +452,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *         <code>oldStatus</code>.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
     public boolean compareAndSetDataSetStatus(String token, String dataSetCode,
             DataSetArchivingStatus oldStatus, DataSetArchivingStatus newStatus,
@@ -575,11 +465,9 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return number of data sets scheduled for archiving.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
-    public int archiveDatasets(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
-            List<String> datasetCodes, boolean removeFromDataStore);
+    public int archiveDatasets(String sessionToken, List<String> datasetCodes,
+            boolean removeFromDataStore);
 
     /**
      * Schedules unarchiving of specified data sets.
@@ -587,11 +475,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return number of data sets scheduled for unarchiving.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
-    public int unarchiveDatasets(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
-            List<String> datasetCodes);
+    public int unarchiveDatasets(String sessionToken, List<String> datasetCodes);
 
     /**
      * Check if the user has USER access on the space
@@ -600,16 +485,12 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @param spaceId The id for the space the user wants to access
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
-    public void checkSpaceAccess(String sessionToken,
-            @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class)
-            SpaceIdentifier spaceId);
+    public void checkSpaceAccess(String sessionToken, SpaceIdentifier spaceId);
 
     /**
      * Returns a list of unique codes for the specified entity kind.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> generateCodes(String sessionToken, String prefix, EntityKind entityKind,
             int number);
 
@@ -617,7 +498,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Returns a list users who could be considered administrators.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<Person> listAdministrators(String sessionToken);
 
     /**
@@ -625,7 +505,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * a userId match; if none was found, it searches for an Email match.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public Person tryPersonWithUserIdOrEmail(String sessionToken, String useridOrEmail);
 
     /**
@@ -641,13 +520,10 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *             layer.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value =
         { ObjectKind.SAMPLE, ObjectKind.DATA_SET })
-    public Sample registerSampleAndDataSet(final String sessionToken,
-            @AuthorizationGuard(guardClass = NewSamplePredicate.class)
-            final NewSample newSample, final NewExternalData externalData, String userIdOrNull)
-            throws UserFailureException;
+    public Sample registerSampleAndDataSet(final String sessionToken, final NewSample newSample,
+            final NewExternalData externalData, String userIdOrNull) throws UserFailureException;
 
     /**
      * Updates a sample and registers a data set connected to that sample in one transaction.
@@ -661,12 +537,10 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *             layer.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value = ObjectKind.SAMPLE)
     @DatabaseCreateOrDeleteModification(value = ObjectKind.DATA_SET)
-    public Sample updateSampleAndRegisterDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class)
-            SampleUpdatesDTO updates, NewExternalData externalData);
+    public Sample updateSampleAndRegisterDataSet(String sessionToken, SampleUpdatesDTO updates,
+            NewExternalData externalData);
 
     /**
      * Updates a sample and registers a data set connected to that sample in one transaction.
@@ -677,35 +551,25 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      *             layer.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value =
         { ObjectKind.SAMPLE, ObjectKind.EXPERIMENT, ObjectKind.DATA_SET })
     @DatabaseCreateOrDeleteModification(value =
         { ObjectKind.SPACE, ObjectKind.PROJECT, ObjectKind.SAMPLE, ObjectKind.EXPERIMENT,
                 ObjectKind.DATA_SET })
     public AtomicEntityOperationResult performEntityOperations(String sessionToken,
-            @AuthorizationGuard(guardClass = AtomicOperationsPredicate.class)
             AtomicEntityOperationDetails operationDetails);
 
     /**
      * Tries to return the space specified by its identifier.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(value =
-        { RoleWithHierarchy.SPACE_ETL_SERVER })
-    public Space tryGetSpace(String sessionToken,
-            @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class)
-            SpaceIdentifier spaceIdentifier);
+    public Space tryGetSpace(String sessionToken, SpaceIdentifier spaceIdentifier);
 
     /**
      * Tries to return the project specified by its identifier.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(value =
-        { RoleWithHierarchy.SPACE_ETL_SERVER })
-    public Project tryGetProject(String sessionToken,
-            @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class)
-            ProjectIdentifier projectIdentifier);
+    public Project tryGetProject(String sessionToken, ProjectIdentifier projectIdentifier);
 
     /**
      * Search for samples matching the provided criteria.
@@ -715,7 +579,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return A collection of samples matching the search criteria.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<Sample> searchForSamples(String sessionToken, SearchCriteria searchCriteria);
 
     /**
@@ -726,32 +589,26 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * @return A collection of data sets matching the search criteria.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> searchForDataSets(String sessionToken, SearchCriteria searchCriteria);
 
     /**
      * permanently deletes a list of data sets.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value =
         { ObjectKind.SAMPLE, ObjectKind.EXPERIMENT })
     @DatabaseCreateOrDeleteModification(value =
         { ObjectKind.DATA_SET })
-    public void removeDataSetsPermanently(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
-            List<String> dataSetCodes, String reason);
+    public void removeDataSetsPermanently(String sessionToken, List<String> dataSetCodes,
+            String reason);
 
     /**
      * updates a data set.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value =
         { ObjectKind.EXPERIMENT, ObjectKind.SAMPLE, ObjectKind.DATA_SET })
-    public void updateDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetUpdatesPredicate.class)
-            DataSetUpdatesDTO dataSetUpdates);
+    public void updateDataSet(String sessionToken, DataSetUpdatesDTO dataSetUpdates);
 
     /**
      * Returns a list of configured trusted domains which can host external shared web resources.
@@ -760,14 +617,12 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Can return empty list.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> getTrustedCrossOriginDomains(String sessionToken);
 
     /**
      * Marks the storage of dataset as confirmed. Adds the given dataset to post-registration queue
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseUpdateModification(value =
         { ObjectKind.DATA_SET })
     @DatabaseCreateOrDeleteModification(value =
@@ -779,7 +634,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * removed from the post-registration queue.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     @DatabaseCreateOrDeleteModification(value =
         { ObjectKind.POSTREGISTRATION_QUEUE })
     public void markSuccessfulPostRegistration(String token, String dataSetCode);
@@ -788,7 +642,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Gets the list of all datasets, which are in the post-registration queue.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<ExternalData> listDataSetsForPostRegistration(String token, String dataStoreCode);
 
     /**
@@ -796,35 +649,30 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * registrationId succeeded.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public EntityOperationsState didEntityOperationsSucceed(String token, TechId registrationId);
 
     /**
      * Method that does nothing. Use it to check if the connection to the server is working.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public void heartbeat(String token);
 
     /**
      * Check whether the specified user has the given role
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public boolean doesUserHaveRole(String token, String user, String roleCode, String spaceOrNull);
 
     /**
      * Filter list of datasets to only those visible by the given user
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> filterToVisibleDataSets(String token, String user, List<String> dataSetCodes);
 
     /**
      * Filter list of experiments to only those visible by the given user
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> filterToVisibleExperiments(String token, String user,
             List<String> experimentIds);
 
@@ -832,7 +680,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * Filter list of samples to only those visible by the given user
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<String> filterToVisibleSamples(String token, String user,
             List<String> samplesIndentifiers);
 
@@ -840,7 +687,6 @@ public interface IETLLIMSService extends IServer, ISessionProvider, IConversatio
      * For given code returns the corresponding {@link ExternalDataManagementSystem}.
      */
     @Transactional(readOnly = true)
-    @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public ExternalDataManagementSystem tryGetExternalDataManagementSystem(String token,
             String externalDataManagementSystemCode);
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/authorization/ETLServiceAuthorizationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/authorization/ETLServiceAuthorizationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9709fc86566e62dcff42cf448dc9b45778e4772
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/authorization/ETLServiceAuthorizationTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.systemtest.authorization;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
+import ch.systemsx.cisd.openbis.systemtest.base.BaseTest;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class ETLServiceAuthorizationTest extends BaseTest
+{
+    private Space space;
+
+    private Space anotherSpace;
+
+    private Project project;
+
+    private Project anotherProject;
+
+    private Experiment experiment;
+
+    @BeforeClass
+    public void createSomeEntities()
+    {
+        space = create(aSpace());
+        anotherSpace = create(aSpace());
+        project = create(aProject().inSpace(space));
+        anotherProject = create(aProject().inSpace(anotherSpace));
+        experiment = create(anExperiment().inProject(project));
+        create(aSample().inExperiment(experiment));
+        create(aSample().inExperiment(experiment));
+    }
+
+    @Test
+    public void testListSamplesForInstanceAdmin()
+    {
+        String sessionToken = create(aSession().withInstanceRole(RoleWithHierarchy.INSTANCE_ADMIN));
+
+        List<Sample> samples =
+                etlService.listSamples(sessionToken,
+                        ListSampleCriteria.createForExperiment(new TechId(experiment.getId())));
+
+        assertEquals(2, samples.size());
+    }
+
+    @Test(expectedExceptions =
+        { AuthorizationFailureException.class })
+    public void testListSamplesForObserverForAnotherSpace()
+    {
+        String sessionToken =
+                create(aSession().withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, anotherSpace));
+
+        etlService.listSamples(sessionToken,
+                ListSampleCriteria.createForExperiment(new TechId(experiment.getId())));
+    }
+
+    @Test
+    public void testListProjectsForInstanceAdmin()
+    {
+        String sessionToken = create(aSession().withInstanceRole(RoleWithHierarchy.INSTANCE_ADMIN));
+
+        List<Project> projects = etlService.listProjects(sessionToken);
+
+        assertEquals(2, projects.size());
+    }
+
+    @Test
+    public void testListProjectsForObserverForSpace()
+    {
+        String sessionToken =
+                create(aSession().withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, space));
+
+        List<Project> projects = etlService.listProjects(sessionToken);
+
+        assertEquals(1, projects.size());
+    }
+}
diff --git a/openbis_all/.classpath b/openbis_all/.classpath
index e67cd218ce8190bd668379ed777b0f02af114f9e..9b9ddb2573df9593703241cc6a5a84e4e7a654ad 100644
--- a/openbis_all/.classpath
+++ b/openbis_all/.classpath
@@ -21,5 +21,6 @@
 	<classpathentry combineaccessrules="false" kind="src" path="/openbis_knime"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/openbis_api"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/openbis_standard_technologies"/>
+	<classpathentry kind="lib" path="/libraries/cisd-base/cisd-base.jar" sourcepath="/libraries/cisd-base/cisd-base-src.zip"/>
 	<classpathentry kind="output" path="targets/classes"/>
 </classpath>
diff --git a/openbis_all/source/java/.gitignore b/openbis_all/source/java/.gitignore
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/openbis_all/source/java/TransferAuthorizationAnnotations.java b/openbis_all/source/java/TransferAuthorizationAnnotations.java
new file mode 100644
index 0000000000000000000000000000000000000000..002c948f8cd839c8a69954104a921477889e9b60
--- /dev/null
+++ b/openbis_all/source/java/TransferAuthorizationAnnotations.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.shared.basic.utils.CommaSeparatedListBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.Capability;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class TransferAuthorizationAnnotations
+{
+    private static final String AUTHORIZATION_GUARD_ANNOTATION = "@"
+            + AuthorizationGuard.class.getSimpleName() + "(";
+
+    private static final Set<String> METHOD_AUTHORIZATION_ANNOTATIONS = new HashSet<String>(
+            Arrays.asList(RolesAllowed.class.getSimpleName(), Capability.class.getSimpleName(),
+                    ReturnValueFilter.class.getSimpleName()));
+
+    private static final class MethodAnnotation
+    {
+        private List<String> lines = new ArrayList<String>();
+
+        private String annotationName;
+
+        private boolean finished;
+
+        MethodAnnotation(String firstLine)
+        {
+            add(firstLine);
+            int indexOfStart = firstLine.indexOf('@');
+            int indexOfOpenParanthesis = firstLine.indexOf('(');
+            if (indexOfOpenParanthesis < 0)
+            {
+                indexOfOpenParanthesis = firstLine.length();
+            }
+            annotationName = firstLine.substring(indexOfStart + 1, indexOfOpenParanthesis);
+        }
+
+        void add(String line)
+        {
+            lines.add(line);
+            finished = line.trim().endsWith(")");
+        }
+
+        boolean isFinishedAnnotation()
+        {
+            return finished;
+        }
+
+        boolean isAuthorizationAnnotation()
+        {
+            return METHOD_AUTHORIZATION_ANNOTATIONS.contains(annotationName);
+        }
+    }
+
+    private static final class MethodWithAnnotations
+    {
+        private final List<MethodAnnotation> annotations = new ArrayList<MethodAnnotation>();
+
+        private final List<String> signatureLines = new ArrayList<String>();
+
+        private String joinedSignatureLines = "";
+
+        private String canonicalSignature;
+
+        void addAnnotation(MethodAnnotation methodAnnotation)
+        {
+            annotations.add(methodAnnotation);
+        }
+
+        void addMethodSignatureLine(String line)
+        {
+            if (line.lastIndexOf(';') >= 0)
+            {
+                line = line.substring(0, line.lastIndexOf(';'));
+            }
+            signatureLines.add(line);
+            joinedSignatureLines += line.trim();
+        }
+
+        String getSignature()
+        {
+            if (canonicalSignature == null)
+            {
+                canonicalSignature = getCanonicalSignature(joinedSignatureLines);
+            }
+            return canonicalSignature;
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            return obj instanceof MethodWithAnnotations ? getSignature().equals(
+                    ((MethodWithAnnotations) obj).getSignature()) : false;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return getSignature().hashCode();
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuilder builder = new StringBuilder();
+            builder.append(getSignature()).append(":\n");
+            for (MethodAnnotation methodAnnotation : annotations)
+            {
+                appendLines(builder, methodAnnotation.lines);
+            }
+            appendLines(builder, signatureLines);
+            return builder.toString();
+        }
+
+        public boolean hasAuthorizationAnnotations()
+        {
+            return annotations.isEmpty() == false;
+        }
+
+        public List<String> getAllLines()
+        {
+            List<String> allLines = new ArrayList<String>();
+            for (MethodAnnotation methodAnnotation : annotations)
+            {
+                allLines.addAll(methodAnnotation.lines);
+            }
+            allLines.addAll(signatureLines);
+            return allLines;
+        }
+
+    }
+
+    private static void appendLines(StringBuilder builder, List<String> lines)
+    {
+        for (String line : lines)
+        {
+            builder.append(line).append('\n');
+        }
+    }
+
+    private static String getCanonicalSignature(String joinedSignatureLines)
+    {
+        int parametersStartIndex = joinedSignatureLines.indexOf('(');
+        int parametersEndIndex = joinedSignatureLines.lastIndexOf(')');
+        String[] splittedBeginning =
+                joinedSignatureLines.substring(0, parametersStartIndex).split(" ");
+        String methodName = splittedBeginning[splittedBeginning.length - 1];
+        StringBuilder builder = new StringBuilder();
+        builder.append(methodName).append('(');
+        String[] splittedParameters =
+                joinedSignatureLines.substring(parametersStartIndex + 1, parametersEndIndex).split(
+                        ",");
+        CommaSeparatedListBuilder parametersBuilder = new CommaSeparatedListBuilder();
+        for (String parameter : splittedParameters)
+        {
+            if (parameter.trim().length() == 0)
+            {
+                continue;
+            }
+            String modifiedParameter = removeAuthorizationGuardAnnotation(parameter);
+            StringTokenizer stringTokenizer = new StringTokenizer(modifiedParameter);
+            String firstToken = stringTokenizer.nextToken();
+            parametersBuilder.append(firstToken.equals("final") ? stringTokenizer.nextToken()
+                    : firstToken);
+        }
+        return builder.append(parametersBuilder).append(')').toString();
+
+    }
+
+    private static final class MethodsBuilder
+    {
+        private Map<String, MethodWithAnnotations> methods =
+                new LinkedHashMap<String, MethodWithAnnotations>();
+
+        private MethodWithAnnotations currentMethod = new MethodWithAnnotations();
+
+        private MethodAnnotation methodAnnotation;
+
+        private boolean insideBody;
+
+        private boolean insideMethodSignature;
+
+        boolean addLine(String line)
+        {
+            if (insideBody == false)
+            {
+                insideBody = line.startsWith("{");
+                return false;
+            }
+            if (insideMethodSignature == false)
+            {
+                return handleAnnotationLine(line);
+            }
+            return handleSignatureLine(line);
+        }
+
+        private boolean handleAnnotationLine(String line)
+        {
+            if (line.trim().startsWith("@"))
+            {
+                methodAnnotation = new MethodAnnotation(line);
+                if (methodAnnotation.isAuthorizationAnnotation())
+                {
+                    currentMethod.addAnnotation(methodAnnotation);
+                }
+                return methodAnnotation.isAuthorizationAnnotation();
+            }
+            if (methodAnnotation != null && methodAnnotation.isFinishedAnnotation() == false)
+            {
+                methodAnnotation.add(line);
+                return methodAnnotation.isAuthorizationAnnotation();
+            }
+            return handleSignatureLine(line);
+        }
+
+        private boolean handleSignatureLine(String line)
+        {
+            currentMethod.addMethodSignatureLine(line);
+            insideMethodSignature = line.trim().endsWith(";") == false;
+            if (insideMethodSignature == false)
+            {
+                if (currentMethod.hasAuthorizationAnnotations())
+                {
+                    methods.put(currentMethod.getSignature(), currentMethod);
+                }
+                currentMethod = new MethodWithAnnotations();
+            }
+            return false;
+        }
+
+        Map<String, MethodWithAnnotations> getMethods()
+        {
+            return methods;
+        }
+    }
+
+    public static void main(String[] args)
+    {
+        if (args.length != 2)
+        {
+            System.err.println("Usage " + TransferAuthorizationAnnotations.class.getName()
+                    + " <interface source code file> <implementation source code file>");
+            System.exit(1);
+        }
+        File interfaceSourceCodeFile = new File(args[0]);
+        File implementationSourceCodeFile = new File(args[1]);
+        List<String> interfaceSourceCode = FileUtilities.loadToStringList(interfaceSourceCodeFile);
+        List<String> implementationSourceCode =
+                FileUtilities.loadToStringList(implementationSourceCodeFile);
+
+        Map<String, MethodWithAnnotations> methods =
+                parseAndRemoveAuthorizationAnnotations(interfaceSourceCode);
+        List<String> newInterfaceSourceCode =
+                removeAuthorizationGuardAnnotations(interfaceSourceCode);
+        List<String> newImplementationSourceCode =
+                injectAuthorizationAnnotations(implementationSourceCode, methods);
+        writeBack(interfaceSourceCodeFile, newInterfaceSourceCode);
+        writeBack(implementationSourceCodeFile, newImplementationSourceCode);
+    }
+
+    private static List<String> injectAuthorizationAnnotations(
+            List<String> implementationSourceCode, Map<String, MethodWithAnnotations> methods)
+    {
+        List<String> result = new ArrayList<String>();
+        List<String> methodSignature = new ArrayList<String>();
+        boolean insideBody = false;
+        for (String line : implementationSourceCode)
+        {
+            if (isEmptyLineOrJavadocOrComment(line))
+            {
+                result.add(line);
+                continue;
+            }
+            if (insideBody == false)
+            {
+                insideBody = line.startsWith("{");
+                result.add(line);
+                continue;
+            }
+            if (methodSignature.isEmpty())
+            {
+                if (line.startsWith("    public "))
+                {
+                    methodSignature.add(line);
+                } else
+                {
+                    result.add(line);
+                }
+                continue;
+            }
+            if (line.trim().startsWith("{") == false)
+            {
+                methodSignature.add(line);
+                continue;
+            }
+            String canonicalSignature = getCanonicalSignature(methodSignature);
+            MethodWithAnnotations method = methods.get(canonicalSignature);
+            result.addAll(method == null ? methodSignature : method.getAllLines());
+            methodSignature.clear();
+            result.add(line);
+        }
+        return result;
+    }
+
+    private static String getCanonicalSignature(List<String> signatureLines)
+    {
+        StringBuilder builder = new StringBuilder();
+        for (String line : signatureLines)
+        {
+            builder.append(line.trim());
+        }
+        return getCanonicalSignature(builder.toString());
+    }
+
+    private static Map<String, MethodWithAnnotations> parseAndRemoveAuthorizationAnnotations(
+            List<String> interfaceSourceCode)
+    {
+        MethodsBuilder builder = new MethodsBuilder();
+        for (Iterator<String> iterator = interfaceSourceCode.iterator(); iterator.hasNext();)
+        {
+            String line = iterator.next();
+            if (isEmptyLineOrJavadocOrComment(line))
+            {
+                continue;
+            }
+            boolean remove = builder.addLine(line);
+            if (remove)
+            {
+                iterator.remove();
+            }
+        }
+        return builder.getMethods();
+    }
+
+    private static List<String> removeAuthorizationGuardAnnotations(List<String> interfaceSourceCode)
+    {
+        List<String> result = new ArrayList<String>();
+        for (String line : interfaceSourceCode)
+        {
+            String modifiedLine = removeAuthorizationGuardAnnotation(line);
+            if (modifiedLine.trim().length() > 0 || line.indexOf('@') < 0)
+            {
+                result.add(modifiedLine);
+            }
+        }
+        return result;
+    }
+
+    private static String removeAuthorizationGuardAnnotation(String line)
+    {
+        int indexOfAuthorizationGuardAnnotation = line.indexOf(AUTHORIZATION_GUARD_ANNOTATION);
+        if (indexOfAuthorizationGuardAnnotation < 0)
+        {
+            return line;
+        }
+        int indexOfAnnotationEnd = line.indexOf(")", indexOfAuthorizationGuardAnnotation);
+        if (indexOfAnnotationEnd < 0)
+        {
+            throw new IllegalArgumentException("Multiline annotation?: " + line);
+        }
+        return line.substring(0, indexOfAuthorizationGuardAnnotation)
+                + line.substring(indexOfAnnotationEnd + 1);
+    }
+
+    private static boolean isEmptyLineOrJavadocOrComment(String line)
+    {
+        String trimmedLine = line.trim();
+        return trimmedLine.length() == 0 || trimmedLine.startsWith("//")
+                || trimmedLine.startsWith("/*") || trimmedLine.startsWith("/**")
+                || trimmedLine.startsWith("*");
+    }
+
+    private static void writeBack(File file, List<String> sourceCode)
+    {
+        StringBuilder builder = new StringBuilder();
+        for (String line : sourceCode)
+        {
+            builder.append(line).append('\n');
+        }
+        FileUtilities.writeToFile(file, builder.toString());
+    }
+}
diff --git a/openbis_all/source/python/transferAuthorizationAnnotations.py b/openbis_all/source/python/transferAuthorizationAnnotations.py
new file mode 100644
index 0000000000000000000000000000000000000000..26754f7febae64e708197cf1407cb25eb46ec585
--- /dev/null
+++ b/openbis_all/source/python/transferAuthorizationAnnotations.py
@@ -0,0 +1,12 @@
+#!/usr/bin/python
+
+def readFile(path):
+  lines = []
+  with open(path, "r") as file:
+    for line in file:
+      lines += [line.rstrip()]
+  return lines
+  
+def transferAnnotations(interfaceSourceFilePath, to):
+  interfaceSourceCode = readFile(interfaceSourceFilePath)
+  
\ No newline at end of file