Showing posts with label gpg. Show all posts
Showing posts with label gpg. Show all posts

Friday, October 18, 2013

Signing maven releases with gpg while keeping your passphrase secure

On the road towards putting sample code into Maven Central I stumbled at GPG signatures of my artifacts. The problem was how to handle my passphrase.

The recommended solutions (one source of many) all had shortcomings:

  • Prompting for your passphrase is often unuseful and is broken when running maven in Cygwin.
  • Putting your passphrase on the command-line is visible to ps and is saved in history.
  • Putting your passphrase into {{settings.xml}} leaves it on disk.
  • Putting your passphrase on removable media and linking to it in {{settings.xml}} is awkward.
  • Using a gpg agent would be best, but I did get everything hooked up right; I should investigate further.
  • I will not even entertain removing the passphrase from my secrets just to satisfy maven.

A little think and some trial and error led me to:

  1. In pom.xml enable maven-pgp-plugin and configure maven-release-plugin:
    <plugin>
        <artifactId>maven-release-plugin</artifactId>
        <configuration>
            <arguments>-Dgpg.passphrase=${gpg.passphrase}</arguments>
        </configuration>
    </plugin>
  2. In settings.xml add a profile:
    <profile>
        <id>gpg-sign</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <gpg.passphrase>${env.GPG_PASSPHRASE}</gpg.passphrase>
        </properties>
    </profile>
  3. Write a small helper shell script:
    #!/usr/bin/bash
    
    read -er -p 'Passphrase: ' gpg_passphrase
    echo # Get back newline
    GPG_PASSPHRASE="$gpg_passphrase" exec "$@"

The key observation is that environment variables are private to the process, in memory and transient. I invoke thus:

$ ./rls mvn clean verify
Passphrase:
[INFO] Scanning for projects...