The first time I configured Maven to authenticate against a protected repository manager, I was somewhat disturbed by presence of unencrypted passwords in my home directory. While many of us have grown accustomed to leaving a few unencrypted passwords here or there in a production system, it just didn't seem appropriate to leave a password for something like a repository manager sitting in a known file location (~/.m2/settings.xml). Luckily, Maven provides a very easy method for encrypting passwords. In this post, I'll walk you through the process.
Once you start to use Maven to deploy software to remote repositories and to interact with source control systems directly, you will start to collect a number of passwords in your Maven Settings and without a mechanism for encrypting these passwords, a developer's ~/.m2/settings.xml will quickly become a security risk as it will contain plain-text passwords to source control and repository managers. Maven 2.1 introduced a facility to encrypt passwords in a user's Maven Settings (~/.m2/settings.xml). To do this, you must first create a master password and store this master password in a security-settings.xml file in ~/.m2/settings-security.xml. You can then use this master password to encrypt passwords stored in Maven Settings (~/.m2/settings.xml).
To illustrate this feature, consider the process Maven uses to retrieve an unencrypted server password for a user's Maven Settings as shown in the following figure. A user will reference a named server using an identifier in a project's POM, Maven looks for a matching server in Maven Settings. When it finds a matching server element in Maven Settings, Maven will then use the password associated with that server element and send this password along to the server. The password is stored as plain-text in ~/.m2/settings.xml and it is readily available to anyone who has read access to this file.
Next, consider the process Maven uses to support encrypted passwords as shown in the following figure.
To configure encrypted passwords, create a master password by running mvn -emp or mvn --encrypt-master-password followed by your master password.
$ mvn -emp mypassword {rsB56BJcqoEHZqEZ0R1VR4TIspmODx1Ln8/PVvsgaGw=}
Maven prints out an encrypted copy of the password to standard out. Copy this encrypted password and paste it into a ~/.m2/settings-security.xml file.
<settingsSecurity> <master>{rsB56BJcqoEHZqEZ0R1VR4TIspmODx1Ln8/PVvsgaGw=}</master> </settingsSecurity>
After you have created a master password, you can then encrypt passwords for use in your Maven Settings. To encrypt a password with the master password, run mvn -ep or mvn --encrypt-password. Assume that you have a repository manager and you need to send a username of "deployment" and a password of "qualityFIRST". To encrypt this particular password, you would run the following command:
$ mvn -ep qualityFIRST {uMrbEOEf/VQHnc0W2X49Qab75j9LSTwiM3mg2LCrOzI=}
At this point, copy the encrypted password printed from the output of mvn -ep and paste it into your Maven Settings.
<settings> <servers> <server> <id>nexus</id> <username>deployment</username> <password>{uMrbEOEf/VQHnc0W2X49Qab75j9LSTwiM3mg2LCrOzI=}</password> </server> </servers> ... </settings>
When you run a Maven build that needs to interact with the repository manager, Maven will retrieve the Master password from the ~/.m2/settings-security.xml file and use this master password to decrypt the password stored in your ~/.m2/settings.xml file. Maven will then send the decrypted password to the server.
What does this buy you? It allows you to avoid storing your passwords in ~/.m2/settings.xml as plain-text passwords providing you with the peace of mind that your critical passwords are not being stored, unprotected in a Maven Settings file. Note that this feature does not provide for encryption of the password while it is being sent to the remote server. An enterprising attacker could still capture the password using a network analysis tool.
For an extra level of security, you can encourage your developers to store the encrypted master password on a removable storage device like a USB hard drive. Using this method, a developer would plug a removable drive into a workstation when she wanted to perform a deployment or interact with a remote server. To support this, your ~/.m2/settings-security.xml file would contain a reference to the location of the settings-security.xml file using the relocation element.
<settingsSecurity> <relocation>/Volumes/usb-key/settings-security.xml</relocation> </settingsSecurity>
The developer would then store the settings-security.xml file at /Volumes/usb-key/settings-security.xml which would only be available if the developer were sitting at the workstation.