Swift build differs from xcode build

I am writing a command-line tool for macOS that uses AuthorizationServices to authorize the user and perform certain tasks as root. Unfortunately, using AuthorizationServices with the binary created from command line via swift build fails with an internal error -60008. Yet, the same project works just fine when it is built with Xcode.

At first, I thought this is due to some code signing issues. So, I tried to sign it with a valid codesigning identity and com.apple.security.authorization entitlement, but it did not fix the issue. I also checked the codesigning information of both binaries and there seems to be only minor differences:

Xcode build has no entitlements and has linker-signed flag:

CodeDirectory v=20400 size=18814 flags=0x20002(adhoc,linker-signed) hashes=585+0 location=embedded

Swift build has entitlement, although it is basically empty, and has no linker-signed flag:

CodeDirectory v=20400 size=18887 flags=0x2(adhoc) hashes=579+7 location=embedded

Are there any meaningful differences between the xcode builds and swift package manager builds? How can I fix the swift build such that the AuthorizationServices works there as well?

Unfortunately, there are not many (if any) resources out there to guide me through this. So, I decided to ask here.

Here is the link to the project, in case you wanted to build it: GitHub - seinmon/scrub: Simple macOS cleaner

Thanks

Wow, that’s a classic example of the cause being far removed from the symptoms.

Error -60008 is errAuthorizationInternal, which does indeed suggest that this is problem with the way that your executable is built. However, that’s not the case. Rather, it’s a problem with where your executable is stored.

To investigate this I created my own test package that reproduces the problem:

% cat Package.swift 
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "TestAuthorizationServices",
    platforms: [.macOS(.v14)],
    products: [
        .executable(
            name: "TestAuthorizationServicesTool",
            targets: ["TestAuthorizationServicesTool"]
        ),
    ],
    dependencies: [],
    targets: [
        .executableTarget(
            name: "TestAuthorizationServicesTool",
            dependencies: [],
        ),
    ]
)
% cat Sources/TestAuthorizationServicesTool/main.swift 
import Security

func main() {
    print("Hello Cruel World!")
    var refQ: AuthorizationRef? = nil
    let err = AuthorizationCreate(nil, nil, [], &refQ)
    print(err)
}

main()
% swift build   
…
% swift run
…
Hello Cruel World!
-60008

I originally thought it might be caused by the swift run runtime environment, so I tried running it straight from Terminal.

% .build/arm64-apple-macosx/debug/TestAuthorizationServicesTool
Hello Cruel World!
-60008

No dice! But check this out:

% mv .build/arm64-apple-macosx/debug/TestAuthorizationServicesTool ~
% ~/TestAuthorizationServicesTool 
Hello Cruel World!
0

Simply moving the tool to ~ causes it work correctly. I tried this based on this system log entry

type: error
time: 2025-06-30 08:46:41.045994 +0100
process: kernel
category: <Missing Description>
message: System Policy: authd(439) deny(1) file-read-data /Users/quinn/Desktop/TestAuthorizationServices

It seems that Authorization Services XPCs over to authd which tries to read the executable’s code signature. When you build with Xcode, that works because the executable is in ~/Library. However, when you build with Swift Package Manager the executable goes into the local .build directory. In my case that was on the desktop, which is protected by MAC [1]. So authd can’t read the code signature and thus Authorization Services fails with this error.

If I move my package directory to ~:

% pwd
/Users/quinn/TestAuthorizationServices

then everything Just Works™:

% swift package clean
% swift run        
Building for debugging...
…
Hello Cruel World!
0

And that’s my general advice here. Don’t store source code in locations protected by MAC. It causes all sorts of weird problems.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

[1] See On File System Permissions.

4 Likes

Thank you Eskimo! I moved the binary and it works now!

I wish this was mentioned in the Authorization Services documentations. You have no idea how much time I spent trying to debug this thing.

Anyways, thank you again for your help.

I wish this was mentioned in the Authorization Services documentations.

IMO this falls more under the category of bug than documented behaviour. Either way, you should feel free to file a bug about this, either against the docs or the implementation depending on which camp you fall in to.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like