9.1 KiB
Artifact Ban Maven Plugin
This is a maven plugin that allows for 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 prevents the artifact from being downloaded as well. This is crucial within certain organizations with strict security scans that crawl the Maven cache.
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>
<includes>
<artifact>
<groupId>...<groupId>
<artifactId>...<artifactId>
<version>...</version>
</artifact>
<artifact>
<groupIdRegex>...<groupIdRegex>
<artifactIdRegex>...<artifactIdRegex>
<version>...</version>
</artifact>
<artifact>com.inteligr8:ban-maven-plugin:[,1.0.0)</artifact>
<artifact>log4j:log4j</artifact>
<artifact>org\.springframe.+::[,4.0.0.RELEASE)</artifact>
</includes>
<excludes>
<artifact>
....
</artifact>
</excludes>
</configuration>
</plugin>
...
</plugins>
...
</build>
...
</project>
The extensions
elements is critical. Without it, the plugin does nothing as far as banning artifacts/dependencies. With it, the plugin is able to not only detect banned artifacts, but do it before they are downloaded. This works with both dependencies and plugins. This keeps libraries from even reaching your local Maven repository cache.
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>
The purge-repo
goal will remove all banned artifacts from your local Maven cache. It does not support groupIdRegex
or blank groupId
specifications. So any of those will not be purged/removed.
For instance, you can use the following and expect it to work for preventing and purging banned dependencies and plugins:
<include>
<artifact>
<groupId>...<groupId>
<artifactId>...<artifactId>
<version>...</version>
</artifact>
<artifact>com.inteligr8:ban-maven-plugin:[,1.0.0)</artifact>
<artifact>log4j:log4j</artifact>
</include>
Configuration
If no includes
are provided, then no artifacts will be banned. An included artifact is a banned artifact. An excluded artifact is not banned. It is the opposite of what you may think. If no excludes
are provided, then no banned artifacts are granted an exception.
The artifact
element supports the descriptive groupId
/artifactId
/version
elements or the abbreviated colon-based notation. 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.
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 <includes><artifact>:</artifact></includes>
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 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 be avoided.
The version
element supports the standard Maven 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,)
.
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.
If you include all versions by omitting the version
element, you can still exclude (un-ban) certain versions, like [1.2.17,)
.
Order does not matter. All include specifications are processed, followed by all exclude specifications.
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 elmenet of that XML should be configuration
. It will only support the includes
and excludes
elements. so you cannot do 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 includes
and excludes
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. That is by design in this scenario.
The import
elements supports multiple url
or artifact
declarations. All imported and directly specified include specifications are processed before all exclude specifications. You cannot change an include when importing, but you can add new ones, that may cover more versions; and you can exclude versions that may have been included by the import.
The excludes
element is a way to provide project-by-project exceptions to imported banned artifacts where warranted.
Examples
The recommended use of this plugin is for its use across whole organizations. 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>
<includes>
<!-- CVE-2019-17571 -->
<artifact>org.apache.logging.log4j::[,2.17.1)</artifact>
<artifact>log4j:log4j</artifact>
</includes>
</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 add the following to every single Maven project that should be governed by the aforementioned ban-config
. See the examples/governed-artifact
project for a full example.
<plugin>
<groupId>com.inteligr8</groupId>
<artifactId>ban-maven-plugin</artifactId>
<version>...</version>
<extensions>true</extensions>
<configuration>
<import>
<artifact>com.inteligr8:ban-config:[2025.03,)</artifact>
</import>
</configuration>
</plugin>