My company has recently taken over an open source project originally written by Facebook.

As part of this process, we wanted to also ensure that we had an automated virtual machine process that could quickly clone both private and public repositories from GitHub and setup our build process.

Caching your git username/password

There are several ways to cache your git credentials, but most of them involved writing the username and password to an unencrypted file on disk. This was simply out of the question.

GitHub has a document on how to use osxkeychain helper which is bundled with Xcode (/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-credential-osxkeychain)

While this is helpful, this requires you to initially run git clone and type your username and password. This approach cannot be automated.

Reverse Engineering the process

If you follow the GitHub document, you will find out that in the end it creates an Internet Password item in the login keychain and it has an ACL pointing to the osxkeychain helper tool.

Security command

After playing around with the helper tool, I finally settled on the following:

# Add Github account
/usr/bin/security add-internet-password \
-a "USERNAME" \
-s "github.com" \
-w "PASSWORD" \
-T /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-credential-osxkeychain \
-r "htps" \
login.keychain

Bugs

When originally testing this, I kept getting stuck on http when using the -r flag.

-r protocol     Specify protocol (optional four-character SecProtocolType, e.g. "http", "ftp ")

According to Apple https was a valid protocol type, but when trying this, I received the following error:

Error: four-character types must be exactly 4 characters long.

My co-worker joked and said to type htps and sure enough… it worked.

Snags with Sierra

Unfortunately, while the keychain item looked exactly like the one made with osxkeychain helper, I kept receiving a popup when using git clone. After dumping the keychains I saw the issue:

credential-osxkeychain (OK)
    entry 3:
        authorizations (1): partition_id
        dont-require-password
        description: apple-tool:
        applications: <null>

As of Sierra, Apple added a new partition_id scheme that is honestly still undocumented after a year. You can find people complaining about it on jamfnation, apple discussions, stackoverflow, stackoverflow 2, openradar, github, and github2

Essentially, the partition_id needs to contain apple-tool:, apple: in the description.

After playing around with it for a while, this is what I found worked

/usr/bin/security set-internet-password-partition-list \
-l "github.com" \
-S "apple-tool:,apple:" \
-k "PASSWORD" \
login.keychain

Putting it altogether

Requirements

  • Xcode
  • Xcode Command Line tools
  • Username and Password of the account (preferably in an encrypted data format)

Example Code

# Add Github account credentials
/usr/bin/security add-internet-password \
-a "USERNAME" \
-s "github.com" \
-w "PASSWORD" \
-T /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-credential-osxkeychain \
-r "htps" \
login.keychain

# Set partition_id to prevent Keychain popups
/usr/bin/security set-internet-password-partition-list \
-l "github.com" \
-S "apple-tool:,apple:" \
-k "PASSWORD" \
login.keychain

# Set git to use the login keychain for credentials
/usr/bin/git config \
--global credential.helper osxkeychain

# git clone private repo requiring auth

git clone http://github.com/username/privaterepo.git

Table Of Contents