Storing plaintext passwords in Maven's settings.xml is a known risk. Tools that read the file, LLMs that process it, and remote code execution vulnerabilities can all expose credentials that were meant to stay private. Locksmith, a Maven extension from developer exabrial, removes those passwords from the file entirely by reading them from the macOS Keychain at build time, or deferring to a Unix socket when the Keychain is not available.
The Problem Locksmith Solves
Maven's settings.xml stores server credentials for repositories, distribution targets, and deployment endpoints. In a typical configuration, these are plaintext passwords. For teams in regulated industries, this creates a compliance problem: the file must exist on disk, but the passwords in it must not be recoverable by other software on the machine.
Locksmith replaces the plaintext password with a reference to a Keychain entry. The format is a structured string that tells Maven's security dispatcher to call the Locksmith decryptor instead of using the password directly. The actual password never appears in the file. A FIPS-140 auditor sees a Keychain reference, not a credential.
How the Integration Works
At startup, Maven loads all jars in its lib/ext directory. Sisu, Maven's dependency injection framework, discovers the LocksmithPasswordDecryptor component from the extension jar. When Maven encounters a password with the type=locksmith attribute in settings.xml, the DefaultSecDispatcher routes the decryption request to Locksmith.
The core library reads the password from the macOS Keychain using Java's Panama Foreign Function and Memory API. This requires Java 25 or later. The Keychain access is a standard security prompt: on first use, macOS asks for the login keychain password. After that, the build proceeds without any plaintext credentials on disk.
The extension must be configured through a settings-security.xml file. Maven's DefaultSecDispatcher checks for this file before invoking any custom PasswordDecryptors. Locksmith's installation script creates a minimal settings-security.xml if one does not already exist, making the setup transparent to existing projects.
Remote Builds and the Unix Socket Fallback
On Linux, where the macOS Keychain is not available, Locksmith defers to a Unix socket. The common use case is remote builds over SSH. A shell script agent runs on the Mac, listens on a socket, and answers Keychain lookups. SSH forwards that socket to the remote build machine. The build agent on the remote side sends a service/account request over the socket, the local agent calls security find-generic-password, and the password flows back without ever being stored on the remote machine.
Locksmith checks for the socket in a specific order: the LOCKSMITH_SOCK environment variable first, then $XDG_RUNTIME_DIR/locksmith.sock on Linux, then $HOME/.locksmith/locksmith.sock on macOS. The first path that exists wins. This makes it straightforward to override the default in environments where the standard paths do not apply.
The launchd agent setup is documented in detail. The agent uses socket activation, so it starts on demand when a connection arrives. The SSH config section shows how to forward the socket from the local machine to the remote build host, using the remote user's UID to construct the correct path.
Two Modes: Extension and Plugin
The Maven Core Extension handles server passwords in settings.xml. This covers repository authentication, distribution management, and wagon credentials. It runs automatically at startup with no per-project configuration required beyond the extension jar and settings-security.xml.
The Maven Plugin handles cases where a password is needed as a Maven project property during the build. It reads the password from the Keychain during the validate phase and exposes it as a property that subsequent plugins can reference. This is useful when a third-party plugin expects a credential in a property rather than in the server configuration.
Both modes use the same core library. The extension and plugin are separate jars, but they share the Keychain and socket reading logic.
Installation and Verification
Global installation puts the extension jar in Maven's lib/ext folder. The recommended approach downloads the jar, verifies its GPG signature against a published key, and moves it into place. The verification step uses a key on keys.openpgp.org, and the download script stages everything in a temporary directory before moving the jar to its final location.
Project-local installation uses .mvn/extensions.xml to declare the extension. This method does not require a global install and keeps the extension version tied to the project. The tradeoff is that every developer working on the project must have the extension configured, either through the global install or through the project's extensions file.
The project is available on Maven Central under the com.github.exabrial.locksmith groupId. Version 1.1.0 is the current release. The codebase is open source on GitHub under exabrial/locksmith.