diff --git a/lib/modules/manager/bazel-module/extract.spec.ts b/lib/modules/manager/bazel-module/extract.spec.ts
index 15776b4035680670d6ff21be95bfc7d9a4c653b0..5e82c5682c35ab5aaa9440c19c0dc8142369254c 100644
--- a/lib/modules/manager/bazel-module/extract.spec.ts
+++ b/lib/modules/manager/bazel-module/extract.spec.ts
@@ -5,6 +5,7 @@ import { GlobalConfig } from '../../../config/global';
 import type { RepoGlobalConfig } from '../../../config/types';
 import { BazelDatasource } from '../../datasource/bazel';
 import { GithubTagsDatasource } from '../../datasource/github-tags';
+import { MavenDatasource } from '../../datasource/maven';
 import * as parser from './parser';
 import { extractPackageFile } from '.';
 
@@ -235,5 +236,106 @@ describe('modules/manager/bazel-module/extract', () => {
         },
       ]);
     });
+
+    it('returns maven.install and maven.artifact dependencies', async () => {
+      const input = codeBlock`
+        maven.artifact(
+            artifact = "core.specs.alpha",
+            exclusions = ["org.clojure:clojure"],
+            group = "org.clojure",
+            version = "0.2.56",
+        )
+
+        maven.install(
+            artifacts = [
+                "junit:junit:4.13.2",
+                "com.google.guava:guava:31.1-jre",
+            ],
+            lock_file = "//:maven_install.json",
+            repositories = [
+                "https://repo1.maven.org/maven2/",
+            ],
+            version_conflict_policy = "pinned",
+        )
+      `;
+      const result = await extractPackageFile(input, 'MODULE.bazel');
+      if (!result) {
+        throw new Error('Expected a result.');
+      }
+      expect(result.deps).toEqual([
+        {
+          datasource: MavenDatasource.id,
+          depType: 'maven_install',
+          depName: 'junit:junit',
+          currentValue: '4.13.2',
+          registryUrls: ['https://repo1.maven.org/maven2/'],
+          versioning: 'gradle',
+        },
+        {
+          datasource: MavenDatasource.id,
+          depType: 'maven_install',
+          depName: 'com.google.guava:guava',
+          currentValue: '31.1-jre',
+          registryUrls: ['https://repo1.maven.org/maven2/'],
+          versioning: 'gradle',
+        },
+        {
+          datasource: MavenDatasource.id,
+          depType: 'maven_install',
+          depName: 'org.clojure:core.specs.alpha',
+          currentValue: '0.2.56',
+          registryUrls: ['https://repo1.maven.org/maven2/'],
+          versioning: 'gradle',
+        },
+      ]);
+    });
+
+    it('returns maven.install and bazel_dep dependencies together', async () => {
+      const input = codeBlock`
+        bazel_dep(name = "bazel_jar_jar", version = "0.1.0")
+
+        maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
+
+        maven.install(
+            artifacts = [
+                "junit:junit:4.13.2",
+                "com.google.guava:guava:31.1-jre",
+            ],
+            lock_file = "//:maven_install.json",
+            repositories = [
+                "https://repo1.maven.org/maven2/",
+            ],
+            version_conflict_policy = "pinned",
+        )
+      `;
+      const result = await extractPackageFile(input, 'MODULE.bazel');
+      if (!result) {
+        throw new Error('Expected a result.');
+      }
+      expect(result.deps).toEqual([
+        {
+          datasource: BazelDatasource.id,
+          depType: 'bazel_dep',
+          depName: 'bazel_jar_jar',
+          currentValue: '0.1.0',
+        },
+        {
+          datasource: MavenDatasource.id,
+          depType: 'maven_install',
+          depName: 'junit:junit',
+          currentValue: '4.13.2',
+          registryUrls: ['https://repo1.maven.org/maven2/'],
+          versioning: 'gradle',
+        },
+        {
+          datasource: MavenDatasource.id,
+          depType: 'maven_install',
+          depName: 'com.google.guava:guava',
+          currentValue: '31.1-jre',
+          registryUrls: ['https://repo1.maven.org/maven2/'],
+          versioning: 'gradle',
+        },
+      ]);
+    });
   });
 });
diff --git a/lib/modules/manager/bazel-module/extract.ts b/lib/modules/manager/bazel-module/extract.ts
index a6b298eb26d4d26e91cd6cfdaaeb1396e4f65eed..399d471ca2b3fbc3003345d7709c10a86070dd4a 100644
--- a/lib/modules/manager/bazel-module/extract.ts
+++ b/lib/modules/manager/bazel-module/extract.ts
@@ -2,9 +2,11 @@ import { dirname } from 'upath';
 import { logger } from '../../../logger';
 import { isNotNullOrUndefined } from '../../../util/array';
 import { LooseArray } from '../../../util/schema-utils';
-import type { PackageFileContent } from '../types';
+import type { PackageDependency, PackageFileContent } from '../types';
 import * as bazelrc from './bazelrc';
+import type { RecordFragment } from './fragments';
 import { parse } from './parser';
+import { RuleToMavenPackageDep, fillRegistryUrls } from './parser/maven';
 import { RuleToBazelModulePackageDep } from './rules';
 import * as rules from './rules';
 
@@ -14,28 +16,43 @@ export async function extractPackageFile(
 ): Promise<PackageFileContent | null> {
   try {
     const records = parse(content);
-    const pfc: PackageFileContent | null = LooseArray(
-      RuleToBazelModulePackageDep,
-    )
-      .transform(rules.toPackageDependencies)
-      .transform((deps) => (deps.length ? { deps } : null))
-      .parse(records);
-    if (!pfc) {
-      return null;
-    }
+    const pfc = await extractBazelPfc(records, packageFile);
+    const mavenDeps = extractMavenDeps(records);
 
-    const registryUrls = (await bazelrc.read(dirname(packageFile)))
-      // Ignore any entries for custom configurations
-      .filter((ce) => ce.config === undefined)
-      .map((ce) => ce.getOption('registry')?.value)
-      .filter(isNotNullOrUndefined);
-    if (registryUrls.length) {
-      pfc.registryUrls = registryUrls;
+    if (mavenDeps.length) {
+      pfc.deps.push(...mavenDeps);
     }
 
-    return pfc;
+    return pfc.deps.length ? pfc : null;
   } catch (err) {
     logger.debug({ err, packageFile }, 'Failed to parse bazel module file.');
     return null;
   }
 }
+
+async function extractBazelPfc(
+  records: RecordFragment[],
+  packageFile: string,
+): Promise<PackageFileContent> {
+  const pfc: PackageFileContent = LooseArray(RuleToBazelModulePackageDep)
+    .transform(rules.toPackageDependencies)
+    .transform((deps) => ({ deps }))
+    .parse(records);
+
+  const registryUrls = (await bazelrc.read(dirname(packageFile)))
+    // Ignore any entries for custom configurations
+    .filter((ce) => ce.config === undefined)
+    .map((ce) => ce.getOption('registry')?.value)
+    .filter(isNotNullOrUndefined);
+  if (registryUrls.length) {
+    pfc.registryUrls = registryUrls;
+  }
+
+  return pfc;
+}
+
+function extractMavenDeps(records: RecordFragment[]): PackageDependency[] {
+  return LooseArray(RuleToMavenPackageDep)
+    .transform(fillRegistryUrls)
+    .parse(records);
+}
diff --git a/lib/modules/manager/bazel-module/fragments.ts b/lib/modules/manager/bazel-module/fragments.ts
index a5e74aa1092a29a00a11f20ff7a2142a8d30e1cb..806a9beb15ec60b81f79e45d3060deb60cb9efcb 100644
--- a/lib/modules/manager/bazel-module/fragments.ts
+++ b/lib/modules/manager/bazel-module/fragments.ts
@@ -21,6 +21,11 @@ export const ArrayFragmentSchema = z.object({
   items: LooseArray(PrimitiveFragmentsSchema),
   isComplete: z.boolean(),
 });
+export const StringArrayFragmentSchema = z.object({
+  type: z.literal('array'),
+  items: LooseArray(StringFragmentSchema),
+  isComplete: z.boolean(),
+});
 const ValueFragmentsSchema = z.discriminatedUnion('type', [
   StringFragmentSchema,
   BooleanFragmentSchema,
diff --git a/lib/modules/manager/bazel-module/index.ts b/lib/modules/manager/bazel-module/index.ts
index 021ef601adab08acae79ac8b6f2e352e57bf56e4..d3a8e798591d89d885a27857f543a3be3951a7bc 100644
--- a/lib/modules/manager/bazel-module/index.ts
+++ b/lib/modules/manager/bazel-module/index.ts
@@ -1,6 +1,7 @@
 import type { Category } from '../../../constants';
 import { BazelDatasource } from '../../datasource/bazel';
 import { GithubTagsDatasource } from '../../datasource/github-tags';
+import { MavenDatasource } from '../../datasource/maven';
 import { extractPackageFile } from './extract';
 
 export { extractPackageFile };
@@ -14,4 +15,5 @@ export const categories: Category[] = ['bazel'];
 export const supportedDatasources = [
   BazelDatasource.id,
   GithubTagsDatasource.id,
+  MavenDatasource.id,
 ];
diff --git a/lib/modules/manager/bazel-module/parser/index.spec.ts b/lib/modules/manager/bazel-module/parser/index.spec.ts
index 2424fa8018c4e45125a13de1c037f5b5152f328d..f0137c9f13a09cd8d04c14bb6fd41e7b89b7ef32 100644
--- a/lib/modules/manager/bazel-module/parser/index.spec.ts
+++ b/lib/modules/manager/bazel-module/parser/index.spec.ts
@@ -66,12 +66,12 @@ describe('modules/manager/bazel-module/parser/index', () => {
           {
             rule: fragments.string('git_override'),
             module_name: fragments.string('rules_foo'),
-            remote: fragments.string(
-              'https://github.com/example/rules_foo.git',
-            ),
             commit: fragments.string(
               '6a2c2e22849b3e6b33d5ea9aa72222d4803a986a',
             ),
+            remote: fragments.string(
+              'https://github.com/example/rules_foo.git',
+            ),
           },
           true,
         ),
@@ -167,5 +167,116 @@ describe('modules/manager/bazel-module/parser/index', () => {
         ),
       ]);
     });
+
+    it('finds maven.artifact', () => {
+      const input = codeBlock`
+        maven.artifact(
+            artifact = "core.specs.alpha",
+            exclusions = ["org.clojure:clojure"],
+            group = "org.clojure",
+            version = "0.2.56",
+        )
+
+        maven_1.artifact(
+            artifact = "core.specs.alpha1",
+            group = "org.clojure1",
+            version = "0.2.561",
+        )
+      `;
+      const res = parse(input);
+      expect(res).toEqual([
+        fragments.record(
+          {
+            rule: fragments.string('maven_artifact'),
+            group: fragments.string('org.clojure'),
+            artifact: fragments.string('core.specs.alpha'),
+            version: fragments.string('0.2.56'),
+            exclusions: fragments.array(
+              [
+                {
+                  type: 'string',
+                  value: 'org.clojure:clojure',
+                  isComplete: true,
+                },
+              ],
+              true,
+            ),
+          },
+          true,
+        ),
+        fragments.record(
+          {
+            rule: fragments.string('maven_artifact'),
+            group: fragments.string('org.clojure1'),
+            artifact: fragments.string('core.specs.alpha1'),
+            version: fragments.string('0.2.561'),
+          },
+          true,
+        ),
+      ]);
+    });
+
+    it('finds maven.install and maven.artifact', () => {
+      const input = codeBlock`
+        maven.install(
+            artifacts = [
+                "junit:junit:4.13.2",
+                "com.google.guava:guava:31.1-jre",
+            ],
+            repositories = [
+                "https://repo1.maven.org/maven2/"
+            ]
+        )
+
+        maven.artifact(
+            artifact = "core.specs.alpha",
+            group = "org.clojure",
+            version = "0.2.56",
+        )
+      `;
+      const res = parse(input);
+      expect(res).toEqual([
+        fragments.record(
+          {
+            rule: fragments.string('maven_install'),
+            artifacts: fragments.array(
+              [
+                {
+                  type: 'string',
+                  value: 'junit:junit:4.13.2',
+                  isComplete: true,
+                },
+                {
+                  type: 'string',
+                  value: 'com.google.guava:guava:31.1-jre',
+                  isComplete: true,
+                },
+              ],
+              true,
+            ),
+            repositories: fragments.array(
+              [
+                {
+                  type: 'string',
+                  value: 'https://repo1.maven.org/maven2/',
+                  isComplete: true,
+                },
+              ],
+              true,
+            ),
+          },
+          true,
+        ),
+        fragments.record(
+          {
+            rule: fragments.string('maven_artifact'),
+            group: fragments.string('org.clojure'),
+            artifact: fragments.string('core.specs.alpha'),
+            version: fragments.string('0.2.56'),
+          },
+          true,
+        ),
+      ]);
+    });
   });
 });
diff --git a/lib/modules/manager/bazel-module/parser/index.ts b/lib/modules/manager/bazel-module/parser/index.ts
index e98d997e8754de32aa6c5809b7113a32b0f4153c..0757a63687557b9d0d7a5436f647fbfd865335e6 100644
--- a/lib/modules/manager/bazel-module/parser/index.ts
+++ b/lib/modules/manager/bazel-module/parser/index.ts
@@ -1,9 +1,10 @@
 import { lang, query as q } from 'good-enough-parser';
 import { Ctx } from '../context';
 import type { RecordFragment } from '../fragments';
+import { mavenRules } from './maven';
 import { moduleRules } from './module';
 
-const rule = q.alt<Ctx>(moduleRules);
+const rule = q.alt<Ctx>(moduleRules, mavenRules);
 
 const query = q.tree<Ctx>({
   type: 'root-tree',
diff --git a/lib/modules/manager/bazel-module/parser/maven.ts b/lib/modules/manager/bazel-module/parser/maven.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9248297c9a461392ba030492631c5e05a8983a3f
--- /dev/null
+++ b/lib/modules/manager/bazel-module/parser/maven.ts
@@ -0,0 +1,153 @@
+import { query as q } from 'good-enough-parser';
+import { z } from 'zod';
+import { regEx } from '../../../../util/regex';
+import { MavenDatasource } from '../../../datasource/maven';
+import { id as versioning } from '../../../versioning/gradle';
+import type { PackageDependency } from '../../types';
+import type { Ctx } from '../context';
+import {
+  RecordFragmentSchema,
+  StringArrayFragmentSchema,
+  StringFragmentSchema,
+} from '../fragments';
+
+const artifactMethod = 'artifact';
+const installMethod = 'install';
+const commonDepType = 'maven_install';
+const mavenVariableRegex = regEx(/^maven.*/);
+const bzlmodMavenMethods = [installMethod, artifactMethod];
+const methodRegex = regEx(`^${bzlmodMavenMethods.join('|')}$`);
+
+function getParsedRuleByMethod(method: string): string {
+  return `maven_${method}`;
+}
+
+const ArtifactSpec = z.object({
+  group: z.string(),
+  artifact: z.string(),
+  version: z.string(),
+});
+type ArtifactSpec = z.infer<typeof ArtifactSpec>;
+
+const MavenArtifactTarget = RecordFragmentSchema.extend({
+  children: z.object({
+    rule: StringFragmentSchema.extend({
+      value: z.literal(getParsedRuleByMethod(artifactMethod)),
+    }),
+    artifact: StringFragmentSchema,
+    group: StringFragmentSchema,
+    version: StringFragmentSchema,
+  }),
+}).transform(
+  ({ children: { rule, artifact, group, version } }): PackageDependency[] => [
+    {
+      datasource: MavenDatasource.id,
+      versioning,
+      depName: `${group.value}:${artifact.value}`,
+      currentValue: version.value,
+      depType: rule.value,
+    },
+  ],
+);
+
+const MavenInstallTarget = RecordFragmentSchema.extend({
+  children: z.object({
+    rule: StringFragmentSchema.extend({
+      value: z.literal(getParsedRuleByMethod(installMethod)),
+    }),
+    artifacts: StringArrayFragmentSchema.transform((artifacts) => {
+      const result: ArtifactSpec[] = [];
+      for (const { value } of artifacts.items) {
+        const [group, artifact, version] = value.split(':');
+        if (group && artifact && version) {
+          result.push({ group, artifact, version });
+        }
+      }
+
+      return result;
+    }),
+    repositories: StringArrayFragmentSchema,
+  }),
+}).transform(
+  ({ children: { rule, artifacts, repositories } }): PackageDependency[] =>
+    artifacts.map(({ group, artifact, version: currentValue }) => ({
+      datasource: MavenDatasource.id,
+      versioning,
+      depName: `${group}:${artifact}`,
+      currentValue,
+      depType: rule.value,
+      registryUrls: repositories.items.map((i) => i.value),
+    })),
+);
+
+export const RuleToMavenPackageDep = z.union([
+  MavenArtifactTarget,
+  MavenInstallTarget,
+]);
+
+export function fillRegistryUrls(
+  packageDeps: PackageDependency[][],
+): PackageDependency[] {
+  const artifactRules: PackageDependency[] = [];
+  const registryUrls: string[] = [];
+  const result: PackageDependency[] = [];
+
+  // registry urls are specified only in maven.install, not in maven.artifact
+  packageDeps.flat().forEach((dep) => {
+    if (dep.depType === getParsedRuleByMethod(installMethod)) {
+      if (Array.isArray(dep.registryUrls)) {
+        registryUrls.push(...dep.registryUrls);
+        result.push(dep);
+      }
+    } else if (dep.depType === getParsedRuleByMethod(artifactMethod)) {
+      artifactRules.push(dep);
+    }
+  });
+
+  const uniqUrls = [...new Set(registryUrls)];
+
+  for (const artifactRule of artifactRules) {
+    artifactRule.registryUrls = uniqUrls;
+    artifactRule.depType = commonDepType;
+    result.push(artifactRule);
+  }
+
+  return result;
+}
+
+const kvParams = q
+  .sym<Ctx>((ctx, token) => ctx.startAttribute(token.value))
+  .op('=')
+  .alt(
+    q.str((ctx, token) => ctx.addString(token.value)),
+    q.tree({
+      type: 'wrapped-tree',
+      maxDepth: 1,
+      startsWith: '[',
+      endsWith: ']',
+      postHandler: (ctx) => ctx.endArray(),
+      preHandler: (ctx) => ctx.startArray(),
+      search: q.many(q.str<Ctx>((ctx, token) => ctx.addString(token.value))),
+    }),
+  );
+
+export const mavenRules = q
+  .sym<Ctx>(mavenVariableRegex, (ctx, token) => {
+    return ctx.startRule(token.value);
+  })
+  .op('.')
+  .sym(methodRegex, (ctx, token) => {
+    const rule = ctx.currentRecord.children.rule;
+    if (rule.type === 'string') {
+      rule.value = getParsedRuleByMethod(token.value);
+    }
+    return ctx;
+  })
+  .join(
+    q.tree({
+      type: 'wrapped-tree',
+      maxDepth: 1,
+      search: kvParams,
+      postHandler: (ctx) => ctx.endRule(),
+    }),
+  );
diff --git a/lib/modules/manager/bazel-module/parser/module.ts b/lib/modules/manager/bazel-module/parser/module.ts
index 0c75234b6286204123d00a712e3a3a606e99f81c..ace1d413d7ab8f28db49523ae942f12fa07ae5f6 100644
--- a/lib/modules/manager/bazel-module/parser/module.ts
+++ b/lib/modules/manager/bazel-module/parser/module.ts
@@ -16,6 +16,7 @@ const supportedRulesRegex = regEx(`^${supportedRules.join('|')}$`);
 /**
  * Matches key-value pairs:
  * - `name = "foobar"`
+ * - `name = True`
  **/
 const kvParams = q
   .sym<Ctx>((ctx, token) => ctx.startAttribute(token.value))
@@ -32,6 +33,6 @@ export const moduleRules = q
       type: 'wrapped-tree',
       maxDepth: 1,
       search: kvParams,
-      postHandler: (ctx, tree) => ctx.endRule(),
+      postHandler: (ctx) => ctx.endRule(),
     }),
   );
diff --git a/lib/modules/manager/bazel-module/readme.md b/lib/modules/manager/bazel-module/readme.md
index 6ba11d6580039851cdf43728c95bdacd24bef360..b5b439ba9f0c3696bfbc4493a20685eeae55ab39 100644
--- a/lib/modules/manager/bazel-module/readme.md
+++ b/lib/modules/manager/bazel-module/readme.md
@@ -1 +1,28 @@
 The `bazel-module` manager can update [Bazel module (bzlmod)](https://bazel.build/external/module) enabled workspaces.
+
+It also takes care about maven artifacts initalized with [bzlmod](https://github.com/bazelbuild/rules_jvm_external/blob/master/docs/bzlmod.md). For simplicity the name of extension variable is limited to `maven*`. E.g.:
+
+```
+maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
+```
+
+```
+maven_1 = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
+```
+
+Both `install` and `artifact` methods are supported:
+
+```
+maven.install(
+    artifacts = [
+        "org.seleniumhq.selenium:selenium-java:4.4.0",
+    ],
+)
+
+maven.artifact(
+    artifact = "javapoet",
+    group = "com.squareup",
+    neverlink = True,
+    version = "1.11.1",
+)
+```