Only allow modules specified in known_contributing_modules to contribute artifacts or boms to the root module (#1523)

diff --git a/docs/bzlmod.md b/docs/bzlmod.md
index c68ec70..09fc426 100644
--- a/docs/bzlmod.md
+++ b/docs/bzlmod.md
@@ -163,7 +163,7 @@
 
 In the root module, if this is expected and known, you can disable this warning by adding
 the list of modules to the `known_contributing_modules` attribute of the `install` tag. The entry
-to add will be printed for you as part of the warning.
+to add will be printed for you as part of the warning. Once you set a value for `known_contributing_modules` then only those modules will be allowed to contribute dependencies.
 
 The default name used is `maven`. Modules that are expected to be included via a `bazel_dep` should
 avoid using the default name, and should always set their own (eg. `rules_jvm_external` uses
@@ -184,8 +184,13 @@
     com.google.guava:guava (31.1-jre, 33.2.1-jre)
 ```
 
-To resolve this issue, ensure that the artifact is listed in the root module. That will be the
-version used in the dependency resolution.
+The resolver will use the highest version artifact from the root and sub-modules. If the root version is not the highest you will see a warning during repinning similar to:
+
+```
+WARNING: For dependency 'com.google.protobuf:protobuf-java' the root @maven repo wants version 3.25.5, but got 4.27.2 from the bazel_worker_java bazel dep. Please update the version in your MODULE.bazel or set `force_version = True`.
+```
+
+You can either update the version in the root module to the highest version or set `force_version = True` in the root module to ensure that version will be the one used in the dependency resolution.
 
 ## Known issues
 
diff --git a/private/extensions/maven.bzl b/private/extensions/maven.bzl
index 1001a60..dc9e47a 100644
--- a/private/extensions/maven.bzl
+++ b/private/extensions/maven.bzl
@@ -585,11 +585,35 @@
         root_artifacts = root_repo.get("artifacts", [])
         bazel_dep_to_non_root_artifacts = non_root_repo.get("bazel_dep_to_artifacts", {})
         root_boms = root_repo.get("boms", [])
-        non_root_bazel_dep_to_boms = non_root_repo.get("bazel_dep_to_boms", [])
+        bazel_dep_to_non_root_boms = non_root_repo.get("bazel_dep_to_boms", [])
 
         if repo_name in root_module_repos.keys():
-            # Warn users if multiple modules contribute to the same maven `name`
-            _warn_if_multiple_contributing_modules(root_repo, repo_name, bazel_dep_to_non_root_artifacts)
+            known_contributing_modules = root_repo.get("known_contributing_modules", sets.make())
+            if sets.length(known_contributing_modules) == 0:
+                # Warn users if multiple modules contribute to the same maven `name`
+                _warn_if_multiple_contributing_modules(root_repo, repo_name, bazel_dep_to_non_root_artifacts)
+            else:
+                # Filter results so only modules in the known_contributing_modules add artifacts or boms
+                all_non_root_artifact_modules = bazel_dep_to_non_root_artifacts.keys()
+                bazel_dep_to_non_root_artifacts = {
+                    k: bazel_dep_to_non_root_artifacts[k]
+                    for k in sets.to_list(known_contributing_modules)
+                    if k in bazel_dep_to_non_root_artifacts
+                }
+                if rje_verbose_env_var:
+                    for k in all_non_root_artifact_modules:
+                        if k not in bazel_dep_to_non_root_artifacts.keys():
+                            print("\nINFO: The @%s repo is not using deps from %s because it is not in the known_contributing_modules" % (repo_name, k))
+                all_non_root_bom_modules = bazel_dep_to_non_root_boms.keys()
+                bazel_dep_to_non_root_boms = {
+                    k: bazel_dep_to_non_root_boms[k]
+                    for k in sets.to_list(known_contributing_modules)
+                    if k in bazel_dep_to_non_root_boms
+                }
+                if rje_verbose_env_var:
+                    for k in all_non_root_bom_modules:
+                        if k not in bazel_dep_to_non_root_boms.keys():
+                            print("\nINFO: The @%s repo is not using boms from %s because it is not in the known_contributing_modules" % (repo_name, k))
 
             merged_repo["artifacts"] = _deduplicate_artifacts_with_root_priority(
                 repo_name,
@@ -602,13 +626,13 @@
             merged_repo["boms"] = _deduplicate_artifacts_with_root_priority(
                 repo_name,
                 root_boms,
-                non_root_bazel_dep_to_boms,
+                bazel_dep_to_non_root_boms,
                 repin_env_var,
                 rje_verbose_env_var,
             )
         else:
             merged_repo["artifacts"] = _deduplicate_non_root_artifacts(bazel_dep_to_non_root_artifacts, True)
-            merged_repo["boms"] = _deduplicate_non_root_artifacts(non_root_bazel_dep_to_boms, True)
+            merged_repo["boms"] = _deduplicate_non_root_artifacts(bazel_dep_to_non_root_boms, True)
 
         # For list attributes, concatenate but avoid duplicates (root items first)
         for list_attr in ["repositories", "excluded_artifacts", "additional_netrc_lines", "additional_coursier_options"]: