iPhone VPN Per Domain: Decide Where the Refusal Happens
NeverConnect stops the VPN from starting; it does not block a website. Decide whether the refusal belongs at the service boundary or in a managed policy.
Two requirements get written down as one sentence and then implemented in completely different places. This site must only be reachable over the VPN is a statement about admission, and its natural home is the network in front of the service. This iPhone must never contact that domain directly is a statement about the device, and only a managed client policy can express it. Decide which one you actually have before opening a profile editor.
Two requirements that sound identical
Take the illustrative host records.corp.example. In the admission case you publish it only to addresses behind the VPN, so a direct attempt from a phone on cellular fails at the network while the same request through the tunnel succeeds and still demands a real account login. In the device case the phone may reach the public internet, so the host resolves and answers for anyone, and the only place to stop the attempt is on the device. The service cannot enforce a rule about a request that never reaches it.
Misreading the requirement shows up as a specific deployment. The record is still public, the operator believes the VPN is mandatory, and an audit of a cellular attempt shows the request never entered the tunnel. Nothing in the logs looks broken, because nothing was blocked.
Read the evaluation actions literally
The on-demand machinery has two distinct layers of actions, and conflating them produces most of the confusion here. The outer rule action decides what happens to the tunnel when the rule matches, and the connection-evaluation action decides what happens to a hostname match inside an evaluation rule. Apple's Never Connect reference describes only the second layer.
| Layer | Action | What it controls |
|---|---|---|
| Outer rule | connect | Bring the tunnel up when the rule matches |
| Outer rule | disconnect | Tear the tunnel down when the rule matches |
| Outer rule | evaluateConnection | Run a hostname evaluation instead of acting directly |
| Outer rule | ignore | Leave the current tunnel state alone |
| Connection evaluation | connectIfNeeded | Start the tunnel when the hostname cannot be resolved |
| Connection evaluation | neverConnect | Do not start the tunnel for that match |
neverConnect is the value that gets misread most often, because the name suggests a block. It governs starting the tunnel for a matched hostname, not the phone permission to reach a name, so a Never Connect entry is not a domain block. Labelling it that way in a design document is how a deployment gets approved with an enforcement boundary it does not have.
When you own the service, enforce at the boundary
Restricting admission means publishing the name only where the VPN path can reach it, then testing that the intended path works and another path does not. Cover every published record, both address families if you publish them, and any intermediate or alternate name the app uses. An old CNAME still pointing at a public load balancer keeps the direct path alive no matter how tidy the main record is.
This protects the service rather than the device. It does not stop the phone from sending a DNS query, and it does not stop the app from trying. If those attempts are acceptable, boundary enforcement is the cheaper and more durable choice, because it holds for every client instead of only the ones you configured. It also survives a phone that was never enrolled.
When the phone must not even try, you need a managed policy
Stopping the attempt needs a supported enforcement policy that covers the app or destinations before connection, during a tunnel failure, and after a network change. Ask the VPN or device-management provider to name that policy, say whether it requires organisational management, and describe what else it affects. A per-app tunnel plus an on-demand rule is not the same thing, and neither is a home screen shortcut to a connection.
Test the failure case by disabling the tunnel and watching whether the request goes out. If it does, the boundary you documented is not the boundary you deployed.
Decide with three questions
First, do you control the service or only the phone? Second, may the device legitimately use the public internet for everything else? Third, is the phone managed, and by whom? Owning the service plus a managed fleet means either layer is available, while owning only the phone makes the client policy the sole option and it has to be supported.
Answer those three before touching a profile. The configuration then stops being a guess about what a checkbox named Never means.