codesign fails when started from SSH, succeed in Terminal

Hello,

I am setting up a build (CICD) machine. I create a keychain and imported certificate and my signing key.

I SSH into the machine and run xcodebuild:

security unlock-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN_NAME
xcodebuild build \
           -workspace "$WORKSPACE" \
           -scheme "$SCHEME" \
           -archivePath "$ARCHIVE_PATH" \
           -configuration "$CONFIGURATION"

It fails with

Code Signing /Users/ec2-user/Library/Developer/Xcode/DerivedData/getting_started-cvkdjbhbeisorvewfctokujbqufy/Build/Products/Release-iphoneos/getting started.app/Frameworks/AWSAuthCore.framework with Identity Apple Distribution: Sebastien Stormacq (56U756R2L2)

/usr/bin/codesign --force --sign 91C0CBE144634D8B64DFE0AD1676BF956C40D051  --preserve-metadata=identifier,entitlements '/Users/ec2-user/Library/Developer/Xcode/DerivedData/getting_started-cvkdjbhbeisorvewfctokujbqufy/Build/Products/Release-iphoneos/getting started.app/Frameworks/AWSAuthCore.framework'

Warning: unable to build chain to self-signed root for signer "Apple Distribution: Sebastien Stormacq (56U756R2L2)"

/Users/ec2-user/Library/Developer/Xcode/DerivedData/getting_started-cvkdjbhbeisorvewfctokujbqufy/Build/Products/Release-iphoneos/getting started.app/Frameworks/AWSAuthCore.framework: errSecInternalComponent

Notice these two lines

  • Warning: unable to build chain to self-signed root for signer "Apple Distribution: Sebastien Stormacq (56U756R2L2)"
  • errSecInternalComponent

I start a GUI session on the same machine, with the same user. I open a Terminal and type the exact same command

security unlock-keychain -p Passw0rd dev.keychain

xcodebuild build \
           -workspace "$WORKSPACE" \
           -scheme "$SCHEME" \
           -archivePath "$ARCHIVE_PATH" \
           -configuration "$CONFIGURATION"

the code signing succeeds with

** BUILD SUCCEEDED **

I think this indicates the keychain and signing certificate are correct, I still double checked :

  • All certificates, including the intermediate AppleWWDRCAGA3.cer, are in the keychain.
  • All certificates have "Use System default" as trust.
security dump-keychain | grep -i alis 

    "alis"<blob>="Apple Worldwide Developer Relations Certification Authority"
    "alis"<blob>="Apple Worldwide Developer Relations Certification Authority"
    "alis"<blob>="Apple Root CA - G2"
    "alis"<blob>="Apple Root CA - G3"
    "alis"<blob>="Apple Development: Sebastien Stormacq (UF9TVM4GSV)"
    "alis"<blob>="Apple Distribution: Sebastien Stormacq (56U756R2L2)"
    "alis"<blob>="Apple iPhone Certification Authority"
    "alis"<blob>="Apple iPhone OS Provisioning Profile Signing"
    "alis"<blob>="Apple Root CA"

What is different between SSH session and GUI Terminal session ?

Answered by sebsto in 689270022

I found a workaround but I don't understand the root cause.

Instead of installing the Apple WWDR G3 intermediate certificate in the keychain I am building dynamically at run time with

if [ ! -f $CERTIFICATES_DIR/AppleWWDRCAG3.cer ]; then
    echo "Downloadind Apple Worlwide Developer Relation GA3 certificate"
    curl -s -o $CERTIFICATES_DIR/AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
fi
echo "Installing Apple Worlwide Developer Relation GA3 certificate"
security import $CERTIFICATES_DIR/AppleWWDRCAG3.cer -t cert -k "${KEYCHAIN_NAME}" "${AUTHORISATION[@]}"

I now install the certificate in the System keychain. This is the only extra certificate I do install. When in System keychain, it is correctly picked up by codesign, not when it is in my custom (unlocked) keychain.

if [ ! -f $CERTIFICATES_DIR/AppleWWDRCAG3.cer ]; then
    echo "Downloadind Apple Worlwide Developer Relation GA3 certificate"
    curl -s -o $CERTIFICATES_DIR/AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
fi
echo "Installing Apple Worlwide Developer Relation GA3 certificate into System keychain"
SYSTEM_KEYCHAIN=/Library/Keychains/System.keychain
sudo security import $CERTIFICATES_DIR/AppleWWDRCAG3.cer -t cert -k "${SYSTEM_KEYCHAIN}" "${AUTHORISATION[@]}"
Accepted Answer

I found a workaround but I don't understand the root cause.

Instead of installing the Apple WWDR G3 intermediate certificate in the keychain I am building dynamically at run time with

if [ ! -f $CERTIFICATES_DIR/AppleWWDRCAG3.cer ]; then
    echo "Downloadind Apple Worlwide Developer Relation GA3 certificate"
    curl -s -o $CERTIFICATES_DIR/AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
fi
echo "Installing Apple Worlwide Developer Relation GA3 certificate"
security import $CERTIFICATES_DIR/AppleWWDRCAG3.cer -t cert -k "${KEYCHAIN_NAME}" "${AUTHORISATION[@]}"

I now install the certificate in the System keychain. This is the only extra certificate I do install. When in System keychain, it is correctly picked up by codesign, not when it is in my custom (unlocked) keychain.

if [ ! -f $CERTIFICATES_DIR/AppleWWDRCAG3.cer ]; then
    echo "Downloadind Apple Worlwide Developer Relation GA3 certificate"
    curl -s -o $CERTIFICATES_DIR/AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
fi
echo "Installing Apple Worlwide Developer Relation GA3 certificate into System keychain"
SYSTEM_KEYCHAIN=/Library/Keychains/System.keychain
sudo security import $CERTIFICATES_DIR/AppleWWDRCAG3.cer -t cert -k "${SYSTEM_KEYCHAIN}" "${AUTHORISATION[@]}"

What is different between SSH session and GUI Terminal session ?

The main difference is that the login keychain is unlocked. You can do the same thing by unlocking the login keychain in your ssh session.

However, what I don't know -- and would really like to know -- is what codesign is looking for in the login keychain that isn't in the other keychain. So I could move it to that keychain and not have to worry about the login one for building.

codesign fails when started from SSH, succeed in Terminal
 
 
Q