Skip to content

Maven

The proxy implements the Maven repository protocol, so any client that resolves from a Maven repository can build through ShieldedStack.

Endpoint: <proxy-url>/maven/

Authentication: the API key, sent as the password in HTTP basic auth. The username is not checked; _ is the conventional placeholder.

Configuration below is written for Maven and Gradle. Other clients that resolve from Maven repositories, such as sbt, use the same endpoint and the same key through their own resolver settings.

This route proxies Maven Central. It does not proxy the Gradle Plugin Portal, which Gradle resolves separately.

In ~/.m2/settings.xml:

<settings>
<servers>
<server>
<id>shieldedstack</id>
<username>_</username>
<password>YOUR_API_KEY_HERE</password>
</server>
</servers>
<mirrors>
<mirror>
<id>shieldedstack</id>
<name>ShieldedStack Maven Proxy</name>
<url>PROXY_URL/maven/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
</settings>

Replace PROXY_URL with the base URL. The samples on this page use a bare PROXY_URL rather than <proxy-url> so that the file stays valid XML before you substitute it.

The <id> on the server and the mirror must match, which is how Maven attaches the credentials to the mirror.

<mirrorOf>*</mirrorOf> is what stops repositories declared inside a build from bypassing the proxy. The trade-off is that an artifact the configured upstream does not carry will fail rather than fall back to another repository.

In settings.gradle:

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven {
name = "shieldedstack"
url = uri("<proxy-url>/maven/")
credentials {
username = "_"
password = System.getenv("SHIELDEDSTACK_API_KEY")
}
}
}
}

This governs project dependency repositories in this build only. pluginManagement.repositories, legacy buildscript.repositories, buildSrc, and included builds each have their own repository scope and need reviewing separately. Enforcing this across an organization is a job for a centrally managed init script rather than per-project configuration.

Gradle’s form above already reads the key from the environment, so settings.gradle is safe to commit as written.

For Maven, commit a settings.xml.template that references the environment variable, and generate the real file from it:

<settings>
<servers>
<server>
<id>shieldedstack</id>
<username>_</username>
<password>${env.SHIELDEDSTACK_API_KEY}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>shieldedstack</id>
<url>PROXY_URL/maven/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
</settings>
Terminal window
mvn -q dependency:tree
# or: ./gradlew dependencies

The resolved artifacts appear under Packages in the Control Plane, attributed to the project name on the API key.

401 or 403. Confirm the mirror <id> matches the server <id>, and that the credentials are username: _ with the API key as the password.

Some dependencies still come from elsewhere. Confirm <mirrorOf>*</mirrorOf>. In Gradle, check the scopes FAIL_ON_PROJECT_REPOS does not cover: plugin management, buildscript, buildSrc, and included builds.

Diagnosing a resolution failure. mvn -X dependency:tree for Maven. For Gradle, ./gradlew dependencies --info, which reports repository failures without printing credentials.