Keychain file is suddenly created on root-level instead of user-level

Hi,

I have met with a rather interesting phenomenon today and I couldn't figure out the reason.

As part of a script, I import certificates and for that I create a designated keychain:

security create-keychain -p "" $KEYCHAIN_NAME.keychain-db

This has so far been creating the keychain at the expected location, Users/my-user/Library/Keychains/$KEYCHAIN_NAME.keychain-db.

However, I have noticed that since yesterday, my script has been failing with a

security: SecKeychainCreate XXXXXXXXX.keychain-db: UNIX[Permission denied]

error.

I kept investigating and noticed that the same script as given above, now tries to create the keychain on the /Library/Keychains/$KEYCHAIN_NAME.keychain-db path (the same path where System.keychain is located).

I confirmed this in two ways:

  • running the command with sudo no longer resulted in above UNIX error, instead created it next to the System keychain.
  • locally, I tried to create a keychain with an absolute path, like this: security create-keychain -p 1234 "/Library/Keychains/new.keychain" and got back the same UNIX[Permission denied] error.

I tried to poke around in the man page for security and search online, but found nothing that would mention the default path changing for the security command (because it must be some setting for security, given that a simple XXXX.keychain would be created at ~/Library/Keychain/***.keychain, whichever folder I execute the command from.

Thanks in advance for any advice!

Replies

Based on the open-source code (this make()method is called in SecKeychainCreate()) I understand this must come from either

  • The preference domain being set to the system domain over the user domain, but I don't understand how this could happen, given that there isn't a security command-line-tool equivalent for SecKeychainSetPreferenceDomain().
  • or the user having wrong settings for $HOME or passwd->pw_dir, but we did check these and they seem to be correct.

How are you running this script? From Terminal?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How are you running this script? From Terminal?

It's a shell (bash) executor on a GitLab runner. I don't know if that qualifies as a yes or a no answer here. However it hadn't been showing differences to local Terminal-executed commands so far.

It's a shell (bash) executor on a GitLab runner.

Yeah, so this is something you should escalate with your CI vendor.

My experience is that many CI systems play fast’n’loose with macOS’s execution context rules [1], which results in things like this shell script running in a mixed execution context. When you do that, weird things happen. It’s generally not worth spending time investigating exactly what’s causing those weird things. Rather, it’s better to spend that time working out how to get the code to run in a supported context.

I have more to say about sort of thing in Resolving errSecInternalComponent errors during code signing, which is another common symptom of this problem.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Specifically, and with reference to the Execution Contexts section of Technote 2083 Daemons and Agents, many CI systems change the BSD execution context (UIDs and GIDs) without changing the security context.