I just spent sometime between 30 minutes and 1 hour convincing the Mac Pro that sits in my office to successfully codesign an iOS app via Bazel. This was after having to update the signing key to a newer one and after rebooting the machine due to the macOS 10.15.5 upgrade—all remotely thanks to COVID-19.

The build of the app was failing with an errSecInternalComponent error printed by codesign. It is not the first time I face this, but in all previous cases, I had either been at the computer to click through security popups, had had functional Chrome Remote Desktop access, or did not have to install a new signing key remotely.

Here are the notes of what I discovered throughout this process in case I face it again in the future.

The first thing I did was distill the problem into a minimal reproduction so I didn’t have to go through the cost of a full build to test if my troubleshooting steps had an effect. This is always a good idea. The following was sufficient to show the problem:

$ rm /tmp/empty
$ touch /tmp/empty
$ codesign --sign "${KEY_SHORT_HASH?}" -v /tmp/empty
/tmp/empty: errSecInternalComponent

And here are the steps to fix it, all from the command line because that’s all I had access to:

  1. Inspect existing identities to find the hash of the expired one:

    $ security find-identity
  2. Delete the expired identity from the login keychain using its long hash, obtained from the step above:

    $ security delete-identity -Z "${LONG_HASH?}"
  3. Download the new identity.p12 file and install it into the system keychain, not the login one:

    $ sudo security import identity.p12 -k /Library/Keychains/System.keychain -P "${PASSPHRASE?}" -T /usr/bin/codesign

    The -T /usr/bin/codesign flag is supposed to make the system trust this tool to access the imported identity without asking for a password… but the system still wants to ask for the password at least once and, as far as I can tell, the only way it has to do so seems to be through the graphical UI.

    Installing the identity into the system keychain side-steps this need to add a password. The rationale I’ve found online is that the SSH daemon is trusted to access this keychain, so given that I’m accessing the machine via SSH, it can get access.

And that’s it. It sounds very simple, right? But I got lost in trying many different things. In particular, I tried:

  1. Locking and unlocking the login keychain via security lock-keychain and security unlock-keychain, as the documentation online says. No luck.

  2. Researching and writing an AppleScript (!) snippet to let me enter the password remotely into the popup window that macOS shows. This didn’t work due to other permissions missing, but it wouldn’t have worked anyway because the calls to codesign from SSH didn’t seem to wait for such popup window.

  3. Trying to recover Chrome Remote Desktop access, which I had enabled before abandoning the office but which stopped working as soon as I rebooted the machine in the past. Apparently you need to physically log in for the daemon to start, and I suspect the macOS upgrades invalidated whatever permissions this needed.

What a waste of time and I’m not even sure this is the right way to go. But for now, it’ll do.