Keychain Access From Shell

I have a few scripts which need a password to complete their task. For example I have GeekTool show information extracted from a database, I create new sneakemail addresses from Quicksilver by letting a script simulate the browser session, and I have the TextMate makefile sign updates with a passphrase protected private key.

Mac OS has a keychain which is intended for storing and retrieving passwords in a secure fashion, and this service can fortunately be accessed from shell, so that is what I use for my passwords.

The command to access the keychain is security and it has a manual page. But let me save you some time and give you the gist of it.

The keychain can store different kinds of entries. Generally we are interested in either generic passwords (i.e. with no predetermined purpose) or internet passwords (those which go together with an internet scheme/protocol such as https, sftp, smtp, or similar.)

You can create a new password by launching Keychain Access (located in the Utilities folder) and click the plus button below the right list (showing all your existing keychain items.)

Keychain will ask you for Keychain Item Name, Account Name, and Password. For a generic password, the Keychain Item Name is a textual description of the password (also labeled Where and referred to as the service.) The Account Name is the name we will use to retrieve the password (we can also retrieve by service, or both,) and the Password should be self-explanatory.

After having created a password, let’s say we set the Account Name to test, we can run the following from the shell (Terminal):

security find-generic-password -a test

This dumps the record for the test account, everything except the actual password. To also get the password, we would have to add the -g option:

security find-generic-password -ga test

When you run this command, you will be asked if security should be granted access to the keychain item we created. You can either deny, allow once, or always allow. You can later edit which applications are allowed to access the item from Keychain Access. Locate the item and click the I button below the list (or double click) to alter the settings of the item.

The output from security is however not useable as-is. The output looks something like:

For better or worse, the last line (containing the actual password) is actually written to stderr instead of stdout. This however means, that we can quickly silence all but the last line by redirecting stdout to /dev/null. We redirect stderr to stdout (which is done using 2>&1, meaning redirect file descriptor 2 (stderr) to a duplicate of 1 (stdout)). The ordering here matters, since stderr is redirected to a duplicate of stdout, it is important that we do this redirection before we redirect stdout to /dev/null. So we end up with:

security 2>&1 >/dev/null find-generic-password -ga test

And the result from that is:

password: "the4seasons"

We can pipe the result through a small ruby script to extract the password:

Then whenever we need the password, we can use "$(get_pw)" as placeholder for the actual password.

I mentioned that there is also something called internet passwords. These work the same, but instead the command to retrieve one is find-internet-password and in addition to -a for account (the username) and -s for service (the domain name to which the password is associated) there are a few other options as well, like -r for a four letter protocol “name” (ftp is "ftp " and https is "htps"), -p for path, -P for port, etc.

As with the generic passwords, it is possible to search for a password by only providing one search criterion. For example if you have a PayPal account, you can try this line:

And in case the whitespace gets swallowed when I submit the comment, you can see the script properly formatted here: http://www.macosxhints.com/article.php?story=2003121708324421 Scroll to the bottom of that hint and look for “ssh-askpass”.

It’s too bad this doesn’t work when you’re SSH’ed in… I want to be able to retreive these from my home computer when I’m at work, but I get the error “security: SecKeychainFindInternetPassword: User interaction is not allowed.” when it tries to do the Allow once/Allow always/Deny dialog

Hi - been a while since a post - but im looking to ADD a new item to the keychain through the security command - to be pricise a wireless password. We have 400+ MBP’s and our wireless credentials will change - we want to be able to roll out the wireless password to all these users without having to distribute passwords/get them to do it. ANyone have any idea how we could do this through the ‘Security’ command?

It doesn’t like the ‘Where’ item - which i assume is the SSID or something of the network (These properties are pulled out of keychain access). WHen i remove ‘where’, it compiles ok, but when run it says “Can’t make class key’. Where am I going wrong?