In order to be able to sign Xcode applications it is required to access the certificates for signing. These certificates are stored inside a keychain. The keychain must be open in order to retrieve the certificate for the built application. Typically the xcode-maven-plugin will be used on a continuous-integration infrastructure like e.g. Hudson or Jenkins. As long as the continuous-integration infrastructure is operated in a single node mode it is sufficient to put the certificate into the login keychain of the user that runs the continuous-integration server. The situation becomes difficult when operating continuous-integration servers in the master/slave mode. The preferred way to establish the communication between the master and the slave is ssh. Unfortunatally the keychains are not accessible by default when connecting to a machine using ssh. This page explains how applications can be signed on slaves using the xcode-maven-plugin in a master/slave setup. As already explaind above the challange is to get access to the keychain containing the certificate required for the codesiging.
The steps mentions below refer to Hudson/Jenkins as a build server.
When a slave is started we end up from the technical point of view in a call like
[SSH] Opening SSH connection to <SLAVE>:22. [SSH] Authenticating as <USER_NAME>/******. [SSH] Authentication successful. ... [SSH] Starting slave process: cd '<REMOTE_FS_ROOT>' && java -jar slave.jar
When logging on via SSH the login keychain is not open - even if the same user is logged in with a graphical session on the target machine. In this case triggering an Xcode build for an application leads to:
/usr/bin/codesign --force --sign <IDENTITY> --resource-rules=<RESOURCE_RULES> --entitlements <ENTITLEMENTS> <PATH_TO_APP> <PATH_TO_APP>: User interaction is not allowed. Command /usr/bin/codesign failed with exit code 1
Codesign tries to ask for the keychain password in a modal dialog. This attempt fails since there is no graphical session. This is why we get the "User interaction is not allowed." error message.
The preferred way to open the keychain is during startup of the slave process. But so far there is no known way to open the keychain when the slave process is launched.
The second best way to open the keychain is to unlock it inside the Hudson/Jenkins job. The example code for opening a keychain looks like:
#!/bin/bash ... keychain=<PATH_TO_KEYCHAIN_FILE> # e.g. $HOME/Library/Keychains/login.keychain security unlock-keychain -p "<PASSWORD>" ${keychain} &>/dev/null if [ $? -ne 0 ];then echo "Cannot open keychain ${keychain}" exit 1 fi ...
In order to secure the password contained as plain text in the shell perform the following steps