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

Local Network Privacy not Working as Documented

In TN3179 under "macOS considerations" there are a set of instances where local network privacy does not apply:

macOS automatically allows local network access by:

  • Any daemon started by launchd
  • Any program running as root
  • Command-line tools run from Terminal or over SSH, including any child processes they spawn

I am running some tests in my app that use the local network, attempting to run them from both the terminal app and from a VScode terminal and I am getting permissions prompts. After allowing these pop ups, some of the tests still fail as if networking was blocked.

Answered by DTS Engineer in 829676022

The devil is in the details here. First, this:

[quote='776479021, baxterjo, /thread/776479, /profile/baxterjo'] from a VScode terminal and I am getting permissions prompts. [/quote]

A VS Code terminal is not Terminal. The exception carved out for Terminal doesn’t apply to other terminal-ish apps.

What’ll actually happen in the VS Code case is gonna depend on how it implemented its terminal environment. It’s possible that the system will see VS Code as the responsible code for your program and thus VS Code’s Local Network privilege will apply. However, it’s also possible for programs to do things that break that responsibility chain, in which case your program will look like a tool being run in a background context. What happens then is complex.

Regardless, this is something to talk about with the VS Code folks.

Coming back to Terminal, that exception works as documented, at least in my experience. Consider my built copy of the TLSTool sample code:

% codesign -d -vvv `which TLSTool`
…
Authority=Developer ID Application: Quinn Quinn
…

There’s nothing Apple-specific about this; I built it using Xcode and signed it with a Developer ID, just like any developer could.

Running this from Terminal it’s able to connect to a local server just fine:

% TLSTool s_client -connect fluffy.local.:443 -noverify
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: ECDHE_RSA_WITH_AES_256_GCM_SHA384
…
^C

No prompts and no need to grant Terminal the Local Network privilege. This was on macOS 15.3.1, but I’ve run similar tests on many versions of macOS 15 and Terminal has worked reliably on all of them.

Now, it is possible to do things in your code to stop this from working, but it’s hard to list all the possible ways that might happen. My advice is that you try this with a simple test program to see if you can reproduce the problem there. If you can, post some details and I’ll take another look.


Oh, there’s a few other things to check:

  • Make sure your code is signed with a stable code-signing identity, like Apple Development. Strictly speaking I don’t think that’s required in this case, but it’s a good idea generally.

  • Make sure your code has a main executable UUID, as discussed in TN3178: Checking for and resolving build UUID problems. Without that, weird things will happen.

Share and Enjoy

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

The devil is in the details here. First, this:

[quote='776479021, baxterjo, /thread/776479, /profile/baxterjo'] from a VScode terminal and I am getting permissions prompts. [/quote]

A VS Code terminal is not Terminal. The exception carved out for Terminal doesn’t apply to other terminal-ish apps.

What’ll actually happen in the VS Code case is gonna depend on how it implemented its terminal environment. It’s possible that the system will see VS Code as the responsible code for your program and thus VS Code’s Local Network privilege will apply. However, it’s also possible for programs to do things that break that responsibility chain, in which case your program will look like a tool being run in a background context. What happens then is complex.

Regardless, this is something to talk about with the VS Code folks.

Coming back to Terminal, that exception works as documented, at least in my experience. Consider my built copy of the TLSTool sample code:

% codesign -d -vvv `which TLSTool`
…
Authority=Developer ID Application: Quinn Quinn
…

There’s nothing Apple-specific about this; I built it using Xcode and signed it with a Developer ID, just like any developer could.

Running this from Terminal it’s able to connect to a local server just fine:

% TLSTool s_client -connect fluffy.local.:443 -noverify
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: ECDHE_RSA_WITH_AES_256_GCM_SHA384
…
^C

No prompts and no need to grant Terminal the Local Network privilege. This was on macOS 15.3.1, but I’ve run similar tests on many versions of macOS 15 and Terminal has worked reliably on all of them.

Now, it is possible to do things in your code to stop this from working, but it’s hard to list all the possible ways that might happen. My advice is that you try this with a simple test program to see if you can reproduce the problem there. If you can, post some details and I’ll take another look.


Oh, there’s a few other things to check:

  • Make sure your code is signed with a stable code-signing identity, like Apple Development. Strictly speaking I don’t think that’s required in this case, but it’s a good idea generally.

  • Make sure your code has a main executable UUID, as discussed in TN3178: Checking for and resolving build UUID problems. Without that, weird things will happen.

Share and Enjoy

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

Here is a screenshot of a test I am running from the terminal that uses localhost networking to connect two MQTT brokers running in the same process through a custom networking backend. At the lowest IETF level the custom networking backend is using QUIC (udp). There are some additional mDNS shenanigans going on too, in case multicast is the issue.

I see that this pop up is firewall related, which I'm unsure has to do with the Local Network Privacy feature. But this pop-up is new with the new version of macOS.

Accepted Answer
I see that this pop up is firewall related, which I'm unsure has to do with the Local Network Privacy feature.

This has nothing to do with local network privacy. None of the advice in TN3179 applies to this issue. It’s just a coincidence that we also updated the firewall in macOS 15.

You have two options when it comes to firewall issues:

  • Turn it off.

  • Sign your code correctly.

The firewall isn’t particularly valuable security-wise, so I generally just leave it off. That’s a reasonable option on your development machine, but you will have to solve this problem when you distribute your product because you can’t ask all your users to turn it off.

The firewall tries to remember the user’s choices, so that the user doesn’t have to keep clicking Allow or Deny. To do this is needs to be able to identify the code, so it knows that the current build of your product is the ‘same’ as your previous build. It does this using the product’s code signature [1].

To resolve this issue, sign your code with a stable code-signing identity. I general recommend an Apple Development code-signing identity for day-to-day work. For distribution, you have to use an identity that’s appropriate for your distribution channel [2].

Once your code is signed correctly, the firewall should remember your Allow choice and you won’t see this alert again.

Share and Enjoy

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

[1] I talk about this concept in a lot more detail in TN3127 Inside Code Signing: Requirements.

[2] See Creating distribution-signed code for macOS, and its companion, Packaging Mac software for distribution.

Local Network Privacy not Working as Documented
 
 
Q