XCodebuild test failed `SecKeychainCopyDefault` with -25307 on Github Action

I'm setting up unit tests for my application using Xcode. When I tried to access default keychain on MacOS using SecKeychainCopyDefault, I got error OSStatus -25307, which means "A default keychain could not be found." The tests worked locally, and the issue only happened with Github Actions.

Would anyone have any insight on this issue, or point me to some reading I can refer to? Thanks in advance!

Here is some more tests I've done here. I tried to run "security default-keychain" on GithubAction, and I got

> security default-keychain
    "/Users/runner/Library/Keychains/login.keychain-db"

However, when I tried to start a shell to run the same security command in my unit test, I got

SecKeychainCopyDefault: A default keychain could not be found.

Here is my test calling security command from shell:

    static func run_shell(_ command: String) -> String {
        let task = Process()
        let pipe = Pipe()
        
        task.standardOutput = pipe
        task.standardError = pipe
        task.arguments = ["-c", command]
        task.launchPath = "/bin/zsh"
        task.standardInput = nil
        task.launch()
        
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        let output = String(data: data, encoding: .utf8)!
        
        return output
    }
    
    func testSecurityDefaultKeychain() throws
    {
        print(TLSContextTests.run_shell("security default-keychain"));
    }

Although I’ve not dug into this specific issue (GitHub Actions), I see problems like this all the time. For example, it’s a major focus of my Resolving errSecInternalComponent errors during code signing post.

The default-keychain subcommand is just a wrapper around SecKeychainCopyDefault, which is public API. So you can simplify your test by calling that rather than running security as a child process. If you do that, does SecKeychainCopyDefault also fail?

Share and Enjoy

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

It was still failed. In fact the original issue was exactly SecKeychainCopyDefault failed when I run xcodebuild test.

However, if I ran default-keychain directly in the terminal, it can correctly return the default keychain. Therefore, I'm thinking if that is an issue with xcode setup on the CI host. Would I need to do a code-sign for xcode build?

Reading Resolving errSecInternalComponent errors during code signing, I also tried to run unlock keychain before run my test. As I'm running on Github CI, I dont have the password for the default keychain there. I tested by creating my own keychain like, but unfortunately it did not help.

security create-keychain -p pwd build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p pwd build.keychain

Therefore, I'm thinking if that is an issue with xcode setup on the CI host.

Well, more likely the environment in which the host is running xcodebuild.

I recommend that you escalate this via the support channel for your CI provider. Lots of folks use xcodebuild in lots of different CI environments, so I suspect that there is a way to configure your jobs so that they run in an environment with a keychain. However, I don’t maintain expertise in third-party CI systems, so I have no suggestions as to what that might be.

Share and Enjoy

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

Update: Resolved. It turned out to be an issue for environment variable "HOME". "HOME" was set to a different value in terminal and failed the keychain operation.

XCodebuild test failed `SecKeychainCopyDefault` with -25307 on Github Action
 
 
Q