diff --git a/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/utils/CriteriaUtils.java b/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/utils/CriteriaUtils.java
index 310fc23ba532456dc173a842a61140b948571d6d..204e05c6143de04b1ca363fd7bceb3a8f4c98829 100644
--- a/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/utils/CriteriaUtils.java
+++ b/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/utils/CriteriaUtils.java
@@ -127,21 +127,32 @@ public final class CriteriaUtils {
      */
     public static void checkContainsAuthorizedKeys(final QueryDto queryDto, final Collection<String> allowedKeys) {
         queryDto.getCriterionList().forEach(criterion -> {
+            if (allowedKeys.contains(criterion.getKey())) {
+                return;
+            }
+
             // if we have a ElemMatch operator we have to check that current field is allowed and his child field also
             // field.childField
+            String keyWithPoint = criterion.getKey() + ".";
             if (criterion.getOperator().equals(CriterionOperator.ELEMMATCH) &&
-                allowedKeys.stream().anyMatch(key -> key.startsWith(criterion.getKey() + "."))) {
-                // we recurse on children to check the allowed key
+                allowedKeys.stream().anyMatch(key -> key.startsWith(keyWithPoint))) {
+                // we recurse on children's to check the allowed key
                 try {
                     QueryDto elemMatchQuery = QueryDto.fromJson(JsonUtils.toJson(criterion.getValue()));
-                    checkContainsAuthorizedKeys(elemMatchQuery, allowedKeys);
+                    List<String> elemAllowedKeys =
+                        allowedKeys.stream()
+                            .filter(key -> key.startsWith(keyWithPoint))
+                            .map(key -> key.replaceFirst(keyWithPoint, ""))
+                            .collect(Collectors.toList());
+                    checkContainsAuthorizedKeys(elemMatchQuery, elemAllowedKeys);
                 }
                 catch (JsonProcessingException e) {
                     throw new InvalidFormatException(e.getMessage(), e);
                 }
-            } else if (!allowedKeys.contains(criterion.getKey())) {
-                throw new ForbiddenException("Criterion with key : " + criterion.getKey() + " is not allowed");
+                return;
             }
+
+            throw new ForbiddenException("Criterion with key : " + criterion.getKey() + " is not allowed");
         });
         queryDto.getSubQueries().forEach(queryDtoItem -> checkContainsAuthorizedKeys(queryDtoItem, allowedKeys));
     }
diff --git a/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java b/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java
index 2186eceffad2fed5f2d06a680a837e7f6414730f..9326268ced60077684fe2ff756c5c40980314ee6 100644
--- a/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java
+++ b/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java
@@ -290,7 +290,7 @@ public final class MongoUtils {
                 criteria = buildAndOperator(startCriteria, endCriteria);
                 break;
             case ELEMMATCH :
-                criteria = Criteria.where(key).elemMatch(queryDtoToCriterion((QueryDto)val));
+                criteria = Criteria.where(key).elemMatch(queryDtoToCriteria((QueryDto)val));
                 break;
             default :
                 throw new IllegalArgumentException("Operator " + operator + " is not supported");
@@ -298,7 +298,12 @@ public final class MongoUtils {
         return criteria;
     }
 
-    public static Criteria queryDtoToCriterion(QueryDto queryDto) {
+    /**
+     * convert QueryDto to mongodb criteria
+     * @param queryDto the QueryDto to convert
+     * @return mongodb criteria
+     */
+    public static Criteria queryDtoToCriteria(QueryDto queryDto) {
         Collection<CriteriaDefinition> criteria = new ArrayList<>();
         queryDto.getCriterionList().forEach(criterion -> {
             criteria.add(MongoUtils.getCriteria(criterion.getKey(), criterion.getValue(), criterion.getOperator()));
@@ -306,7 +311,7 @@ public final class MongoUtils {
 
         // if the criteria contains subQueries, a recursive call is made for each subQuery
         queryDto.getSubQueries().forEach(queryDtoItem -> {
-            criteria.add(queryDtoToCriterion(queryDtoItem));
+            criteria.add(queryDtoToCriteria(queryDtoItem));
         });
 
         final Criteria commonCustomCriteria = new Criteria();