How Maven's Encryption (mvnenc) Works for Passwords: A Technical Deep Dive

Maven's mvnenc command-line tool encrypts passwords using AES-256-CBC with PKCS5Padding, storing a master key in settings-security.xml and wrapping encrypted values in {ENC} tokens that DefaultSettingsDecrypter or Maven 4's SecDispatcher transparently decrypt at runtime.

The mvnenc utility is Apache Maven's dedicated workstation-level password management solution, replacing the legacy settings-security.xml handling tied to Maven 3's SecDispatcher. According to the apache/maven source code, this tool operates as a specialized CLI invoker that validates goals and delegates cryptographic operations to specific goal implementations under org.apache.maven.cling.invoker.mvnenc.

The Encryption Architecture and Entry Points

The EncryptInvoker Entry Point

The mvnenc command resolves to EncryptInvoker at org.apache.maven.cling.invoker.mvnenc.EncryptInvoker. Its execute() method validates that exactly one goal is supplied (either init, encrypt, decrypt, or diag), then forwards the request to the corresponding Goal implementation.

// From EncryptInvoker.java
public int execute(InvokerRequest request) throws Exception {
    // Validates single goal and dispatches to Init, Encrypt, Decrypt, or Diag
}

Exit codes are defined as constants in this class: OK, ERROR, BAD_OPERATION, and CANCELED.

Command Parsing and Context Creation

Before cryptographic operations begin, EncryptParser parses the CLI into an EncryptOptions object. This value object holds:

  • The selected goal
  • Optional master-password file paths
  • Flags like --show-errors

The EncryptContext class then bundles the InvokerRequest, parsed options, a JLine Terminal, and a LineReader for handling interactive password prompts without echoing to the console.

The Four Core Goals: init, encrypt, decrypt, and diag

Init: Generating the Master Encryption Key

The Init goal (org.apache.maven.cling.invoker.mvnenc.goals.Init) creates a random 256-bit AES key that serves as the master password for the workstation. This key is base64-encoded and written to $HOME/.m2/.mvn/settings-security.xml inside a <master>{…}</master> element.

This file is created once per workstation and is required before any password encryption can occur.

Encrypt: Securing Passwords with AES-CBC

The Encrypt goal (org.apache.maven.cling.invoker.mvnenc.goals.Encrypt) handles the actual password protection:

  1. Input Collection: Uses ConsolePasswordPrompt (JLine-based) to securely read clear-text passwords without terminal echo
  2. Cryptographic Processing: Encrypts bytes using AES-CBC/PKCS5Padding with the master key
  3. Output Formatting: Base64-encodes the ciphertext and wraps it in the {ENC} prefix

The resulting string (e.g., {ENC}k3J9vE7c2Zp0+...) can be safely stored in settings.xml or other configuration files.

Decrypt: Restoring Clear-Text Passwords

The Decrypt goal reverses the encryption process. It extracts the base64 payload from an {ENC} string, decrypts it using the same master key stored in settings-security.xml, and prints the original clear-text password to stdout.

Diag: Runtime Diagnostics

The Diag goal displays which security implementation is active. It detects whether Maven 4's SecDispatcher is available or if the system will fall back to Maven 3's compatibility layer.

Cryptographic Implementation and Fallback Strategy

The actual encryption/decryption logic delegates to Maven's Settings security component. When Maven 4's SecDispatcher is present, mvnenc uses it directly as the preferred path. If the dispatcher is unavailable (e.g., on older Java runtimes), the tool falls back to org.apache.maven.settings.crypto.DefaultSettingsDecrypter.

This fallback mechanism ensures backward compatibility while allowing Maven 4 to use modern security implementations. The diagnostic output from mvnenc diag indicates which path is active.

Practical Workflow Examples

Initialize the master password store (run once per workstation):

mvnenc init

# Creates $HOME/.m2/.mvn/settings-security.xml

Encrypt a password interactively:

mvnenc encrypt
Password: ********

# Output: {ENC}k3J9vE7c2Zp0+...

Encrypt non-interactively for scripts:

echo "mySecret" | mvnenc encrypt -q
{ENC}k3J9vE7c2Zp0+...

Decrypt an existing value:

mvnenc decrypt -p "{ENC}k3J9vE7c2Zp0+..."
mySecret

Check which implementation is available:

mvnenc diag
Maven Encryption is configured.
Using Maven 4 SecDispatcher.

Summary

  • mvnenc is the dedicated CLI tool for Maven password management, replacing legacy Maven 3 security handling
  • Master key storage: 256-bit AES key stored at $HOME/.m2/.mvn/settings-security.xml
  • Encryption algorithm: AES-CBC with PKCS5Padding, base64-encoded and wrapped in {ENC} tokens
  • Core classes: EncryptInvoker, EncryptParser, EncryptContext, and goal implementations (Init, Encrypt, Decrypt, Diag)
  • Fallback support: Automatically uses DefaultSettingsDecrypter when Maven 4's SecDispatcher is unavailable
  • Security: Password input uses JLine ConsolePasswordPrompt to prevent terminal echo

Frequently Asked Questions

Where does mvnenc store the master password?

The master password is stored in $HOME/.m2/.mvn/settings-security.xml as a base64-encoded 256-bit AES key inside a <master> element. This file should be protected with filesystem permissions and never committed to version control.

What encryption algorithm does Maven use for password encryption?

Maven uses AES-256-CBC with PKCS5Padding (AES/CBC/PKCS5Padding). The ciphertext is base64-encoded and prefixed with {ENC} so that Maven's settings decrypter can automatically recognize and decrypt it during the build process.

How does Maven 4 password encryption differ from Maven 3?

Maven 4 introduces the SecDispatcher API, which mvnenc prefers over the legacy DefaultSettingsDecrypter found in Maven 3. If the Maven 4 dispatcher is unavailable, the tool automatically falls back to the Maven 3 compatibility layer without user intervention.

Can mvnenc encrypt passwords without interactive prompting?

Yes. You can pipe the password to mvnenc encrypt using standard input redirection: echo "password" | mvnenc encrypt -q. The -q (quiet) flag suppresses interactive prompts, making the tool suitable for CI/CD pipelines and automation scripts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →