diff --git a/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_de.properties
index 8ca50e57036682cf62abaf63919fb306061b6faa..4cef8f68713a4478e2c076eecb5695005b12d7e7 100644
--- a/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_de.properties
@@ -51,7 +51,8 @@ restrictToInstResourceManagersAndAuthorsSiteSecurityCallback=Autoren und Lernres
 restrictToUserManagerSiteSecurityCallback=Benutzerverwalter
 restrictToGroupManagerSiteSecurityCallback=Gruppenverwalter
 restrictToPoolAdminSiteSecurityCallback=Poolverwalter
-taxonomySiteSecurityCallback=Kompetenzbasiert gemäss Taxonomiekonfiguration 
+taxonomySiteSecurityCallback=Kompetenzbasiert gemäss Taxonomiekonfiguration
+poolTaxonomySiteSecurityCallback=Poolverwalter und Kompetenz
 poolPrivateMembersSiteSecurityCallback=Poolmitglieder und Poolverwalter
 authorAndPoolPrivateMembersSiteSecurityCallback=Autoren, Poolmitglieder und Poolverwalter
 VideoSiteDef=LearnTube
diff --git a/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_en.properties
index 47062af13f94f8532ceb4c54c62506aac9bea8f7..c65903177a8a5e0f2d0d858c62c4cc9568ec2fcd 100644
--- a/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_en.properties
@@ -28,6 +28,7 @@ defaultSiteSecurityCallback=All, including guests and invitee
 disabledSiteSecurityCallback=Disabled
 down=Down
 managersSiteSecurityCallback=Managers
+poolTaxonomySiteSecurityCallback=Question bank admins and competence
 poolPrivateMembersSiteSecurityCallback=Question bank admins and members
 registredOrGuestSiteSecurityCallback=Registered users and guests without invitee
 registredSiteSecurityCallback=Registered users without guests/invitee
diff --git a/src/main/java/org/olat/core/gui/control/_spring/sitedefContext.xml b/src/main/java/org/olat/core/gui/control/_spring/sitedefContext.xml
index 740ab8cff32eace7946cb826aefa9cbb675ff7d3..67ce9b7c53eed04792d6699c3fe9aaf3629ec2f9 100644
--- a/src/main/java/org/olat/core/gui/control/_spring/sitedefContext.xml
+++ b/src/main/java/org/olat/core/gui/control/_spring/sitedefContext.xml
@@ -81,7 +81,7 @@
 	<bean id="olatsites_qpool" class="org.olat.modules.qpool.site.QuestionPoolSiteDef">
 	   <property name="order" value="10" />
 	   <property name="enabled" value="${site.questionpool.enable}"/>
-	   	<property name="defaultSiteSecurityCallbackBeanId" value="restrictToAuthorSiteSecurityCallback"/>
+	   <property name="defaultSiteSecurityCallbackBeanId" value="restrictToAuthorSiteSecurityCallback"/>
 	</bean>
 	<bean id="olatsites_catalogadmin" class="org.olat.repository.site.CatalogAdminSiteDef">
 	   <property name="order" value="11" />
@@ -152,17 +152,6 @@
 		<property name="catalogManager" ref="catalogManager" />
 	</bean>
 	
-	<bean id="poolPrivateMembersSiteSecurityCallback" class="org.olat.modules.qpool.site.PoolPrivateMembersSecurityCallback">
-		<property name="qPoolService" ref="qpoolService" />
-		<property name="questionPoolModule" ref="qpoolModule" />
-	</bean>
-	
-	<bean id="authorAndPoolPrivateMembersSiteSecurityCallback" class="org.olat.modules.qpool.site.AuthorAndPoolPrivateMembersSecurityCallback">
-		<property name="qPoolService" ref="qpoolService" />
-		<property name="questionPoolModule" ref="qpoolModule" />
-	</bean>
-	
-	
 	<!-- Alternative controllers -->
 	<bean id="courseSiteForbiddenAlt" class="org.olat.core.gui.control.navigation.SiteAlternativeControllerCreator">
 		<property name="className" value="org.olat.course.site.ui.ForbiddenCourseSiteController"/>
diff --git a/src/main/java/org/olat/modules/qpool/site/AuthorAndPoolPrivateMembersSecurityCallback.java b/src/main/java/org/olat/modules/qpool/site/AuthorAndPoolPrivateMembersSecurityCallback.java
index d7e696b4547ea0f6282fb1f369d549aa371b50ff..74f7775c9e16d205ccb13ff3006e89e949c56fc3 100644
--- a/src/main/java/org/olat/modules/qpool/site/AuthorAndPoolPrivateMembersSecurityCallback.java
+++ b/src/main/java/org/olat/modules/qpool/site/AuthorAndPoolPrivateMembersSecurityCallback.java
@@ -22,10 +22,12 @@ package org.olat.modules.qpool.site;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.navigation.SiteSecurityCallback;
-import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
+import org.olat.core.util.UserSession;
 import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionPoolModule;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * 
@@ -33,42 +35,33 @@ import org.olat.modules.qpool.QuestionPoolModule;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
+@Service("authorAndPoolPrivateMembersSiteSecurityCallback")
 public class AuthorAndPoolPrivateMembersSecurityCallback implements SiteSecurityCallback {
 	
+	@Autowired
 	private QPoolService qPoolService;
+	@Autowired
 	private QuestionPoolModule questionPoolModule;
-	
-	/**
-	 * [used by Spring]
-	 * @param qPoolService
-	 */
-	public void setQPoolService(QPoolService qPoolService) {
-		this.qPoolService = qPoolService;
-	}
-	
-	/**
-	 * [used by Spring]
-	 * @param questionPoolModule
-	 */
-	public void setQuestionPoolModule(QuestionPoolModule questionPoolModule) {
-		this.questionPoolModule = questionPoolModule;
-	}
 
 	/**
 	 * @see com.frentix.olat.coursesite.SiteSecurityCallback#isAllowedToLaunchSite(org.olat.core.gui.UserRequest)
 	 */
 	@Override
 	public boolean isAllowedToLaunchSite(UserRequest ureq) {
-		if (!questionPoolModule.isEnabled() || ureq == null || ureq.getUserSession() == null || ureq.getUserSession().getRoles() == null
-				|| ureq.getIdentity() == null
-				|| ureq.getUserSession().getRoles().isInvitee() || ureq.getUserSession().getRoles().isGuestOnly()) {
+		if (!questionPoolModule.isEnabled() || ureq == null || ureq.getIdentity() == null) {
+			return false;
+		}
+		UserSession usess = ureq.getUserSession();
+		if (usess == null) {
+			return false;
+		}
+		Roles roles = usess.getRoles();
+		if (roles == null || roles.isInvitee() || roles.isGuestOnly()) {
 			return false;
 		}
-		Roles roles = ureq.getUserSession().getRoles();
 		if (roles.isOLATAdmin() || roles.isPoolAdmin() || roles.isAuthor()) {
 			return true;
 		}
-		Identity identity = ureq.getIdentity();
-		return qPoolService.isMemberOfPrivatePools(identity);
+		return qPoolService.isMemberOfPrivatePools(ureq.getIdentity());
 	}
 }
diff --git a/src/main/java/org/olat/modules/qpool/site/PoolPrivateMembersSecurityCallback.java b/src/main/java/org/olat/modules/qpool/site/PoolPrivateMembersSecurityCallback.java
index 27f798a5f61851f3fa8dcd11368ad08d38c9b966..c74a5dce9ed5d909b7788c3915fc59b15962f9fd 100644
--- a/src/main/java/org/olat/modules/qpool/site/PoolPrivateMembersSecurityCallback.java
+++ b/src/main/java/org/olat/modules/qpool/site/PoolPrivateMembersSecurityCallback.java
@@ -22,10 +22,12 @@ package org.olat.modules.qpool.site;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.navigation.SiteSecurityCallback;
-import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
+import org.olat.core.util.UserSession;
 import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionPoolModule;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * 
@@ -33,45 +35,34 @@ import org.olat.modules.qpool.QuestionPoolModule;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
+@Service("poolPrivateMembersSiteSecurityCallback")
 public class PoolPrivateMembersSecurityCallback implements SiteSecurityCallback {
 	
+	@Autowired
 	private QPoolService qPoolService;
+	@Autowired
 	private QuestionPoolModule questionPoolModule;
-	
-	
-	/**
-	 * [used by Spring]
-	 * @param qPoolService
-	 */
-	public void setQPoolService(QPoolService qPoolService) {
-		this.qPoolService = qPoolService;
-	}
-
-	/**
-	 * [used by Spring]
-	 * @param questionPoolModule
-	 */
-	public void setQuestionPoolModule(QuestionPoolModule questionPoolModule) {
-		this.questionPoolModule = questionPoolModule;
-	}
 
 	/**
 	 * @see com.frentix.olat.coursesite.SiteSecurityCallback#isAllowedToLaunchSite(org.olat.core.gui.UserRequest)
 	 */
 	@Override
 	public boolean isAllowedToLaunchSite(UserRequest ureq) {
-		if (!questionPoolModule.isEnabled() || ureq == null || ureq.getUserSession() == null || ureq.getUserSession().getRoles() == null
-				|| ureq.getIdentity() == null
-				|| ureq.getUserSession().getRoles().isInvitee() || ureq.getUserSession().getRoles().isGuestOnly()) {
+		if (!questionPoolModule.isEnabled() || ureq == null || ureq.getIdentity() == null) {
+			return false;
+		}
+		
+		UserSession usess = ureq.getUserSession();
+		if (usess == null) {
+			return false;
+		}
+		Roles roles = usess.getRoles();
+		if(roles == null || roles.isInvitee() || roles.isGuestOnly()) {
 			return false;
 		}
-
-		Roles roles = ureq.getUserSession().getRoles();
 		if (roles.isOLATAdmin() || roles.isPoolAdmin()) {
 			return true;
 		}
-		
-		Identity identity = ureq.getIdentity();
-		return qPoolService.isMemberOfPrivatePools(identity);
+		return qPoolService.isMemberOfPrivatePools(ureq.getIdentity());
 	}
 }
diff --git a/src/main/java/org/olat/modules/qpool/site/PoolTaxonomySecurityCallback.java b/src/main/java/org/olat/modules/qpool/site/PoolTaxonomySecurityCallback.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6b732acffee23f4551f94c59e690cadcdf103d9
--- /dev/null
+++ b/src/main/java/org/olat/modules/qpool/site/PoolTaxonomySecurityCallback.java
@@ -0,0 +1,85 @@
+/**
+ * OLAT - Online Learning and Training<br>
+ * http://www.olat.org
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Copyright (c) frentix GmbH<br>
+ * http://www.frentix.com<br>
+ * <p>
+ */
+package org.olat.modules.qpool.site;
+
+import java.util.Date;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.control.navigation.SiteSecurityCallback;
+import org.olat.core.id.Roles;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.UserSession;
+import org.olat.modules.qpool.QuestionPoolModule;
+import org.olat.modules.taxonomy.TaxonomyCompetenceTypes;
+import org.olat.modules.taxonomy.TaxonomyRef;
+import org.olat.modules.taxonomy.TaxonomyService;
+import org.olat.modules.taxonomy.model.TaxonomyRefImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Guest and invittee are discarded. Administrator and pool administrators
+ * are allowed and the user with a competence manage or teach (dependent
+ * on question pool settings).
+ * 
+ * Initial date: 5 janv. 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@Service("poolTaxonomySiteSecurityCallback")
+public class PoolTaxonomySecurityCallback implements SiteSecurityCallback {
+	
+	@Autowired
+	private TaxonomyService taxonomyService;
+	@Autowired
+	private QuestionPoolModule questionPoolModule;
+	
+	@Override
+	public boolean isAllowedToLaunchSite(UserRequest ureq) {
+		if (!questionPoolModule.isEnabled() || !StringHelper.isLong(questionPoolModule.getTaxonomyQPoolKey())
+				|| ureq == null || ureq.getIdentity() == null ) {
+			return false;
+		}
+		
+		UserSession usess = ureq.getUserSession();
+		if (usess == null) {
+			return false;
+		}
+
+		Roles roles = usess.getRoles();
+		if (roles == null || roles.isInvitee() || roles.isGuestOnly()) {
+			return false;
+		}
+		if (roles.isOLATAdmin() || roles.isPoolAdmin()) {
+			return true;
+		}
+		
+		TaxonomyCompetenceTypes[] types;
+		if (questionPoolModule.isFinalVisibleTeach()) {
+			types = new TaxonomyCompetenceTypes[] { TaxonomyCompetenceTypes.manage, TaxonomyCompetenceTypes.teach };
+		} else {
+			types = new TaxonomyCompetenceTypes[] { TaxonomyCompetenceTypes.manage };
+		}
+		
+		TaxonomyRef taxonomy = new TaxonomyRefImpl(Long.valueOf(questionPoolModule.getTaxonomyQPoolKey()));
+		return taxonomyService.hasTaxonomyCompetences(taxonomy, ureq.getIdentity(), new Date(), types);
+	}
+}
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java
index 501f5854bcd860600a237a3cd158c164ed003629..1de76930f82dfcf966e349c45c45191a9a26b4c1 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java
@@ -33,6 +33,7 @@ import org.olat.modules.qpool.ui.QuestionItemsSource;
 import org.olat.modules.qpool.ui.QuestionsController;
 import org.olat.modules.qpool.ui.datasource.FinalItemsSource;
 import org.olat.modules.taxonomy.TaxonomyLevel;
+import org.olat.modules.taxonomy.TaxonomyLevelType;
 
 /**
  * 
@@ -60,9 +61,9 @@ public class FinalTreeNode extends GenericTreeNode implements ControllerTreeNode
 		this.taxonomyLevel = taxonomyLevel;
 		
 		this.setTitle(taxonomyLevel.getDisplayName());
-		String iconCssClass = taxonomyLevel.getType().getCssClass();
-		if (StringHelper.containsNonWhitespace(iconCssClass)) {
-			setIconCssClass(iconCssClass);
+		TaxonomyLevelType type = taxonomyLevel.getType();
+		if (type != null && StringHelper.containsNonWhitespace(type.getCssClass())) {
+			setIconCssClass(type.getCssClass());
 		}
 		
 		this.setUserObject(taxonomyLevel);
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java
index 5c8f87a45521b2f24bd975a4c4730153c504374f..669f530475f53935bc42fe65bad017dbde77fb9f 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java
@@ -33,6 +33,7 @@ import org.olat.modules.qpool.ui.QuestionItemsSource;
 import org.olat.modules.qpool.ui.QuestionsController;
 import org.olat.modules.qpool.ui.datasource.MyTaxonomyLevelItemsSource;
 import org.olat.modules.taxonomy.TaxonomyLevel;
+import org.olat.modules.taxonomy.TaxonomyLevelType;
 
 /**
  * 
@@ -60,9 +61,9 @@ public class MyTaxonomyLevelTreeNode extends GenericTreeNode implements Controll
 		this.taxonomyLevel = taxonomyLevel;
 		
 		this.setTitle(taxonomyLevel.getDisplayName());
-		String iconCssClass = taxonomyLevel.getType().getCssClass();
-		if (StringHelper.containsNonWhitespace(iconCssClass)) {
-			setIconCssClass(iconCssClass);
+		TaxonomyLevelType type = taxonomyLevel.getType();
+		if (type != null && StringHelper.containsNonWhitespace(type.getCssClass())) {
+			setIconCssClass(type.getCssClass());
 		}
 		
 		this.setUserObject(taxonomyLevel);
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java
index c57d459338fbf8189e1c43ee7f0d6653406294b4..ec4afa2fa4569186a4542ae0eb92a4d20d7978c7 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java
@@ -36,6 +36,7 @@ import org.olat.modules.qpool.ui.QuestionItemsSource;
 import org.olat.modules.qpool.ui.QuestionsController;
 import org.olat.modules.qpool.ui.datasource.ReviewItemsSource;
 import org.olat.modules.taxonomy.TaxonomyLevel;
+import org.olat.modules.taxonomy.TaxonomyLevelType;
 
 /**
  * 
@@ -65,9 +66,9 @@ public class ReviewTreeNode extends GenericTreeNode implements ControllerTreeNod
 		source = new ReviewItemsSource(identity, roles, taxonomyLevel);
 		
 		setTitle(taxonomyLevel.getDisplayName());
-		String iconCssClass = taxonomyLevel.getType().getCssClass();
-		if (StringHelper.containsNonWhitespace(iconCssClass)) {
-			setIconCssClass(iconCssClass);
+		TaxonomyLevelType type = taxonomyLevel.getType();
+		if (type != null && StringHelper.containsNonWhitespace(type.getCssClass())) {
+			setIconCssClass(type.getCssClass());
 		}
 		reloadCount();