When setting up Jenkins to sign a build product using GnuPG the signing operation might stall, since pinentry-mac can't retrieve the private key passphrase from macOS Keychain Access. The only way to fix this so far, was to login to the signing user account and run the command manually in Terminal once, so the macOS Keychain Access password prompt is displayed and one can choose to never ask again and have the pinentry-mac.app application added to the list where no user password is required to retrieve the passphrase. This is very cumbersome if the server taking care of the signing is only accessible via SSH.
What's even stranger is, that trying to add the keychain item manually using, which should grant access to the item without asking for the user's password via UI:
security add-generic-password -a "<fingerprint>" -l "<somelabel>" -s "GnuPG" -T "/usr/local/MacGPG2/libexec/pinentry-mac.app" -w "passphrase" <keychain>
Turns out -T path/to/application
is no longer enough. A few macOS versions ago a concept was introduced called partition lists. Partition lists are now responsible for telling keychain with which team identifier the application being granted access to has to be signed.
If for example an apple application like codesign
should be allowed access without asking for the user's password via UI, the partition list has to include: apple:
For GPGTools signed binaries like pinentry-mac.app
the partition list has to include: teamid:PKV8ZPD836
Luckily for us, the security
command can be used to alter the partition lists from terminal:
security set-generic-password-partition-list -a "<fingerprint>" -S "apple-tool:,teamid:PKV8ZPD836" <keychain>
Note: apple-tool:
is necessary to remain in the partition as otherwise macOS Keychain Access loses the capability to modify the keychain item
In the past the same problem occurred when Jenkins tried to sign an app via codesign, as macOS Keychain Access wouldn't grant access to the private key without asking for the user's password.
In order for codesign to allow direct access to the Developer ID private key, the partition list has to contain: apple:
The command is not exactly the same, but very similar:
security set-key-partition-list -l "<label>" -S "apple-tool:,apple:" <keychain>
<label>
is the name of the private key, usually something like Mac Developer: Name (Identifier)