2026-05-27 12:25:38 -04:00
2026-05-27 12:25:38 -04:00
2026-05-27 12:25:38 -04:00
2023-05-24 23:51:09 -04:00
2023-05-24 23:51:09 -04:00
2026-05-27 12:25:38 -04:00
2026-05-27 12:25:38 -04:00

Ban Maven Plugin

This is a maven plugin that allows developers and organizations to ban Maven artifacts. We are keenly aware of the capability in the maven-enforcer-plugin. Instead of simply generating an error when a banned artifact is referenced, this plugin provides far more features.

  • Prevents the artifact from being downloaded as well.
  • Considers plugins and dependencies of plugins.
  • Externalizes the rules.
  • Supports transitionary cutoff dates.
  • Supports several levels of impact, from informational through hard failures.

This is crucial within certain organizations with strict security scans that crawl the Maven cache.

Extension

The primary use of this plugin is as a Maven extension. When used that way, it will enforce an inspection of the configured dependencies and plugins and recursively their dependencies. See the snippet below for how the plugin should be declared in your project's pom.xml.

<project>
	...
	<build>
		...
		<plugins>
			...
			<plugin>
				<groupId>com.inteligr8</groupId>
				<artifactId>ban-maven-plugin</artifactId>
				<version>2...</version>
				<extensions>true</extensions>
				<configuration>
					...
				</configuration>
			</plugin>
			...
		</plugins>
		...
	</build>
	...
</project>

The extensions elements is critical. Without it, the plugin is unable to prevent the download of violating artifacts. With it, the plugin is able to not only detect violating artifacts, but do it before they are downloaded. This keeps libraries from even reaching your local Maven repository cache. If that is not necessary, you can instead use the inspect goal (see Goals below) of this plugin as one normally would.

A module project will inherit the extensions setting from its parent project. It does not need to be declared in each child/module project for it to be inspected for violations. If it is declared in the parent, but made an extension in the child/module, then it will only be enforced on the child/module project.

If both the parent and child/module projects have configuration elements for this plugin, those configurations are merged.

Configuration

The configuration is defined in the following XSD: ban-config.xsd

Here is a summary of what is defined there:

Element Description
import/file Import a ban configuration file from the project.
import/url Import a ban configuration file from the URL.
import/artifact Import a ban configuration file from the XML artifact of the specified artifact in the GAV notation groupId:artifactId:version.
rules/rule/id The id of a rule to enforce.
rules/rule/cutoff The date of when to switch enforcement from preCutoffBehavior to defaultBehavior.
rules/rule/artifact An artifact to prosecute under the rule in the GAV notation groupId:artifactId:version
defaultBehavior The behavior when a violation is discovered: fail (default), warn, inform, or none.
preCutoffBehavior The behavior when a violation is discovered, but a defined cutoff date is in the future: fail, warn (default), inform, or none.

These values can appear in the configuration element of the plugin. The element is fully inherited from the parent project and profiles as one would expect. The are merged or overridden, where appropriate.

When specifying artifact, you can use any of the following formats. The example is of this library; just replace the values to match the artifacts you want to ban.

  • Exact artifact/version: com.inteligr8:ban-maven-plugin:[1.0.0]
  • Exact artifact; all versions: com.inteligr8:ban-maven-plugin
  • Exact artifact; version range: com.inteligr8:ban-maven-plugin:[,1.4.0)
  • All artifacts/versions in group: org.springframework:
  • All artifacts in group; version range: org.springframework::[,6.0.0)
  • All artifacts in group/subgroups; version range: org.springframework.*::[,6.0.0)

The format is called GAV notation. You may specify a type or classifier and those are supported too: groupId:artifactId:version:type:classifier. When using the colon-based notation, the group ID and artifact ID may be treated as groupIdRegex and artifactIdRegex (see below). If you only use acceptable groupId and artifactId characters (letters/numbers/dashes/underscores/dots), it will not. But if you include any other characters, like \. or *, then it will be treated as regex. How it is treated will impact the functionality of purge-repo goal, if you are using it.

The artifactDescriptor element is available to provide support for longer notation:

<artifactDescriptor>
	<groupId>com.inteligr8</groupId>
	<artifactId>ban-maven-plugin</artifactId>
	<version>[,1.4.0)</version>
</artifactDescriptor>

It also supports the use of regular expressions with groupIdRegex and artifactIdRegex:

<artifactDescriptor>
	<groupId>com.inteligr8</groupId>
	<artifactIdRegex>ban-.+</artifactIdRegex>
	<version>[,1.4.0)</version>
</artifactDescriptor>

If groupId or artifactId or version are not provided, they are ignored in the matching process. So it will match all applicable artifacts and the constraint will be only for what was specified. This means that <artifact>:</artifact> will ban every artifact and all their versions.

If groupId and groupIdRegex are both provided, only groupId is used. The same is true for artifactId and artifactIdRegex. The *Regex element values use standard Java regular expression parsing. If using regular expressions, remember to escape the dots (\.) in group IDs. If you do use groupIdRegex or use regular expressions in the group part of the colon-notation, the matching artifacts will not be purged using the purge-repo goal. So if you intend to use that goal, group ID regular expression matching needs to be avoided.

The version element supports the standard Maven version specification. You can match a specific version like [1.0.0]. Or you can match all versions before 1.2.17 like [,1.2.17). You can match all future versions after 1.2.17 (inclusive) with [1.2.17,). Contrary to popular belief, the bracket-less 1.0.0 is not the same as [1.0.0].

There is nothing stopping you from specifying two artifact elements with the exact same values. So you can ban multiple version ranges of the same artifact by using multiple artifact elements.

Import

The import file, URL, and artifact are to reference XML files that conform to the same configuration element as described here. In fact, the root element of that XML should be configuration. However, it does not support recursive imports.

You can create a Maven pom packaging type project that deploys a configuration XML to your Maven repository. Then use an import to allow you to change banned dependencies without making changes to each individual project. Just like with the version notation in the rule/artifact elements, your import/artifact element supports a version range. This way the latest banned dependencies can be side-loaded into all projects. This means previously functioning builds may eventually start failing. Although that violates general principles, it is necessary in the context of this plugin and hence why it would be used.

The import elements supports multiple url or artifact declarations. It is bad practice and not expected to override a rule, but it may work. Rules are expected to be amendments, not replacements.

Examples

The recommended use of this plugin is for its use across the whole organization. First, you will want a simple Maven project that is referenced by all other Maven projects. That simple project will declare the banned artifacts and potentially purge existing ones. See the examples/ban-config project for a full example.

<configuration
		xmlns="http://inteligr8.com/maven/ban"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://inteligr8.com/maven/ban https://git.inteligr8.com/inteligr8/ban-maven-plugin/raw/branch/develop/src/main/resources/ban-config.xsd">
	<rules>
		<rule>
			<id>CVE-2021-44228</id>
			<artifact>org.apache.logging.log4j::[,2.17.1)</artifact>
			<artifact>log4j:log4j</artifact>
		</rule>
	</rules>
</configuration>

Deploying that project will result in the publication of the ban-config.xml to your Maven repository. That is where it can be picked up by all other projects so they can enforce the ban. If you do not have a local Maven repository, then you will have to upload the ban-config.xml to some other URL-accessible location by some other means.

Once you have that in place, you will want to use the ban file by some means.

Every single Maven project should be governed by the aforementioned ban-config. See the examples/governed-artifact project for a full example. You will want to define the configuration in the build/pluginManagement/plugins element:

<pluginManagement>
	<plugins>
		<plugin>
			<groupId>com.inteligr8</groupId>
			<artifactId>ban-maven-plugin</artifactId>
			<version>...</version>
			<configuration>
				<import>
					<artifact>com.inteligr8:ban-config:[2021.12,)</artifact>
				</import>
			</configuration>
		</plugin>
	</plugins>
</pluginManagmenet>

This is configured to download of the latest version of ban configuration every time it runs. This is typically the desired use case. You'll want to add the plugin to the project.

<plugins>
	<plugin>
		<groupId>com.inteligr8</groupId>
		<artifactId>ban-maven-plugin</artifactId>
		<extensions>true</extensions>
	</plugin>
</plugins>

There is no way to use this at the Maven installation level or through a profile. This is because those don't support configuration elements and profile doesn't support extension plugins. So it needs to be defined in each project.

Goals

Within a project, this is typically only used as an extension with no execution/goal. However, it can be used with executions/goals as well or instead.

inspect

This goal will perform the same actions as outlined above. The only missing feature is that it may download artifacts that are in violation of the rules. However, it will cause the build to fail or notify as configured.

The other difference here is that this executes later than when using <extensions>true</extensions> as specified above. It will instead execute on whichever lifecycle phase the execution is configured to use. This goal binds to the validate lifecycle phase by default.

This goal has the added feature of only being applied to artifacts by scope. By default, it will only apply to compile and runtime scopes. This is useful for the prevention of packaging violating artifacts in EAR, WAR, shaded, or jar-with-dependencies deliverables. Since test and provided scope artifacts should not be packaged, they can be ignored.

You could use both the <extensions>true</extensions> and this goal. The extension configuration might just flag warnings for violating libraries. And this goal would place a hard enforcement on packaged artifacts.

Configuration

The configuration is identical to what is documented above.

The following additional elements/properties are supported:

Element Maven/Java Property Default Description
skip ban.skip false true to skip the inspection.
scopes ban.scopes compile,runtime See description above

Examples

<plugin>
	<groupId>com.inteligr8</groupId>
	<artifactId>ban-maven-plugin</artifactId>
	<configuration>
		...
	</configuration>
	<executions>
		<execution>
			<id>inspect-artifacts</id>
			<phase>pre-package</phase>
			<goals><goal>inspect</goal></goals>
		</execution>
	</executions>
</plugin>

purge-repo

This goal will purge the local Maven repository of prosecuted artifacts. The most common use is without any real project, but Maven requires one to exist in the directory of execution.

This goal binds to the clean lifecycle phase by default.

This goal does NOT support groupIdRegex or blank groupId specifications. So any of those will be ignored and not be purged/removed.

Configuration

The configuration is identical to what is documented above. However, this table focuses on the properties available as you may not be defining this in a pom.xml.

Element Maven/Java Property
import/file ban.file
import/url ban.url
import/artifact ban.artifact

The following additional elements/properties are supported:

Element Maven/Java Property Default Description
skip ban.skip false true to skip the purge.
dryRun ban.dryRun false true to not actually delete any files or directories.
eager ban.eager false true to delete non-artifact (e.g. pom and _remote.repositories) files.

Examples

mvn -Dban.file=ban-config.xml com.inteligr8:ban-maven-plugin:2.0.0:purge-repo clean

Usage

Prevent Banned Artifacts

Here is a pseudo-code example of all the options this plugin provides.

<project>
	...
	<build>
		...
		<plugins>
			...
			<plugin>
				<groupId>com.inteligr8</groupId>
				<artifactId>ban-maven-plugin</artifactId>
				<version>...</version>
				<extensions>true</extensions>
				<configuration>
					<import>
						<file>project-file.xml</file>
						<url>https://host:port/path/file.xml</url>
						<artifact>groupId:artifactId:version</artifact>
					</import>
					<rules>
						<rule>
							<id>CVE-...</id>
							<cutoff>yyyy-MM-dd</cutoff>
							<artifactDescriptor>
								<groupId>...<groupId>
								<artifactId>...<artifactId>
								<version>...</version>
							</artifactDescriptor>
							<artifactDescriptor>
								<groupIdRegex>...<groupIdRegex>
								<artifactIdRegex>...<artifactIdRegex>
								<version>...</version>
							</artifactDescriptor>
							<artifact>com.inteligr8:ban-maven-plugin:[,1.0.0)</artifact>
							<artifact>log4j:log4j</artifact>
							<artifact>org\.springframe.+::[,4.0.0.RELEASE)</artifact>
						</rule>
					</rules>
					<defaultBehavior>fail</defaultBehavior>
					<preCutoffBehavior>warn</preCutoffBehavior>
				</configuration>
			</plugin>
			...
		</plugins>
		...
	</build>
	...
</project>

Purge Banned Artifacts

Here is an example of the non-extension use case for the plugin. You could use the same plugin for both preventing banned artifacts and cleaning up previously downloaded ones. Just set extensions to true in those cases, as highlighted in the previous section.

<project>
	...
	<build>
		...
		<plugins>
			...
			<plugin>
				<groupId>com.inteligr8</groupId>
				<artifactId>ban-maven-plugin</artifactId>
				<version>...</version>
				<configuration>
					...
				</configuration>
				<executions>
					<execution>
						<id>clean</id>
						<phase>clean</phase>
						<goals><goal>purge-repo</goal></goals>
					</execution>
				</executions>
			</plugin>
			...
		</plugins>
		...
	</build>
	...
</project>
Description
No description provided
Readme 20 MiB
Languages
Java 100%