diff --git a/owners/src/main/java/com/googlesource/gerrit/owners/restapi/GetFilesOwners.java b/owners/src/main/java/com/googlesource/gerrit/owners/restapi/GetFilesOwners.java
index 6bdb9a2..5f5b1fb 100644
--- a/owners/src/main/java/com/googlesource/gerrit/owners/restapi/GetFilesOwners.java
+++ b/owners/src/main/java/com/googlesource/gerrit/owners/restapi/GetFilesOwners.java
@@ -20,7 +20,6 @@
 import com.google.gerrit.entities.Account;
 import com.google.gerrit.entities.Change;
 import com.google.gerrit.entities.LabelId;
-import com.google.gerrit.entities.LabelType;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.GerritApi;
 import com.google.gerrit.extensions.client.ListChangesOption;
@@ -69,9 +68,7 @@
   private final PathOwnersEntriesCache cache;
 
   static final String MISSING_CODE_REVIEW_LABEL =
-      String.format(
-          "Cannot calculate file onwers state when %s label is not configured",
-          LabelId.CODE_REVIEW);
+      "Cannot calculate file owners state when review label is not configured";
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   @Inject
@@ -97,18 +94,6 @@
       throws AuthException, BadRequestException, ResourceConflictException, Exception {
     Change change = revision.getChange();
     ChangeData changeData = revision.getChangeResource().getChangeData();
-    Short codeReviewMaxValue =
-        changeData
-            .getLabelTypes()
-            .byLabel(LabelId.CODE_REVIEW)
-            .map(LabelType::getMaxPositive)
-            .orElseThrow(
-                () -> {
-                  logger.atInfo().log(
-                      "Project %s has no Code-Review label configured hence getting file owners is not possible.",
-                      revision.getProject());
-                  return new ResourceNotFoundException(MISSING_CODE_REVIEW_LABEL);
-                });
 
     Project.NameKey project = change.getProject();
     List<Project.NameKey> projectParents =
@@ -149,34 +134,73 @@
 
       Map<Integer, Map<String, Integer>> ownersLabels = getLabels(change.getChangeId());
 
+      LabelAndScore label = getLabelDefinition(owners, changeData);
+
       Map<String, Set<GroupOwner>> filesWithPendingOwners =
           Maps.filterEntries(
               fileToOwners,
               (fileOwnerEntry) ->
                   !isApprovedByOwner(
-                      fileExpandedOwners.get(fileOwnerEntry.getKey()),
-                      ownersLabels,
-                      codeReviewMaxValue));
+                      fileExpandedOwners.get(fileOwnerEntry.getKey()), ownersLabels, label));
 
       return Response.ok(new FilesOwnersResponse(ownersLabels, filesWithPendingOwners));
     }
   }
 
+  private LabelAndScore getLabelDefinition(PathOwners owners, ChangeData changeData)
+      throws ResourceNotFoundException {
+
+    try {
+      return Optional.of(pluginSettings.enableSubmitRequirement())
+          .filter(Boolean::booleanValue)
+          .flatMap(enabled -> getLabelFromOwners(owners, changeData))
+          .orElseGet(
+              () ->
+                  new LabelAndScore(
+                      LabelId.CODE_REVIEW, getMaxScoreForLabel(changeData, LabelId.CODE_REVIEW)));
+    } catch (LabelNotFoundException e) {
+      logger.atInfo().withCause(e).log("Invalid configuration");
+      throw new ResourceNotFoundException(MISSING_CODE_REVIEW_LABEL, e);
+    }
+  }
+
+  private Optional<LabelAndScore> getLabelFromOwners(PathOwners owners, ChangeData changeData)
+      throws LabelNotFoundException {
+    return owners
+        .getLabel()
+        .map(
+            label ->
+                new LabelAndScore(
+                    label.getName(),
+                    label
+                        .getScore()
+                        .orElseGet(() -> getMaxScoreForLabel(changeData, label.getName()))));
+  }
+
+  private short getMaxScoreForLabel(ChangeData changeData, String labelId)
+      throws LabelNotFoundException {
+    return changeData
+        .getLabelTypes()
+        .byLabel(labelId)
+        .map(label -> label.getMaxPositive())
+        .orElseThrow(() -> new LabelNotFoundException(changeData.change().getProject(), labelId));
+  }
+
   private boolean isApprovedByOwner(
       Set<GroupOwner> fileOwners,
       Map<Integer, Map<String, Integer>> ownersLabels,
-      short codeReviewMaxValue) {
+      LabelAndScore label) {
     return fileOwners.stream()
         .filter(owner -> owner instanceof Owner)
         .map(owner -> ((Owner) owner).getId())
-        .flatMap(ownerId -> codeReviewLabelValue(ownersLabels, ownerId))
-        .anyMatch(value -> value == codeReviewMaxValue);
+        .flatMap(ownerId -> codeReviewLabelValue(ownersLabels, ownerId, label.getLabelId()))
+        .anyMatch(value -> value >= label.getScore());
   }
 
   private Stream<Integer> codeReviewLabelValue(
-      Map<Integer, Map<String, Integer>> ownersLabels, int ownerId) {
+      Map<Integer, Map<String, Integer>> ownersLabels, int ownerId, String labelId) {
     return Stream.ofNullable(ownersLabels.get(ownerId))
-        .flatMap(m -> Stream.ofNullable(m.get(LabelId.CODE_REVIEW)));
+        .flatMap(m -> Stream.ofNullable(m.get(labelId)));
   }
 
   /**
@@ -227,4 +251,30 @@
         .get(accountId)
         .map(as -> new Owner(as.account().fullName(), as.account().id().get()));
   }
+
+  static class LabelNotFoundException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    LabelNotFoundException(Project.NameKey project, String labelId) {
+      super(String.format("Project %s has no %s label defined", project, labelId));
+    }
+  }
+
+  private static class LabelAndScore {
+    private final String labelId;
+    private final short score;
+
+    private LabelAndScore(String labelId, short score) {
+      this.labelId = labelId;
+      this.score = score;
+    }
+
+    private String getLabelId() {
+      return labelId;
+    }
+
+    private short getScore() {
+      return score;
+    }
+  }
 }
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersIT.java b/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersIT.java
index 1c551ec..76c4962 100644
--- a/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersIT.java
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersIT.java
@@ -15,348 +15,9 @@
 
 package com.googlesource.gerrit.owners.restapi;
 
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import com.google.gerrit.acceptance.GitUtil;
-import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
-import com.google.gerrit.acceptance.PushOneCommit.Result;
-import com.google.gerrit.acceptance.TestAccount;
 import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.acceptance.UseLocalDisk;
-import com.google.gerrit.acceptance.config.GlobalPluginConfig;
-import com.google.gerrit.entities.LabelId;
-import com.google.gerrit.entities.LabelType;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.entities.Project.NameKey;
-import com.google.gerrit.entities.RefNames;
-import com.google.gerrit.extensions.client.SubmitType;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.extensions.restapi.BadRequestException;
-import com.google.gerrit.extensions.restapi.ResourceConflictException;
-import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.server.project.testing.TestLabels;
-import com.googlesource.gerrit.owners.entities.FilesOwnersResponse;
-import com.googlesource.gerrit.owners.entities.GroupOwner;
-import com.googlesource.gerrit.owners.entities.Owner;
-import java.util.Arrays;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.compress.utils.Sets;
-import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.transport.FetchResult;
-import org.eclipse.jgit.util.FS;
-import org.junit.Test;
 
 @TestPlugin(name = "owners", sysModule = "com.googlesource.gerrit.owners.OwnersModule")
 @UseLocalDisk
-public class GetFilesOwnersIT extends LightweightPluginDaemonTest {
-
-  private static final String REFS_META_CONFIG = RefNames.REFS_META + "config";
-  private GetFilesOwners ownersApi;
-  private Owner rootOwner;
-  private Owner projectOwner;
-  private NameKey parentProjectName;
-  private NameKey childProjectName;
-  private TestRepository<InMemoryRepository> childRepo;
-  private TestRepository<InMemoryRepository> parentRepo;
-  private TestRepository<InMemoryRepository> allProjectsRepo;
-
-  @Override
-  public void setUpTestPlugin() throws Exception {
-    super.setUpTestPlugin();
-
-    rootOwner = new Owner(admin.fullName(), admin.id().get());
-    projectOwner = new Owner(user.fullName(), user.id().get());
-    ownersApi = plugin.getSysInjector().getInstance(GetFilesOwners.class);
-
-    parentProjectName =
-        createProjectOverAPI("parent", allProjects, true, SubmitType.FAST_FORWARD_ONLY);
-    parentRepo = cloneProjectWithMetaRefs(parentProjectName);
-
-    childProjectName =
-        createProjectOverAPI("child", parentProjectName, true, SubmitType.FAST_FORWARD_ONLY);
-    childRepo = cloneProject(childProjectName);
-
-    allProjectsRepo = cloneProjectWithMetaRefs(allProjects);
-  }
-
-  @Test
-  public void shouldReturnExactFileOwners() throws Exception {
-    addOwnerFileToRoot(true);
-    assertChangeHasOwners(createChange().getChangeId());
-  }
-
-  @Test
-  public void shouldReturnExactFileOwnersWhenOwnersIsSetToAllProjects() throws Exception {
-    addOwnerFileWithMatchers(allProjectsRepo, REFS_META_CONFIG, true);
-    assertChangeHasOwners(createChange(childRepo).getChangeId());
-  }
-
-  @Test
-  public void shouldReturnExactFileOwnersWhenOwnersIsSetToParentProject() throws Exception {
-    addOwnerFileWithMatchers(parentRepo, REFS_META_CONFIG, true);
-    assertChangeHasOwners(createChange(childRepo).getChangeId());
-  }
-
-  @Test
-  public void shouldReturnOwnersLabelsWhenNotApprovedByOwners() throws Exception {
-    addOwnerFileToRoot(true);
-    String changeId = createChange().getChangeId();
-
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files)
-        .containsExactly("a.txt", Sets.newHashSet(new Owner(admin.fullName(), admin.id().get())));
-
-    assertThat(resp.value().ownersLabels).isEmpty();
-  }
-
-  @Test
-  public void shouldReturnEmptyResponseWhenApprovedByOwners() throws Exception {
-    addOwnerFileToRoot(true);
-    String changeId = createChange().getChangeId();
-    approve(changeId);
-
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files).isEmpty();
-  }
-
-  @Test
-  @GlobalPluginConfig(pluginName = "owners", name = "owners.expandGroups", value = "false")
-  public void shouldReturnResponseWithUnexpandedFileOwners() throws Exception {
-    addOwnerFileToRoot(true);
-    String changeId = createChange().getChangeId();
-
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files)
-        .containsExactly("a.txt", Sets.newHashSet(new GroupOwner(admin.username())));
-  }
-
-  @Test
-  @GlobalPluginConfig(pluginName = "owners", name = "owners.expandGroups", value = "false")
-  public void shouldReturnEmptyResponseWhenApprovedByOwnersWithUnexpandedFileOwners()
-      throws Exception {
-    addOwnerFileToRoot(true);
-    String changeId = createChange().getChangeId();
-    approve(changeId);
-
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files).isEmpty();
-  }
-
-  @Test
-  @GlobalPluginConfig(pluginName = "owners", name = "owners.expandGroups", value = "false")
-  public void shouldReturnResponseWithUnexpandedFileMatchersOwners() throws Exception {
-    addOwnerFileWithMatchersToRoot(true);
-    String changeId = createChange().getChangeId();
-
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files)
-        .containsExactly("a.txt", Sets.newHashSet(new GroupOwner(admin.username())));
-  }
-
-  @Test
-  @UseLocalDisk
-  public void shouldReturnInheritedOwnersFromProjectsOwners() throws Exception {
-    assertInheritFromProject(project);
-  }
-
-  @Test
-  @UseLocalDisk
-  public void shouldReturnInheritedOwnersFromParentProjectsOwners() throws Exception {
-    assertInheritFromProject(allProjects);
-  }
-
-  @Test
-  @UseLocalDisk
-  public void shouldReflectChangesInParentProject() throws Exception {
-    addOwnerFileToProjectConfig(allProjects, true, admin);
-
-    String changeId = createChange().getChangeId();
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-    assertThat(resp.value().files).containsExactly("a.txt", Sets.newHashSet(rootOwner));
-
-    addOwnerFileToProjectConfig(allProjects, true, user);
-    resp = assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-    assertThat(resp.value().files).containsExactly("a.txt", Sets.newHashSet(projectOwner));
-  }
-
-  @Test
-  @UseLocalDisk
-  public void shouldNotReturnInheritedOwnersFromProjectsOwners() throws Exception {
-    assertNotInheritFromProject(project);
-  }
-
-  @Test
-  @UseLocalDisk
-  public void shouldNotReturnInheritedOwnersFromParentProjectsOwners() throws Exception {
-    addOwnerFileToProjectConfig(project, false);
-    assertNotInheritFromProject(allProjects);
-  }
-
-  @Test
-  @UseLocalDisk
-  public void shouldThrowExceptionWhenCodeReviewLabelIsNotConfigured() throws Exception {
-    addOwnerFileToProjectConfig(project, false);
-    replaceCodeReviewWithLabel(
-        TestLabels.label(
-            "Foo", TestLabels.value(1, "Foo is fine"), TestLabels.value(-1, "Foo is not fine")));
-    String changeId = createChange().getChangeId();
-
-    ResourceNotFoundException thrown =
-        assertThrows(
-            ResourceNotFoundException.class,
-            () -> ownersApi.apply(parseCurrentRevisionResource(changeId)));
-    assertThat(thrown).hasMessageThat().isEqualTo(GetFilesOwners.MISSING_CODE_REVIEW_LABEL);
-  }
-
-  private void replaceCodeReviewWithLabel(LabelType label) throws Exception {
-    try (ProjectConfigUpdate u = updateProject(allProjects)) {
-      u.getConfig().getLabelSections().remove(LabelId.CODE_REVIEW);
-      u.getConfig().upsertLabelType(label);
-      u.save();
-    }
-  }
-
-  private static <T> Response<T> assertResponseOk(Response<T> response) {
-    assertThat(response.statusCode()).isEqualTo(HttpServletResponse.SC_OK);
-    return response;
-  }
-
-  private void assertNotInheritFromProject(Project.NameKey projectNameKey) throws Exception {
-    addOwnerFileToRoot(false);
-    addOwnerFileToProjectConfig(projectNameKey, true);
-
-    String changeId = createChange().getChangeId();
-    assertChangeHasOwners(changeId);
-  }
-
-  private void assertChangeHasOwners(String changeId)
-      throws AuthException, BadRequestException, ResourceConflictException, Exception {
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files).containsExactly("a.txt", Sets.newHashSet(rootOwner));
-  }
-
-  private void assertInheritFromProject(Project.NameKey projectNameKey) throws Exception {
-    addOwnerFileToRoot(true);
-    addOwnerFileToProjectConfig(projectNameKey, true);
-
-    String changeId = createChange().getChangeId();
-    Response<FilesOwnersResponse> resp =
-        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
-
-    assertThat(resp.value().files)
-        .containsExactly("a.txt", Sets.newHashSet(rootOwner, projectOwner));
-  }
-
-  private void addOwnerFileToProjectConfig(Project.NameKey projectNameKey, boolean inherit)
-      throws Exception {
-    addOwnerFileToProjectConfig(projectNameKey, inherit, user);
-  }
-
-  private void addOwnerFileToProjectConfig(
-      Project.NameKey projectNameKey, boolean inherit, TestAccount account) throws Exception {
-    TestRepository<InMemoryRepository> project = cloneProject(projectNameKey);
-    GitUtil.fetch(project, RefNames.REFS_CONFIG + ":" + RefNames.REFS_CONFIG);
-    project.reset(RefNames.REFS_CONFIG);
-    pushFactory
-        .create(
-            admin.newIdent(),
-            project,
-            "Add OWNER file",
-            "OWNERS",
-            String.format(
-                "inherited: %s\nmatchers:\n" + "- suffix: .txt\n  owners:\n   - %s\n",
-                inherit, account.email()))
-        .to(RefNames.REFS_CONFIG);
-  }
-
-  private void addOwnerFileToRoot(boolean inherit) throws Exception {
-    // Add OWNERS file to root:
-    //
-    // inherited: true
-    // owners:
-    // - admin
-    merge(
-        createChange(
-            testRepo,
-            "master",
-            "Add OWNER file",
-            "OWNERS",
-            String.format("inherited: %s\nowners:\n- %s\n", inherit, admin.email()),
-            ""));
-  }
-
-  private void addOwnerFileWithMatchersToRoot(boolean inherit) throws Exception {
-    addOwnerFileWithMatchers(testRepo, "master", inherit);
-  }
-
-  private void addOwnerFileWithMatchers(TestRepository<?> repo, String targetRef, boolean inherit)
-      throws Exception {
-    // Add OWNERS file to root:
-    //
-    // inherited: true
-    // matchers:
-    // - suffix: .txt
-    //   owners:
-    //   - admin@mail.com
-    Result changeCreated =
-        createChange(
-            repo,
-            targetRef,
-            "Add OWNER file",
-            "OWNERS",
-            String.format(
-                "inherited: %s\nmatchers:\n" + "- suffix: .txt\n  owners:\n   - %s\n",
-                inherit, admin.email()),
-            "");
-    changeCreated.assertOkStatus();
-    merge(changeCreated);
-  }
-
-  public TestRepository<InMemoryRepository> cloneProjectWithMetaRefs(Project.NameKey project)
-      throws Exception {
-    String uri = registerRepoConnection(project, admin);
-    String initialRef = "refs/remotes/origin/config";
-    DfsRepositoryDescription desc = new DfsRepositoryDescription("clone of " + project.get());
-
-    InMemoryRepository.Builder b = new InMemoryRepository.Builder().setRepositoryDescription(desc);
-    if (uri.startsWith("ssh://")) {
-      // SshTransport depends on a real FS to read ~/.ssh/config, but InMemoryRepository by default
-      // uses a null FS.
-      // Avoid leaking user state into our tests.
-      b.setFS(FS.detect().setUserHome(null));
-    }
-    InMemoryRepository dest = b.build();
-    Config cfg = dest.getConfig();
-    cfg.setString("remote", "origin", "url", uri);
-    cfg.setStringList(
-        "remote",
-        "origin",
-        "fetch",
-        Arrays.asList(
-            "+refs/heads/*:refs/remotes/origin/*", "+refs/meta/config:refs/remotes/origin/config"));
-    TestRepository<InMemoryRepository> testRepo = GitUtil.newTestRepository(dest);
-    FetchResult result = testRepo.git().fetch().setRemote("origin").call();
-    if (result.getTrackingRefUpdate(initialRef) != null) {
-      testRepo.reset(initialRef);
-    }
-    return testRepo;
-  }
-}
+public class GetFilesOwnersIT extends GetFilesOwnersITAbstract {}
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersITAbstract.java b/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersITAbstract.java
new file mode 100644
index 0000000..936f3d3
--- /dev/null
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersITAbstract.java
@@ -0,0 +1,361 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// 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 com.googlesource.gerrit.owners.restapi;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.acceptance.GitUtil;
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
+import com.google.gerrit.acceptance.PushOneCommit.Result;
+import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.acceptance.config.GlobalPluginConfig;
+import com.google.gerrit.entities.LabelId;
+import com.google.gerrit.entities.LabelType;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
+import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.BadRequestException;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.server.project.testing.TestLabels;
+import com.googlesource.gerrit.owners.entities.FilesOwnersResponse;
+import com.googlesource.gerrit.owners.entities.GroupOwner;
+import com.googlesource.gerrit.owners.entities.Owner;
+import com.googlesource.gerrit.owners.restapi.GetFilesOwners.LabelNotFoundException;
+import java.util.Arrays;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.compress.utils.Sets;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.transport.FetchResult;
+import org.eclipse.jgit.util.FS;
+import org.junit.Test;
+
+public abstract class GetFilesOwnersITAbstract extends LightweightPluginDaemonTest {
+
+  private static final String REFS_META_CONFIG = RefNames.REFS_META + "config";
+  protected GetFilesOwners ownersApi;
+  private Owner rootOwner;
+  private Owner projectOwner;
+  private NameKey parentProjectName;
+  private NameKey childProjectName;
+  private TestRepository<InMemoryRepository> childRepo;
+  private TestRepository<InMemoryRepository> parentRepo;
+  private TestRepository<InMemoryRepository> allProjectsRepo;
+
+  @Override
+  public void setUpTestPlugin() throws Exception {
+    super.setUpTestPlugin();
+
+    rootOwner = new Owner(admin.fullName(), admin.id().get());
+    projectOwner = new Owner(user.fullName(), user.id().get());
+    ownersApi = plugin.getSysInjector().getInstance(GetFilesOwners.class);
+
+    parentProjectName =
+        createProjectOverAPI("parent", allProjects, true, SubmitType.FAST_FORWARD_ONLY);
+    parentRepo = cloneProjectWithMetaRefs(parentProjectName);
+
+    childProjectName =
+        createProjectOverAPI("child", parentProjectName, true, SubmitType.FAST_FORWARD_ONLY);
+    childRepo = cloneProject(childProjectName);
+
+    allProjectsRepo = cloneProjectWithMetaRefs(allProjects);
+  }
+
+  @Test
+  public void shouldReturnExactFileOwners() throws Exception {
+    addOwnerFileToRoot(true);
+    assertChangeHasOwners(createChange().getChangeId());
+  }
+
+  @Test
+  public void shouldReturnExactFileOwnersWhenOwnersIsSetToAllProjects() throws Exception {
+    addOwnerFileWithMatchers(allProjectsRepo, REFS_META_CONFIG, true);
+    assertChangeHasOwners(createChange(childRepo).getChangeId());
+  }
+
+  @Test
+  public void shouldReturnExactFileOwnersWhenOwnersIsSetToParentProject() throws Exception {
+    addOwnerFileWithMatchers(parentRepo, REFS_META_CONFIG, true);
+    assertChangeHasOwners(createChange(childRepo).getChangeId());
+  }
+
+  @Test
+  public void shouldReturnOwnersLabelsWhenNotApprovedByOwners() throws Exception {
+    addOwnerFileToRoot(true);
+    String changeId = createChange().getChangeId();
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files)
+        .containsExactly("a.txt", Sets.newHashSet(new Owner(admin.fullName(), admin.id().get())));
+
+    assertThat(resp.value().ownersLabels).isEmpty();
+  }
+
+  @Test
+  public void shouldReturnEmptyResponseWhenApprovedByOwners() throws Exception {
+    addOwnerFileToRoot(true);
+    String changeId = createChange().getChangeId();
+    approve(changeId);
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files).isEmpty();
+  }
+
+  @Test
+  @GlobalPluginConfig(pluginName = "owners", name = "owners.expandGroups", value = "false")
+  public void shouldReturnResponseWithUnexpandedFileOwners() throws Exception {
+    addOwnerFileToRoot(true);
+    String changeId = createChange().getChangeId();
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files)
+        .containsExactly("a.txt", Sets.newHashSet(new GroupOwner(admin.username())));
+  }
+
+  @Test
+  @GlobalPluginConfig(pluginName = "owners", name = "owners.expandGroups", value = "false")
+  public void shouldReturnEmptyResponseWhenApprovedByOwnersWithUnexpandedFileOwners()
+      throws Exception {
+    addOwnerFileToRoot(true);
+    String changeId = createChange().getChangeId();
+    approve(changeId);
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files).isEmpty();
+  }
+
+  @Test
+  @GlobalPluginConfig(pluginName = "owners", name = "owners.expandGroups", value = "false")
+  public void shouldReturnResponseWithUnexpandedFileMatchersOwners() throws Exception {
+    addOwnerFileWithMatchersToRoot(true);
+    String changeId = createChange().getChangeId();
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files)
+        .containsExactly("a.txt", Sets.newHashSet(new GroupOwner(admin.username())));
+  }
+
+  @Test
+  @UseLocalDisk
+  public void shouldReturnInheritedOwnersFromProjectsOwners() throws Exception {
+    assertInheritFromProject(project);
+  }
+
+  @Test
+  @UseLocalDisk
+  public void shouldReturnInheritedOwnersFromParentProjectsOwners() throws Exception {
+    assertInheritFromProject(allProjects);
+  }
+
+  @Test
+  @UseLocalDisk
+  public void shouldReflectChangesInParentProject() throws Exception {
+    addOwnerFileToProjectConfig(allProjects, true, admin);
+
+    String changeId = createChange().getChangeId();
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(resp.value().files).containsExactly("a.txt", Sets.newHashSet(rootOwner));
+
+    addOwnerFileToProjectConfig(allProjects, true, user);
+    resp = assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(resp.value().files).containsExactly("a.txt", Sets.newHashSet(projectOwner));
+  }
+
+  @Test
+  @UseLocalDisk
+  public void shouldNotReturnInheritedOwnersFromProjectsOwners() throws Exception {
+    assertNotInheritFromProject(project);
+  }
+
+  @Test
+  @UseLocalDisk
+  public void shouldNotReturnInheritedOwnersFromParentProjectsOwners() throws Exception {
+    addOwnerFileToProjectConfig(project, false);
+    assertNotInheritFromProject(allProjects);
+  }
+
+  @Test
+  @UseLocalDisk
+  public void shouldThrowExceptionWhenCodeReviewLabelIsNotConfigured() throws Exception {
+    addOwnerFileToProjectConfig(project, false);
+    replaceCodeReviewWithLabel(
+        TestLabels.label(
+            "Foo", TestLabels.value(1, "Foo is fine"), TestLabels.value(-1, "Foo is not fine")));
+    String changeId = createChange().getChangeId();
+
+    ResourceNotFoundException thrown =
+        assertThrows(
+            ResourceNotFoundException.class,
+            () -> ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(thrown).hasMessageThat().isEqualTo(GetFilesOwners.MISSING_CODE_REVIEW_LABEL);
+    assertThat(thrown).hasCauseThat().isInstanceOf(LabelNotFoundException.class);
+  }
+
+  protected void replaceCodeReviewWithLabel(LabelType label) throws Exception {
+    try (ProjectConfigUpdate u = updateProject(allProjects)) {
+      u.getConfig().getLabelSections().remove(LabelId.CODE_REVIEW);
+      u.getConfig().upsertLabelType(label);
+      u.save();
+    }
+  }
+
+  protected static <T> Response<T> assertResponseOk(Response<T> response) {
+    assertThat(response.statusCode()).isEqualTo(HttpServletResponse.SC_OK);
+    return response;
+  }
+
+  private void assertNotInheritFromProject(Project.NameKey projectNameKey) throws Exception {
+    addOwnerFileToRoot(false);
+    addOwnerFileToProjectConfig(projectNameKey, true);
+
+    String changeId = createChange().getChangeId();
+    assertChangeHasOwners(changeId);
+  }
+
+  private void assertChangeHasOwners(String changeId)
+      throws AuthException, BadRequestException, ResourceConflictException, Exception {
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files).containsExactly("a.txt", Sets.newHashSet(rootOwner));
+  }
+
+  private void assertInheritFromProject(Project.NameKey projectNameKey) throws Exception {
+    addOwnerFileToRoot(true);
+    addOwnerFileToProjectConfig(projectNameKey, true);
+
+    String changeId = createChange().getChangeId();
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+
+    assertThat(resp.value().files)
+        .containsExactly("a.txt", Sets.newHashSet(rootOwner, projectOwner));
+  }
+
+  private void addOwnerFileToProjectConfig(Project.NameKey projectNameKey, boolean inherit)
+      throws Exception {
+    addOwnerFileToProjectConfig(projectNameKey, inherit, user);
+  }
+
+  private void addOwnerFileToProjectConfig(
+      Project.NameKey projectNameKey, boolean inherit, TestAccount account) throws Exception {
+    TestRepository<InMemoryRepository> project = cloneProject(projectNameKey);
+    GitUtil.fetch(project, RefNames.REFS_CONFIG + ":" + RefNames.REFS_CONFIG);
+    project.reset(RefNames.REFS_CONFIG);
+    pushFactory
+        .create(
+            admin.newIdent(),
+            project,
+            "Add OWNER file",
+            "OWNERS",
+            String.format(
+                "inherited: %s\nmatchers:\n" + "- suffix: .txt\n  owners:\n   - %s\n",
+                inherit, account.email()))
+        .to(RefNames.REFS_CONFIG);
+  }
+
+  private void addOwnerFileToRoot(boolean inherit) throws Exception {
+    // Add OWNERS file to root:
+    //
+    // inherited: true
+    // owners:
+    // - admin
+    merge(
+        createChange(
+            testRepo,
+            "master",
+            "Add OWNER file",
+            "OWNERS",
+            String.format("inherited: %s\nowners:\n- %s\n", inherit, admin.email()),
+            ""));
+  }
+
+  private void addOwnerFileWithMatchersToRoot(boolean inherit) throws Exception {
+    addOwnerFileWithMatchers(testRepo, "master", inherit);
+  }
+
+  private void addOwnerFileWithMatchers(TestRepository<?> repo, String targetRef, boolean inherit)
+      throws Exception {
+    // Add OWNERS file to root:
+    //
+    // inherited: true
+    // matchers:
+    // - suffix: .txt
+    //   owners:
+    //   - admin@mail.com
+    Result changeCreated =
+        createChange(
+            repo,
+            targetRef,
+            "Add OWNER file",
+            "OWNERS",
+            String.format(
+                "inherited: %s\nmatchers:\n" + "- suffix: .txt\n  owners:\n   - %s\n",
+                inherit, admin.email()),
+            "");
+    changeCreated.assertOkStatus();
+    merge(changeCreated);
+  }
+
+  public TestRepository<InMemoryRepository> cloneProjectWithMetaRefs(Project.NameKey project)
+      throws Exception {
+    String uri = registerRepoConnection(project, admin);
+    String initialRef = "refs/remotes/origin/config";
+    DfsRepositoryDescription desc = new DfsRepositoryDescription("clone of " + project.get());
+
+    InMemoryRepository.Builder b = new InMemoryRepository.Builder().setRepositoryDescription(desc);
+    if (uri.startsWith("ssh://")) {
+      // SshTransport depends on a real FS to read ~/.ssh/config, but InMemoryRepository by default
+      // uses a null FS.
+      // Avoid leaking user state into our tests.
+      b.setFS(FS.detect().setUserHome(null));
+    }
+    InMemoryRepository dest = b.build();
+    Config cfg = dest.getConfig();
+    cfg.setString("remote", "origin", "url", uri);
+    cfg.setStringList(
+        "remote",
+        "origin",
+        "fetch",
+        Arrays.asList(
+            "+refs/heads/*:refs/remotes/origin/*", "+refs/meta/config:refs/remotes/origin/config"));
+    TestRepository<InMemoryRepository> testRepo = GitUtil.newTestRepository(dest);
+    FetchResult result = testRepo.git().fetch().setRemote("origin").call();
+    if (result.getTrackingRefUpdate(initialRef) != null) {
+      testRepo.reset(initialRef);
+    }
+    return testRepo;
+  }
+}
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersSubmitRequirementsIT.java b/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersSubmitRequirementsIT.java
new file mode 100644
index 0000000..8172611
--- /dev/null
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/restapi/GetFilesOwnersSubmitRequirementsIT.java
@@ -0,0 +1,143 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// 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 com.googlesource.gerrit.owners.restapi;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+
+import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.entities.LabelId;
+import com.google.gerrit.entities.LabelType;
+import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.server.project.testing.TestLabels;
+import com.google.inject.Inject;
+import com.googlesource.gerrit.owners.common.LabelDefinition;
+import com.googlesource.gerrit.owners.entities.FilesOwnersResponse;
+import com.googlesource.gerrit.owners.entities.Owner;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.Map;
+import org.apache.commons.compress.utils.Sets;
+import org.eclipse.jgit.lib.Config;
+import org.junit.Test;
+
+@TestPlugin(name = "owners", sysModule = "com.googlesource.gerrit.owners.OwnersModule")
+@UseLocalDisk
+public class GetFilesOwnersSubmitRequirementsIT extends GetFilesOwnersITAbstract {
+  @Inject private ProjectOperations projectOperations;
+
+  @Override
+  public void setUpTestPlugin() throws Exception {
+    Config pluginCfg = pluginConfig.getGlobalPluginConfig("owners");
+    // enable submit requirements and store them to the file as there is no `ConfigSuite` mechanism
+    // for plugin config and there is no other way (but adding it to each test case) to enable it
+    // globally
+    pluginCfg.setBoolean("owners", null, "enableSubmitRequirement", true);
+    Files.writeString(
+        server.getSitePath().resolve("etc").resolve("owners.config"),
+        pluginCfg.toText(),
+        StandardOpenOption.CREATE,
+        StandardOpenOption.APPEND);
+    super.setUpTestPlugin();
+  }
+
+  @Test
+  public void shouldRequireConfiguredCodeReviewScore() throws Exception {
+    // configure submit requirement to require CR+1 only
+    addOwnerFileToRoot(LabelDefinition.parse("Code-Review,1").get(), admin);
+
+    String changeId = createChange("Add a file", "foo", "bar").getChangeId();
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(resp.value().files)
+        .containsExactly("foo", Sets.newHashSet(new Owner(admin.fullName(), admin.id().get())));
+    assertThat(resp.value().ownersLabels).isEmpty();
+
+    // give CR+1 as requested
+    recommend(changeId);
+
+    resp = assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(resp.value().files).isEmpty();
+    assertThat(resp.value().ownersLabels)
+        .containsExactly(admin.id().get(), Map.of(LabelId.CODE_REVIEW, 1));
+  }
+
+  @Test
+  public void shouldRequireConfiguredLabelAndScore() throws Exception {
+    // configure submit requirement to require LabelFoo+1
+    String label = "LabelFoo";
+    addOwnerFileToRoot(LabelDefinition.parse(String.format("%s,1", label)).get(), admin);
+    replaceCodeReviewWithLabel(label);
+
+    String changeId = createChange("Add a file", "foo", "bar").getChangeId();
+
+    Response<FilesOwnersResponse> resp =
+        assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(resp.value().files)
+        .containsExactly("foo", Sets.newHashSet(new Owner(admin.fullName(), admin.id().get())));
+    assertThat(resp.value().ownersLabels).isEmpty();
+
+    // give LabelFoo+1 as requested
+    gApi.changes().id(changeId).current().review(new ReviewInput().label(label, 1));
+
+    resp = assertResponseOk(ownersApi.apply(parseCurrentRevisionResource(changeId)));
+    assertThat(resp.value().files).isEmpty();
+    assertThat(resp.value().ownersLabels).containsEntry(admin.id().get(), Map.of(label, 1));
+  }
+
+  private void addOwnerFileToRoot(LabelDefinition label, TestAccount u) throws Exception {
+    // Add OWNERS file to root:
+    //
+    // inherited: true
+    // label: label,score # score is optional
+    // owners:
+    // - u.email()
+    String owners =
+        String.format(
+            "inherited: true\nlabel: %s\nowners:\n- %s\n",
+            String.format(
+                "%s%s",
+                label.getName(),
+                label.getScore().map(value -> String.format(",%d", value)).orElse("")),
+            u.email());
+    pushFactory
+        .create(admin.newIdent(), testRepo, "Add OWNER file", "OWNERS", owners)
+        .to(RefNames.fullName("master"))
+        .assertOkStatus();
+  }
+
+  private void replaceCodeReviewWithLabel(String labelId) throws Exception {
+    LabelType label =
+        TestLabels.label(labelId, TestLabels.value(1, "OK"), TestLabels.value(-1, "Not OK"));
+
+    replaceCodeReviewWithLabel(label);
+
+    // grant label to RegisteredUsers so that it is vote-able
+    String heads = RefNames.REFS_HEADS + "*";
+    projectOperations
+        .project(project)
+        .forUpdate()
+        .add(allowLabel(label.getName()).ref(heads).group(REGISTERED_USERS).range(-1, 1))
+        .update();
+  }
+}
