Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Access Unix Socket from App Sandbox

Hello, I want to access the Docker socket API from inside the macOS App Sandbox. The method queries the API using curl with --unix-socket. However, the Sandbox blocks the request, as shown by the log: curl(22299) deny(1) network-outbound /Users/user/.docker/run/docker.sock Outgoing network traffic is generally allowed, but access to the Docker Unix socket is denied.

Here’s the code I’m using:

private func executeDockerAPI() -> String {
        let process = Process()
        let pipe = Pipe()
        
        process.executableURL = URL(fileURLWithPath: "/usr/bin/curl")
        process.arguments = [
            "--unix-socket", "/Users/user/.docker/run/docker.sock",
            "http://127.0.0.1/containers/json"
        ]
        
        process.standardOutput = pipe
        process.standardError = pipe
        
        do {
            try process.run()
            process.waitUntilExit()
            
            let data = pipe.fileHandleForReading.readDataToEndOfFile()
            if let output = String(data: data, encoding: .utf8) {
                return output
            } else {
                return "Error while decoding"
            }
        } catch {
            return "Error running command: \(error.localizedDescription)"
        }
    }

Is there any entitlement or sandbox configuration I’m missing to allow access to /Users/user/.docker/run/docker.sock from inside the sandbox?

Answered by DTS Engineer in 844170022

Are you sandboxing because you plan to ship on the App Store? Or sandboxing because it’s the right thing to do?

Unix domain sockets are a bit of a weird edge case:

  • You can use them for IPC between different components within your app by placing them in an app group container [1].

  • Otherwise they are blocked by the sandbox as part of its general policy of blocking unmediated IPC between code from different teams.

  • You can’t use a temporary exception entitlement to get around this because of both business and technical limitations:

    • On the business side, App Review generally won’t allow you to use temporary exception entitlements.

    • On the technical side, entitlements like com.apple.security.temporary-exception.files.absolute-path.read-write only work for files and directories; they don’t work for Unix domain sockets.

If you’re sandboxing your product because it’s the right thing to do then you can get around this by moving the code to a non-sandboxed XPC service. I talk more about this in The Case for Sandboxing a Directly Distributed App.

If you’re targeting the Mac App Store then you can’t use that option. Lemme know if that’s the case and we can talk some more.

Share and Enjoy

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

[1] Just use a short app group ID because of the path limits. We recently updated the App Groups Entitlement docs to list these limits.

What do you mean by "the sandbox"?

Do you just mean the Xcode sandbox feature or are you talking about a Mac App Store app? The difference is very important.

Since this path is outside the sandbox, obviously your app (and its child task curl) can't access it. That's the whole point of the sandbox. If this is some purpose-built, quick-n-dirty app, you could probably just give yourself a temporary sandbox exemption. Or just turn off the sandbox.

If this is a Mac App Store app and/or you want to do it the "proper" way, then you'll need a user interface to allow the user to select the socket.

PS: You might also consider ditching curl entirely and just making the connection yourself.

I’m talking about the App Sandbox that I have to enable under Signing & Capabilities for the Mac app I’m developing. I need to keep it enabled because I want to publish the app on the App Store, so simply disabling it isn’t an option.

I recently attended a one-on-one lab, and the engineer mentioned that it’s not necessarily a problem if the file isn’t inside the sandbox (which surprised me a bit). We tried to create a temporary exception for the socket file, but I’m still seeing a deny(1) network-outbound... error. Unfortunately, we weren’t able to resolve the issue during the session, so he recommended that I post the question here in the forum.

When you mention selecting the socket, do you mean creating a bookmark for it?

Are you sandboxing because you plan to ship on the App Store? Or sandboxing because it’s the right thing to do?

Unix domain sockets are a bit of a weird edge case:

  • You can use them for IPC between different components within your app by placing them in an app group container [1].

  • Otherwise they are blocked by the sandbox as part of its general policy of blocking unmediated IPC between code from different teams.

  • You can’t use a temporary exception entitlement to get around this because of both business and technical limitations:

    • On the business side, App Review generally won’t allow you to use temporary exception entitlements.

    • On the technical side, entitlements like com.apple.security.temporary-exception.files.absolute-path.read-write only work for files and directories; they don’t work for Unix domain sockets.

If you’re sandboxing your product because it’s the right thing to do then you can get around this by moving the code to a non-sandboxed XPC service. I talk more about this in The Case for Sandboxing a Directly Distributed App.

If you’re targeting the Mac App Store then you can’t use that option. Lemme know if that’s the case and we can talk some more.

Share and Enjoy

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

[1] Just use a short app group ID because of the path limits. We recently updated the App Groups Entitlement docs to list these limits.

Thanks for the detailed reply. I’m using sandboxing because I’m planning to ship the app on the App Store. More specifically, I’m planning to add functionality to connect to the local socket in one of my existing apps.

Access Unix Socket from App Sandbox
 
 
Q