diff --git a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
index ba0c26fdf5c04a88eaa159afb45a8b502ee57c39..8a122cf3b5f7a1a559cc8ec5b470a3e852a09830 100644
--- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
@@ -24,6 +24,7 @@ import static org.olat.restapi.security.RestSecurityHelper.getUserRequest;
 import static org.olat.restapi.security.RestSecurityHelper.isAdmin;
 import static org.olat.restapi.security.RestSecurityHelper.isAuthor;
 import static org.olat.restapi.security.RestSecurityHelper.isAuthorEditor;
+import static org.olat.restapi.security.RestSecurityHelper.isInstitutionalResourceManager;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -222,7 +223,7 @@ public class CourseWebService {
 		}
 
 		UserRequest ureq = getUserRequest(request);
-		if (!isAuthorEditor(course, request)) {
+		if (!isAuthorEditor(course, request) && !isInstitutionalResourceManager(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -343,7 +344,7 @@ public class CourseWebService {
 	public Response deleteCourse(@Context HttpServletRequest request) {
 		if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
-		} else if (!isAuthorEditor(course, request)) {
+		} else if (!isAuthorEditor(course, request) && !isInstitutionalResourceManager(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -383,7 +384,7 @@ public class CourseWebService {
 	public Response deleteCoursePermanently(@FormParam("newStatus") String newStatus, @Context HttpServletRequest request) {
 		if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
-		} else if (!isAuthorEditor(course, request)) {
+		} else if (!isAuthorEditor(course, request) && !isInstitutionalResourceManager(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -437,7 +438,7 @@ public class CourseWebService {
 	public Response getConfiguration(@Context HttpServletRequest request) {
 		if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
-		} else if (!isAuthorEditor(course, request)) {
+		} else if (!isAuthorEditor(course, request) && !isInstitutionalResourceManager(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		CourseConfigVO vo = ObjectFactory.getConfig(course);
@@ -520,7 +521,7 @@ public class CourseWebService {
 	@Path("runstructure")
 	@Produces(MediaType.APPLICATION_XML)
 	public Response findRunStructureById(@Context HttpServletRequest httpRequest, @Context Request request) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -548,7 +549,7 @@ public class CourseWebService {
 	@Path("editortreemodel")
 	@Produces(MediaType.APPLICATION_XML)
 	public Response findEditorTreeModelById(@Context HttpServletRequest httpRequest, @Context Request request) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		VFSItem editorModelItem = course.getCourseBaseContainer().resolve("editortreemodel.xml");
@@ -575,7 +576,7 @@ public class CourseWebService {
 	@Path("authors")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response getAuthors(@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -605,7 +606,7 @@ public class CourseWebService {
 	@Path("tutors")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response getTutors(@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -635,7 +636,7 @@ public class CourseWebService {
 	@Path("participants")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response getParticipants(@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -667,7 +668,7 @@ public class CourseWebService {
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response getAuthor(@PathParam("identityKey") Long identityKey,
 			@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -699,7 +700,7 @@ public class CourseWebService {
 	@Path("authors/{identityKey}")
 	public Response addAuthor(@PathParam("identityKey") Long identityKey,
 			@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
@@ -733,7 +734,7 @@ public class CourseWebService {
 	@Path("authors")
 	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response addAuthors(UserVO[] authors, @Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
@@ -769,10 +770,9 @@ public class CourseWebService {
 	 */
 	@DELETE
 	@Path("authors/{identityKey}")
-	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response removeAuthor(@PathParam("identityKey") Long identityKey,
 			@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -805,7 +805,7 @@ public class CourseWebService {
 	@Path("tutors/{identityKey}")
 	public Response addCoach(@PathParam("identityKey") Long identityKey,
 			@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
@@ -832,7 +832,7 @@ public class CourseWebService {
 	@Path("tutors")
 	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response addCoaches(UserVO[] coaches, @Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
@@ -848,6 +848,39 @@ public class CourseWebService {
 		return Response.ok().build();
 	}
 	
+	/**
+	 * Remove a coach from the course
+	 * @response.representation.200.doc The user was successfully removed as coach of the course
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course or the user not found
+	 * @param identityKey The user identifier
+	 * @param httpRequest The HTTP request
+	 * @return It returns 200  if the user is removed as coach of the course
+	 */
+	@DELETE
+	@Path("tutors/{identityKey}")
+	public Response removeCoach(@PathParam("identityKey") Long identityKey,
+			@Context HttpServletRequest httpRequest) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		BaseSecurity securityManager = BaseSecurityManager.getInstance();
+		Identity coach = securityManager.loadIdentityByKey(identityKey, false);
+		if(coach == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		Identity identity = getIdentity(httpRequest);
+		
+		//remove the user as coach of the course
+		RepositoryManager rm = RepositoryManager.getInstance();
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		List<Identity> coaches = Collections.singletonList(coach);
+		rm.removeTutors(identity, coaches, repositoryEntry, new MailPackage(false));
+		return Response.ok().build();
+	}
+	
 	/**
 	 * Add an participant to the course
 	 * @response.representation.200.doc The user is a participant of the course
@@ -861,7 +894,7 @@ public class CourseWebService {
 	@Path("participants/{identityKey}")
 	public Response addParticipant(@PathParam("identityKey") Long identityKey,
 			@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
@@ -898,7 +931,7 @@ public class CourseWebService {
 	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response addParticipants(UserVO[] participants,
 			@Context HttpServletRequest httpRequest) {
-		if (!isAuthorEditor(course, httpRequest)) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
@@ -914,6 +947,39 @@ public class CourseWebService {
 		return Response.ok().build();
 	}
 	
+	/**
+	 * Remove a participant from the course
+	 * @response.representation.200.doc The user was successfully removed as participant of the course
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course or the user not found
+	 * @param identityKey The user identifier
+	 * @param httpRequest The HTTP request
+	 * @return It returns 200  if the user is removed as participant of the course
+	 */
+	@DELETE
+	@Path("participants/{identityKey}")
+	public Response removeParticipant(@PathParam("identityKey") Long identityKey,
+			@Context HttpServletRequest httpRequest) {
+		if (!isAuthorEditor(course, httpRequest) && !isInstitutionalResourceManager(httpRequest)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		BaseSecurity securityManager = BaseSecurityManager.getInstance();
+		Identity participant = securityManager.loadIdentityByKey(identityKey, false);
+		if(participant == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		Identity identity = getIdentity(httpRequest);
+		
+		//remove the user as participant of the course
+		RepositoryManager rm = RepositoryManager.getInstance();
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		List<Identity> participants = Collections.singletonList(participant);
+		rm.removeParticipants(identity, participants, repositoryEntry, new MailPackage(false), false);
+		return Response.ok().build();
+	}
+	
 	private List<Identity> loadIdentities(UserVO[] users) {
 		List<Long> identityKeys = new ArrayList<>();
 		for(UserVO user:users) {
diff --git a/src/main/java/org/olat/restapi/security/RestSecurityHelper.java b/src/main/java/org/olat/restapi/security/RestSecurityHelper.java
index 4ca6e30f5e5eda429165042034fab13825603a0a..097b4cb10c9433fbb27e2737119e092cc914351f 100644
--- a/src/main/java/org/olat/restapi/security/RestSecurityHelper.java
+++ b/src/main/java/org/olat/restapi/security/RestSecurityHelper.java
@@ -96,7 +96,7 @@ public class RestSecurityHelper {
 	public static boolean isAuthor(HttpServletRequest request) {
 		try {
 			Roles roles = getRoles(request);
-			return (roles.isAuthor() || roles.isOLATAdmin());
+			return (roles.isAuthor() || roles.isOLATAdmin() || roles.isInstitutionalResourceManager());
 		} catch (Exception e) {
 			return false;
 		}
@@ -151,6 +151,15 @@ public class RestSecurityHelper {
 		}
 	}
 	
+	public static boolean isInstitutionalResourceManager(HttpServletRequest request) {
+		try {
+			Roles roles = getRoles(request);
+			return (roles.isInstitutionalResourceManager() || roles.isOLATAdmin());
+		} catch (Exception e) {
+			return false;
+		}
+	}
+	
 	public static boolean isQuestionPoolManager(HttpServletRequest request) {
 		try {
 			Roles roles = getRoles(request);
diff --git a/src/test/java/org/olat/restapi/CourseTest.java b/src/test/java/org/olat/restapi/CourseTest.java
index b76d8b70d4b1ca42dc53bdd60ae0508ca65a905f..b5f47ec8bf02ac80b2bb86474e502fbd0ba47a58 100644
--- a/src/test/java/org/olat/restapi/CourseTest.java
+++ b/src/test/java/org/olat/restapi/CourseTest.java
@@ -354,7 +354,7 @@ public class CourseTest extends OlatJerseyTestCase {
 		
 		//make auth1 and auth2 owner
 		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
-		List<Identity> authors = new ArrayList<Identity>();
+		List<Identity> authors = new ArrayList<>();
 		authors.add(auth1);
 		authors.add(auth2);
 		IdentitiesAddEvent identitiesAddedEvent = new IdentitiesAddEvent(authors);
@@ -425,6 +425,29 @@ public class CourseTest extends OlatJerseyTestCase {
 		dbInstance.intermediateCommit();
 		assertTrue(isTutor);
 	}
+	
+	@Test
+	public void removeCoach() throws IOException, URISyntaxException {
+		//add a coach
+		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("Course-coach");
+		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
+		repositoryService.addRole(coach, repositoryEntry, GroupRoles.coach.name());
+		dbInstance.commitAndCloseSession();
+		boolean isTutor = repositoryService.hasRole(coach, repositoryEntry, GroupRoles.coach.name());
+		Assert.assertTrue(isTutor);
+		
+		//test remove
+		assertTrue(conn.login("administrator", "openolat"));
+		URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/tutors/" + coach.getKey()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		//check database
+		boolean deletedCoach = repositoryService.hasRole(coach, repositoryEntry, GroupRoles.coach.name());
+		Assert.assertFalse(deletedCoach);
+	}
 
 	@Test
 	public void addCoaches() throws IOException, URISyntaxException {
@@ -500,6 +523,29 @@ public class CourseTest extends OlatJerseyTestCase {
 		Assert.assertTrue(isParticipant);
 	}
 	
+	@Test
+	public void removeParticipant() throws IOException, URISyntaxException {
+		//add a coach
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Course-part");
+		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
+		repositoryService.addRole(participant, repositoryEntry, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		boolean isParticipant = repositoryService.hasRole(participant, repositoryEntry, GroupRoles.participant.name());
+		Assert.assertTrue(isParticipant);
+		
+		//test remove
+		assertTrue(conn.login("administrator", "openolat"));
+		URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/participants/" + participant.getKey()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		//check database
+		boolean stillParticipant = repositoryService.hasRole(participant, repositoryEntry, GroupRoles.participant.name());
+		Assert.assertFalse(stillParticipant);
+	}
+	
 	@Test
 	public void addParticipants() throws IOException, URISyntaxException {
 		Assert.assertTrue(conn.login("administrator", "openolat"));