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