Skip to content

Instantly share code, notes, and snippets.

@djspiewak
Last active August 29, 2015 14:11
Show Gist options
  • Save djspiewak/d8082be3efeb875acd4d to your computer and use it in GitHub Desktop.
Save djspiewak/d8082be3efeb875acd4d to your computer and use it in GitHub Desktop.

Configuring SBT to use 1Password

  1. Install swig-python
  2. Use pip to install 1pass
  3. Install py-levenshtein to avoid annoying warnings
  4. Locate the nearest 1pass script (note: it may be behind you)
  5. Test 1pass on a random password

Create ~/.sbt/0.13/plugins/OnePassword.scala and enter the following contents:

import sbt._

import java.io.ByteArrayInputStream
import java.nio.charset.StandardCharsets

object OnePassword {

  // alright, let's be real here: this is a security leak. sbt-pgp has the same flaw
  private[this] lazy val password =
	SimpleReader.readLine("1Password Master Password: ", Some('*')) getOrElse error("Must provide a password")

  def apply(zone: String, host: String, user: String, entry: String): Credentials = {
	val onePass = Process("/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/1pass" :: "--no-prompt" :: entry :: Nil)
	val is = new ByteArrayInputStream(password.getBytes(StandardCharsets.UTF_8))

	val lines = (onePass #< is).lines

	Credentials(
	  zone,
	  host,
	  user,
	  lines.last)         // throw an exception if it doesn't work
  }
}

Pay no mind to the dangerous security leak... If it makes you feel better, sbt-pgp leaks credentials in exactly the same way! Of course, your PGP key password isn't quite as sensitive as your 1Password master password, so maybe you should feel better after all.

To configure a set of credentials with a password stored in 1Password, follow this pattern (here is my Sonatype credential entry):

credentials +=
  OnePassword(
	"Sonatype Nexus Repository Manager",
	"oss.sonatype.org",
	"djspiewak",
	"Sonatype")

The "Sonatype" final parameter refers to the name of the 1Password entry which contains my Sonatype password. At present, I do not have a way to derive the username from 1Password, though in theory this is possible.

At present, you are prompted for your master password on startup and on the first time you publish. Ideally, it would only be at the latter time, but I honestly don't know how to do that with SBT plugins. Help appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment