diff --git a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java
index 8fb1f607d9552021598254f1df8e1c36f34d6b33..4b93e2f751ad1f2614bd239ae644733855b7e417 100644
--- a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java
+++ b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java
@@ -1138,7 +1138,7 @@ public abstract class BaseTest {
 
     public final static Database DATABASE_2 = Database.builder()
             .id(DATABASE_2_ID)
-            .created(DATABASE_1_CREATED)
+            .created(DATABASE_2_CREATED)
             .lastModified(Instant.now())
             .isPublic(DATABASE_2_PUBLIC)
             .name(DATABASE_2_NAME)
@@ -1160,7 +1160,7 @@ public abstract class BaseTest {
 
     public final static Database DATABASE_2_SIMPLE = Database.builder()
             .id(DATABASE_2_ID)
-            .created(DATABASE_1_CREATED)
+            .created(DATABASE_2_CREATED)
             .lastModified(Instant.now())
             .isPublic(DATABASE_2_PUBLIC)
             .name(DATABASE_2_NAME)
diff --git a/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
index 60f9de04690d74e20234aabe8071fc4de00612b0..b345c7ced3a021bc3aef6707365c7b186016377d 100644
--- a/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
+++ b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
@@ -3,10 +3,13 @@ package at.tuwien.endpoints;
 import at.tuwien.api.database.table.*;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.entities.database.table.Table;
+import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.TableMapper;
+import at.tuwien.service.DatabaseService;
 import at.tuwien.service.MessageQueueService;
 import at.tuwien.service.TableService;
+import at.tuwien.validation.EndpointValidator;
 import io.micrometer.core.annotation.Timed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
@@ -37,12 +40,15 @@ public class TableEndpoint {
     private final TableMapper tableMapper;
     private final TableService tableService;
     private final MessageQueueService amqpService;
+    private final EndpointValidator endpointValidator;
 
     @Autowired
-    public TableEndpoint(TableMapper tableMapper, TableService tableService, MessageQueueService amqpService) {
+    public TableEndpoint(TableMapper tableMapper, TableService tableService, MessageQueueService amqpService,
+                         EndpointValidator endpointValidator) {
         this.tableMapper = tableMapper;
         this.amqpService = amqpService;
         this.tableService = tableService;
+        this.endpointValidator = endpointValidator;
     }
 
     @GetMapping
@@ -69,9 +75,11 @@ public class TableEndpoint {
     public ResponseEntity<List<TableBriefDto>> list(@NotNull @PathVariable("id") Long containerId,
                                                     @NotNull @PathVariable("databaseId") Long databaseId,
                                                     Principal principal)
-            throws DatabaseNotFoundException {
+            throws DatabaseNotFoundException, NotAllowedException {
         log.debug("endpoint list tables, containerId={}, databaseId={}, principal={}", containerId, databaseId,
                 principal);
+        endpointValidator.validateOnlyPrivateAccess(containerId, databaseId, principal);
+        endpointValidator.validateOnlyPrivateHasRole(containerId, databaseId, principal, "list-tables");
         final List<TableBriefDto> dto = tableService.findAll(containerId, databaseId)
                 .stream()
                 .map(tableMapper::tableToTableBriefDto)
@@ -131,6 +139,7 @@ public class TableEndpoint {
             NotAllowedException {
         log.debug("endpoint create table, containerId={}, databaseId={}, createDto={}, principal={}", containerId,
                 databaseId, createDto, principal);
+        endpointValidator.validateOnlyAccess(databaseId, principal, true);
         final Table table = tableService.createTable(containerId, databaseId, createDto, principal);
         amqpService.create(table);
         final TableBriefDto dto = tableMapper.tableToTableBriefDto(table);
@@ -170,9 +179,14 @@ public class TableEndpoint {
                                              @NotNull @PathVariable("databaseId") Long databaseId,
                                              @NotNull @PathVariable("tableId") Long tableId,
                                              Principal principal)
-            throws TableNotFoundException, DatabaseNotFoundException, ContainerNotFoundException {
+            throws TableNotFoundException, DatabaseNotFoundException, ContainerNotFoundException, NotAllowedException {
         log.debug("endpoint find table, containerId={}, databaseId={}, tableId={}, principal={}", containerId,
                 databaseId, tableId, principal);
+        endpointValidator.validateOnlyPrivateAccess(containerId, databaseId, principal);
+        if (principal != null && User.hasRole(principal, "find-table")) {
+            log.error("Failed to find table: role is missing");
+            throw new NotAllowedException("Failed to find table: role is missing");
+        }
         final Table table = tableService.findById(containerId, databaseId, tableId);
         final TableDto dto = tableMapper.tableToTableDto(table);
         log.trace("find table resulted in table {}", dto);
@@ -222,13 +236,14 @@ public class TableEndpoint {
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<Void> delete(@NotNull @PathVariable("id") Long containerId,
-                       @NotNull @PathVariable("databaseId") Long databaseId,
-                       @NotNull @PathVariable("tableId") Long tableId,
-                       @NotNull Principal principal)
+                                       @NotNull @PathVariable("databaseId") Long databaseId,
+                                       @NotNull @PathVariable("tableId") Long tableId,
+                                       @NotNull Principal principal)
             throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
-            DataProcessingException, ContainerNotFoundException, TableMalformedException, QueryMalformedException {
+            DataProcessingException, ContainerNotFoundException, TableMalformedException, QueryMalformedException, NotAllowedException {
         log.debug("endpoint delete table, containerId={}, databaseId={}, tableId={}, principal={}", containerId,
                 databaseId, tableId, principal);
+        endpointValidator.validateOnlyOwner(containerId, databaseId, principal);
         tableService.deleteTable(containerId, databaseId, tableId);
         return ResponseEntity.accepted()
                 .build();
diff --git a/dbrepo-table-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce238cc55a3eb8833cd7c000ad53f0b52f749c58
--- /dev/null
+++ b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
@@ -0,0 +1,97 @@
+package at.tuwien.validation;
+
+import at.tuwien.entities.database.AccessType;
+import at.tuwien.entities.database.Database;
+import at.tuwien.entities.database.DatabaseAccess;
+import at.tuwien.entities.user.User;
+import at.tuwien.exception.DatabaseNotFoundException;
+import at.tuwien.exception.NotAllowedException;
+import at.tuwien.service.AccessService;
+import at.tuwien.service.DatabaseService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.security.Principal;
+
+@Log4j2
+@Component
+public class EndpointValidator {
+
+    private final AccessService accessService;
+    private final DatabaseService databaseService;
+
+    @Autowired
+    public EndpointValidator(AccessService accessService, DatabaseService databaseService) {
+        this.accessService = accessService;
+        this.databaseService = databaseService;
+    }
+
+    public void validateOnlyAccess(Long databaseId, Principal principal) throws NotAllowedException {
+        validateOnlyAccess(databaseId, principal, false);
+    }
+
+    public void validateOnlyPrivateAccess(Long containerId, Long databaseId, Principal principal, boolean writeAccessOnly) throws NotAllowedException, DatabaseNotFoundException {
+        final Database database = databaseService.find(containerId, databaseId);
+        if (database.getIsPublic()) {
+            log.trace("database with id {} is public: no access needed", databaseId);
+            return;
+        }
+        validateOnlyAccess(databaseId, principal, writeAccessOnly);
+    }
+
+    public void validateOnlyPrivateAccess(Long containerId, Long databaseId, Principal principal) throws NotAllowedException, DatabaseNotFoundException {
+        validateOnlyPrivateAccess(containerId, databaseId, principal, false);
+    }
+
+    public void validateOnlyAccess(Long databaseId, Principal principal, boolean writeAccessOnly) throws NotAllowedException {
+        log.trace("database with id {} is private", databaseId);
+        if (principal == null) {
+            log.error("Access not allowed: database with id {} is not public and no authorization provided", databaseId);
+            throw new NotAllowedException("Access not allowed: database with id " + databaseId + " is not public and no authorization provided");
+        }
+        log.trace("principal is {}", principal);
+        final DatabaseAccess access = accessService.find(databaseId, principal.getName());
+        log.trace("found access {}", access);
+        if (writeAccessOnly && !(access.getType().equals(AccessType.WRITE_OWN) || access.getType().equals(AccessType.WRITE_ALL))) {
+            log.error("Access not allowed: no write access");
+            throw new NotAllowedException("Access not allowed: no write access");
+        }
+    }
+
+    public void validateOnlyOwner(Long containerId, Long databaseId, Principal principal)
+            throws DatabaseNotFoundException, NotAllowedException {
+        final Database database = databaseService.find(containerId, databaseId);
+        if (principal == null) {
+            log.error("Access not allowed: no authorization provided");
+            throw new NotAllowedException("Access not allowed: no authorization provided");
+        }
+        log.trace("principal is {}", principal);
+        final DatabaseAccess access = accessService.find(databaseId, principal.getName());
+        log.trace("found access {}", access);
+        if (!database.getOwner().equals(principal)) {
+            log.error("Access not allowed: not the owner of this database with id {}", databaseId);
+            throw new NotAllowedException("Access not allowed: not the owner of this database");
+        }
+    }
+
+    public void validateOnlyPrivateHasRole(Long containerId, Long databaseId, Principal principal, String role)
+            throws DatabaseNotFoundException, NotAllowedException {
+        final Database database = databaseService.find(containerId, databaseId);
+        if (database.getIsPublic()) {
+            log.trace("database with id {} is public: no access needed", databaseId);
+            return;
+        }
+        log.trace("database with id {} is private", databaseId);
+        if (principal == null) {
+            log.error("Access not allowed: no authorization provided");
+            throw new NotAllowedException("Access not allowed: no authorization provided");
+        }
+        log.trace("principal is {}", principal);
+        if (!User.hasRole(principal, role)) {
+            log.error("Access not allowed: role {} missing", role);
+            throw new NotAllowedException("Access not allowed: role " + role + " missing");
+        }
+        log.trace("principal has role '{}': access granted", role);
+    }
+}
diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
index 04daf45d0bfd517513bcf1e066307bdcf7a74fb7..08554b354c24ea8081f222c1a2a3d86d30c7e7df 100644
--- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
+++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
@@ -1,28 +1,48 @@
 package at.tuwien.endpoint;
 
 import at.tuwien.BaseUnitTest;
+import at.tuwien.api.database.table.TableBriefDto;
+import at.tuwien.api.database.table.TableCreateDto;
+import at.tuwien.api.database.table.TableDto;
 import at.tuwien.config.IndexConfig;
 import at.tuwien.config.ReadyConfig;
 import at.tuwien.endpoints.TableEndpoint;
-import at.tuwien.exception.DatabaseNotFoundException;
+import at.tuwien.entities.database.Database;
+import at.tuwien.entities.database.DatabaseAccess;
+import at.tuwien.exception.*;
 import at.tuwien.repository.elastic.TableColumnIdxRepository;
 import at.tuwien.repository.elastic.TableIdxRepository;
 import at.tuwien.repository.jpa.*;
+import at.tuwien.service.AccessService;
 import at.tuwien.service.DatabaseService;
 import com.rabbitmq.client.Channel;
+import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.test.context.support.WithAnonymousUser;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
+import java.security.Principal;
+import java.util.List;
+
 import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
 
-@ExtendWith(SpringExtension.class)
+@Log4j2
+@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class)
 @SpringBootTest
+@ExtendWith(SpringExtension.class)
 public class TableEndpointUnitTest extends BaseUnitTest {
 
     @MockBean
@@ -40,36 +60,267 @@ public class TableEndpointUnitTest extends BaseUnitTest {
     @MockBean
     private TableColumnIdxRepository tableColumnidxRepository;
 
-    @Autowired
-    private ContainerRepository containerRepository;
-
-    @Autowired
-    private ImageRepository imageRepository;
+    @MockBean
+    private DatabaseService databaseService;
 
-    @Autowired
-    private UserRepository userRepository;
+    @MockBean
+    private TableRepository tableRepository;
 
-    @Autowired
-    private RealmRepository realmRepository;
+    @MockBean
+    private AccessService accessService;
 
     @Autowired
     private TableEndpoint tableEndpoint;
 
     @BeforeEach
     public void beforeEach() {
-        /* metadata database */
-        imageRepository.save(IMAGE_1_SIMPLE);
-        realmRepository.save(REALM_DBREPO);
-        userRepository.save(USER_1_SIMPLE);
-        containerRepository.save(CONTAINER_1_SIMPLE);
+        DATABASE_1.setTables(List.of(TABLE_1, TABLE_2, TABLE_3, TABLE_7));
+        DATABASE_3.setTables(List.of(TABLE_8));
+    }
+
+    @Test
+    @WithAnonymousUser
+    public void list_publicAnonymous_succeeds() throws NotAllowedException, DatabaseNotFoundException {
+
+        /* test */
+        generic_list(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, null, null, null);
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = "find-table")
+    public void list_publicHasRoleDatabaseNotFound_fails() {
+
+        /* test */
+        assertThrows(DatabaseNotFoundException.class, () -> {
+            generic_list(CONTAINER_3_ID, DATABASE_3_ID, null, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_READ_ACCESS);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = "find-table")
+    public void list_publicHasRole_succeeds() throws DatabaseNotFoundException, NotAllowedException {
+
+        /* test */
+        final ResponseEntity<List<TableBriefDto>> response = generic_list(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS);
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        final List<TableBriefDto> body = response.getBody();
+        assertNotNull(body);
+        assertEquals(1, body.size());
+    }
+
+    @Test
+    @WithMockUser(username = USER_4_USERNAME)
+    public void list_publicNoRole_succeeds() throws NotAllowedException, DatabaseNotFoundException {
+
+        /* test */
+        generic_list(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, USER_4_USERNAME, USER_4_PRINCIPAL, null);
+    }
+
+    @Test
+    @WithAnonymousUser
+    public void create_publicAnonymous_fails() {
+
+        /* test */
+        assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> {
+            generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, null, null, null);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"})
+    public void create_publicHasRoleDatabaseNotFound_fails() {
+
+        /* test */
+        assertThrows(DatabaseNotFoundException.class, () -> {
+            generic_create(CONTAINER_3_ID, DATABASE_3_ID, null, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_WRITE_OWN_ACCESS);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"})
+    public void create_publicHasRoleNoAccess_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, null);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME)
+    public void create_publicNoRole_fails() {
+
+        /* test */
+        assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> {
+            generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_WRITE_OWN_ACCESS);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"})
+    public void create_publicHasRoleOnlyReadAccess_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_READ_ACCESS);
+        });
+    }
+
+    /* ################################################################################################### */
+    /* ## PRIVATE DATABASES                                                                             ## */
+    /* ################################################################################################### */
+
+    @Test
+    @WithAnonymousUser
+    public void list_privateAnonymous_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_list(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, null, null);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = "find-table")
+    public void list_privateHasRoleDatabaseNotFound_fails() {
+
+        /* test */
+        assertThrows(DatabaseNotFoundException.class, () -> {
+            generic_list(CONTAINER_1_ID, DATABASE_1_ID, null, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = "find-table")
+    public void list_privateHasRole_succeeds() throws DatabaseNotFoundException, NotAllowedException {
+
+        /* test */
+        final ResponseEntity<List<TableBriefDto>> response = generic_list(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS);
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        final List<TableBriefDto> body = response.getBody();
+        assertNotNull(body);
+        assertEquals(4, body.size());
+    }
+
+    @Test
+    @WithMockUser(username = USER_4_USERNAME)
+    public void list_privateNoRole_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_list(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, USER_4_USERNAME, USER_4_PRINCIPAL, null);
+        });
+    }
+
+    @Test
+    @WithAnonymousUser
+    public void create_privateAnonymous_fails() {
+
+        /* test */
+        assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> {
+            generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, null, null, null);
+        });
     }
 
     @Test
-    public void list_databaseNotFound_fails() {
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"})
+    public void create_privateHasRoleDatabaseNotFound_fails() {
 
         /* test */
         assertThrows(DatabaseNotFoundException.class, () -> {
-            tableEndpoint.list(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL);
+            generic_create(CONTAINER_1_ID, DATABASE_1_ID, null, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_WRITE_OWN_ACCESS);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"})
+    public void create_privateHasRoleNoAccess_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, null);
         });
     }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME)
+    public void create_privateNoRole_fails() {
+
+        /* test */
+        assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> {
+            generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_WRITE_OWN_ACCESS);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"})
+    public void create_privateHasRoleOnlyReadAccess_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS);
+        });
+    }
+
+    /* ################################################################################################### */
+    /* ## GENERIC TEST CASES                                                                            ## */
+    /* ################################################################################################### */
+
+    protected ResponseEntity<List<TableBriefDto>> generic_list(Long containerId, Long databaseId, Database database, String username, Principal principal, DatabaseAccess access) throws DatabaseNotFoundException, NotAllowedException {
+
+        /* when */
+        if (database != null) {
+            when(databaseService.find(containerId, databaseId))
+                    .thenReturn(database);
+            log.trace("mock {} tables", database.getTables().size());
+            when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class)))
+                    .thenReturn(database.getTables());
+        } else {
+            doThrow(DatabaseNotFoundException.class)
+                    .when(databaseService)
+                    .find(containerId, databaseId);
+            when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class)))
+                    .thenReturn(List.of());
+        }
+        if (access != null) {
+            when(accessService.find(databaseId, username))
+                    .thenReturn(access);
+        } else {
+            doThrow(NotAllowedException.class)
+                    .when(accessService)
+                    .find(databaseId, username);
+        }
+
+        /* test */
+        return tableEndpoint.list(containerId, databaseId, principal);
+    }
+
+    protected ResponseEntity<TableBriefDto> generic_create(Long containerId, Long databaseId, Database database, TableCreateDto data, String username, Principal principal, DatabaseAccess access) throws DatabaseNotFoundException, NotAllowedException, UserNotFoundException, TableMalformedException, QueryMalformedException, ImageNotSupportedException, AmqpException, TableNameExistsException, ContainerNotFoundException {
+
+        /* when */
+        if (database != null) {
+            when(databaseService.find(containerId, databaseId))
+                    .thenReturn(database);
+            log.trace("mock {} tables", database.getTables().size());
+            when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class)))
+                    .thenReturn(database.getTables());
+        } else {
+            doThrow(DatabaseNotFoundException.class)
+                    .when(databaseService)
+                    .find(containerId, databaseId);
+            when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class)))
+                    .thenReturn(List.of());
+        }
+        if (access != null) {
+            when(accessService.find(databaseId, username))
+                    .thenReturn(access);
+        } else {
+            doThrow(NotAllowedException.class)
+                    .when(accessService)
+                    .find(databaseId, username);
+        }
+
+        /* test */
+        return tableEndpoint.create(containerId, databaseId, data, principal);
+    }
 }
diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java
index 4f1495317503816684bf80a0812d6ff7bc4b9090..3ad760a0b8236f9d1814839af7200546a3179020 100644
--- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java
+++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java
@@ -3,12 +3,15 @@ package at.tuwien.service;
 import at.tuwien.BaseUnitTest;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 @Log4j2
 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
+@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class)
 @SpringBootTest
 @ExtendWith(SpringExtension.class)
 public class ElasticSearchIndexIntegrationTest extends BaseUnitTest {
diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java
index d808459c0808115294b21d7d5c3eb3503254833d..b29d7752a4e410b5e86dbc194ceb818b596572ba 100644
--- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java
+++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java
@@ -9,16 +9,10 @@ import at.tuwien.exception.*;
 import at.tuwien.repository.elastic.TableColumnIdxRepository;
 import at.tuwien.repository.elastic.TableIdxRepository;
 import at.tuwien.repository.jpa.TableRepository;
-import at.tuwien.test.BaseTest;
 import at.tuwien.utils.AmqpUtils;
-import com.github.dockerjava.api.command.CreateContainerResponse;
-import com.github.dockerjava.api.exception.NotModifiedException;
-import com.github.dockerjava.api.model.Network;
-import com.github.dockerjava.api.model.PortBinding;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,7 +20,6 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
-import java.util.Arrays;
 import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.*;
diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java
index 0d529abc1c2e72ae8b4a3bcdc33379a0a981b8a3..d6e09d16241553b574ee5061546f32111891ade9 100644
--- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java
+++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java
@@ -15,6 +15,8 @@ import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.*;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.annotation.DirtiesContext;
@@ -28,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 
 @Log4j2
 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
+@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class)
 @SpringBootTest
 @ExtendWith(SpringExtension.class)
 public class TableServiceIntegrationReadTest extends BaseUnitTest {
diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java
index f6dabd2250294716a70520a37b2ff77f02485082..4fab7905dd319bed297ef679784c55092b0e66cd 100644
--- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java
+++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java
@@ -17,6 +17,8 @@ import org.apache.http.auth.BasicUserPrincipal;
 import org.junit.jupiter.api.*;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.annotation.DirtiesContext;
@@ -26,7 +28,6 @@ import java.io.File;
 import java.security.Principal;
 import java.util.List;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyList;
@@ -35,6 +36,7 @@ import static org.mockito.Mockito.when;
 
 @Log4j2
 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
+@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class)
 @SpringBootTest
 @ExtendWith(SpringExtension.class)
 public class TableServiceIntegrationWriteTest extends BaseUnitTest {
diff --git a/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java b/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java
index 128c4dcb8ca3ce2556d86bb84facb60f207334fe..efe2e564b81eb845098c09d481028a55aaf750f0 100644
--- a/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java
+++ b/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java
@@ -2,9 +2,14 @@ package at.tuwien.service;
 
 import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.exception.AccessDeniedException;
+import at.tuwien.exception.NotAllowedException;
+import org.springframework.transaction.annotation.Transactional;
 
 public interface AccessService {
 
+    @Transactional(readOnly = true)
+    DatabaseAccess find(Long databaseId, String username) throws NotAllowedException;
+
     /**
      * Checks if the user with username has access to the table with given id in database with given id.
      *
diff --git a/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java b/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java
index 5a840aa0e6ca89b2131b10a81cf1743635497f93..1a2f71eab8f384919c4cd22fa43526ac4c8d630f 100644
--- a/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java
+++ b/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java
@@ -2,6 +2,7 @@ package at.tuwien.service.impl;
 
 import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.exception.AccessDeniedException;
+import at.tuwien.exception.NotAllowedException;
 import at.tuwien.repository.jpa.DatabaseAccessRepository;
 import at.tuwien.service.AccessService;
 import lombok.extern.log4j.Log4j2;
@@ -22,6 +23,17 @@ public class AccessServiceImpl implements AccessService {
         this.databaseAccessRepository = databaseAccessRepository;
     }
 
+    @Override
+    @Transactional(readOnly = true)
+    public DatabaseAccess find(Long databaseId, String username) throws NotAllowedException {
+        final Optional<DatabaseAccess> optional = databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username);
+        if (optional.isEmpty()) {
+            log.error("Failed to find database access for database with id {}", databaseId);
+            throw new NotAllowedException("Failed to find database access");
+        }
+        return optional.get();
+    }
+
     @Override
     @Transactional(readOnly = true)
     public DatabaseAccess hasAccess(Long databaseId, Long tableId, String username) throws AccessDeniedException {