Tours

The macOS app, in depth

15 min readView as markdown ↗

URnetwork on the Mac is built from the same Xcode project as the iPhone and iPad app: one codebase, one engine, two window shapes. You use it like a VPN (connect, and your traffic appears from somewhere else), but it exits through real home connections shared by other members, not through datacenters. This tour covers the Mac-shaped parts in full and walks the shared features with enough depth to use them; where the behavior is identical to iOS, the iOS tour has the exhaustive version. For install and first connect, see getting started on macOS; for what member-run exits change, the overview.

How the app is built

Two processes, like every serious VPN on Apple platforms:

  • The app (bundle network.ur) is the window and menu-bar extra.
  • The tunnel extension (network.ur.extension) is an NEPacketTunnelProvider network extension that macOS starts and supervises. Your traffic moves through this process, which means your protection never depends on the window being open.

The app talks to the tunnel over a local device RPC (a private control channel between the two processes), so it can attach to a tunnel that is already running. Quit and reopen the app mid-session, or crash it, and it adopts the live tunnel rather than restarting it. This is also why macOS asks you to approve a VPN configuration on first connect: the extension is a system-managed component, and the OS requires consent.

The app requires macOS 13.5 or later, and everything is open source at github.com/urnetwork, so claims like "the data path logs nothing" can be checked in code rather than taken on trust. No independent audit covers the protocol or the operator's server code, where the privacy claims live. Two 2025 third-party assessments cover other surfaces: a penetration test of the web application and API, and a Leviathan Security Group MASA AL2 assessment of the Android app, which passed. Neither covers the Mac app. The threat model records both and their limits.

The window: a sidebar with four sections

The main window is a split view. The sidebar has the same four sections as the iOS tabs (Connect, Account, Leaderboard, Support), with the selected section filling the rest of the window.

Connect

The big globe is the connect button. The status line under it reads Connected to N providers, and clicking that line opens Provider Locations: a spinnable globe over the list of providers actually carrying you right now. Expect several at once, commonly three to eight. Your client runs two sets side by side (a quality set for HTTPS, a speed set for everything else) and pins each site to one provider, so the picture is plural by design while any single site still sees one stable address. Slow or vanished providers are replaced automatically; one going offline mid-stream costs at most a brief stall while that site moves to another in your set, and if a whole session drags, reconnect to draw a fresh set. The overview explains the path each connection takes, why it stops at four legs, and what each party along it can and cannot see.

Below the globe sits the details drawer: your selected location, Connect options (connection mode, Fixed IP, Strong Anonymization, Post Quantum Encryption), the Remote / Blocked / Local stats cards that open client contracts, split rules and the DNS panel, and the Block ads and trackers toggle. Provide mode is not here. It lives in Account → Settings.

SettingDefaultEffectMain cost
Connection modeAutoAuto runs both provider sets and routes each packet to the fitting oneWeb or Streaming commit to a single set
Fixed IPOffNarrows the window to one provider, so every site sees one steady addressGives up the plural exit
Strong AnonymizationOnForbids a direct client-to-provider path, so a provider never sees your real IPSlower than the direct path
Post Quantum EncryptionOnSeals the session end to end to the provider, so the operator carries ciphertextSkips providers it cannot seal with
Block ads and trackersOffFilters ads and trackers out of everything the tunnel carriesFiltering is tunnel-wide, not per-app
  • Turning Strong Anonymization off is direct mode: faster, and that provider then sees your real address.
  • The seal is fail-closed. While Post Quantum Encryption is on, the client will not send or accept application data in the clear: a provider it cannot establish a sealed session with is skipped, not used unsealed. The cost is availability, not confidentiality — you lose that provider, not your encryption. Every current provider build speaks the responder side, so that is uncommon. Switch the setting off and traffic can take the standard path again. No app yet shows a per-connection sealed-or-not verdict.

A provider is another member's real connection; the platform is the operator in between, matching you to them. A provider sees where the traffic it carries goes, the view your ISP has of you today, but not what is inside, because nearly every site seals its own contents with HTTPS. By default it never learns your real IP, which stays with the platform. The platform, in turn, keeps almost nothing: your address is held as a keyed one-way hash (scrambled with one secret key, not reversible) of its surrounding address block rather than the address itself, and the transfer ledger records byte counts between client ids, never the sites you visit. A geographic lookup does file an approximate city against each connection, so the coarse where is known; the what never is. With both defaults on, a provider never learns who you are and the operator cannot read what you send, so no single party holds both your identity and your activity.

ModeOperator seesProvider seesDefault and availability
Relayed sealedyour account and source connection, which providers you are on, and ciphertext with its timing and volumedestinations it egresses and a device/contract id, not your real IPthe shipped default: Post Quantum Encryption, on in the connect drawer
Relayed standardyour account and source connection, which providers you are on, and the destinations and packet bytes insidedestinations it egresses and a device/contract id, not your real IPonly with Post Quantum Encryption switched off
Directless relay involvementyour real IP and the destinations it egressesopt-in: switch off Strong Anonymization

Limit: nothing verifies that the providers offered to you are independent of each other or of the operator, and the operator can run providers itself. The threat model works these rows against named adversaries, including a hostile operator, and is explicit about where each one fails.

Click the location card and the provider list opens. On the Mac it slides in as a panel beside the connect view rather than a sheet, and the toolbar's Show Provider List button toggles it too. Browsing it lists countries, each with a live count of providers online; type a place name into Search providers and a Cities section appears in the results. City-level targeting is something you search for, not scroll to. Every location is a member's device physically there: the platform geolocates the connection it observes, and an address that looks like a datacenter or a VPN is demoted rather than trusted. "Best available" optimizes for speed near you; a specific location makes you appear there.

Account

Identity and plan live here:

  • Plan. Free is a real daily data allowance; UR Pro is a large monthly one at $5/month or $40/year. Current numbers at ur.io/products.
  • Your providing activity. Where sharing is set up, with what yours has carried itemized. Settings links it as "Uses the UR Protocol"; ur.xyz documents how the rewards for participating work.
  • Balance codes. One-time data top-ups: a gift card for data, no subscription attached.
  • Blocked locations. Countries you never want to exit through.
  • Provider identities. The providers your client currently holds a verified sealed session with.
  • The post-quantum identity panel. Covered below.
  • Settings. Where provide mode, the kill switch, blocked locations, start-at-login, your seedphrase and sign-in methods, and account deletion all live.

The Settings toggles at a glance:

SettingDefaultEffectMain cost
Provide modeNeverShares your Mac's spare bandwidth publicly, or with your own devices onlyEvery byte carried counts against an ISP data cap
Kill switchOffRefuses local fallback, so traffic stops rather than leaking when no provider is reachableNo traffic when providers fail
Launch URnetwork on system startupOffStarts the app at login through macOS's own login-items serviceAn entry in System Settings → Login Items

Starting without an email is a first-class path here. Create Instant Account on the login screen makes a real, permanent network in one click, secured by a seedphrase the platform generates and shows once, immediately after creation. Save it: it is the only way back in, the operator keeps only hashed forms of it, and with it saved the account outlives this Mac. Account is then where you can add any other sign-in method (Apple, Google, email or phone, Solana, Bittensor) to that same network, keeping balance and history. An email or phone is your sign-in and recovery path, nothing more, and the seedphrase and wallet paths, with on-chain USDC payment, let an account carry no email, name, or card at all. An auth code generated on any already-signed-in device is the fastest way to bring your Mac onto an existing account.

Leaderboard

Top providers by data moved, never anything about anyone's browsing. Provide from your Mac and you can appear here, publicly by network name or privately, unnamed. If you do not provide, you are simply not on it.

Support

Plans, help, feedback, and community links, with the ability to attach client logs to a report: the normal path when something breaks. Outside the app, feedback.ur.io works from any browser; security findings go to [email protected] under the disclosure policy at ur.io/vdp.

The menu-bar extra

URnetwork also lives in the menu bar, and it is the fastest way to use the app day to day:

  • Status at a glance. Connected and Providing, each with a check or cross.
  • Connect / Disconnect. One click, no window needed.
  • Show. Bring the main window back.
  • Quit URnetwork. Disconnects and exits.

Close the window and the app keeps running in the menu bar; the tunnel keeps running regardless, because it is a separate system-managed process. ⌘Q is deliberately not a quit either: it hides the window and drops the app out of the Dock into the menu bar. Quit URnetwork here is the real exit, and it takes the tunnel down with it.

Shared with iOS: the deep features

These work identically to the iOS app; the iOS tour covers each in full detail.

Custom DNS

A complete DNS panel under Connect. DNS is the internet's phone book (it turns a name like netflix.com into the address your Mac connects to) and a classic place for snooping and blocking by local and regional firewalls. You do not need to touch the panel: the default, encrypted DNS over HTTPS resolved through the tunnel, is already the most secure setting. From there you can switch any combination of DoH (remote/local) and unencrypted DNS (remote/local), edit the resolver lists yourself, and use local DNS fallback, which races a local resolver while the tunnel starts so lookups never stall during the handshake (off means DNS resolves only through the tunnel). The screen offers per-country recommended settings, because some national networks interfere with lookups enough to break the strictest configuration, with one-tap apply and one-tap restore to the secure defaults, plus suggested servers marked in your connected country's color.

Split rules

Route specific traffic outside the tunnel or pin it in place, at the domain and IP level. Tap live traffic to route it locally, the fix when an office intranet, printer, or NAS vanishes behind the tunnel. Or hold a site to a single provider for a stable address, which keeps address-sensitive sites like banks calm; that provider then sees your visits to that one site, still without your identity or content. Rules catch the whole co-associated network cluster, so CDN and subdomain traffic moves together. As on iOS, there is no per-app split tunneling here. Android and Windows have it, but Apple platforms do not give VPN apps a supported per-app hook, so rules on the Mac are network-level.

Provide mode

Sharing your Mac's spare bandwidth (a desktop on a good uplink is exactly the device the network wants) is set in Account → Settings → Connections, where Provide mode is a four-way choice rather than a switch:

ModeWhat it carries
NeverNothing. The default: you are purely a user
AutoPublic traffic while you are connected; only your own devices when you are not
AlwaysPublic traffic, connected or not
NetworkOnly ever your own devices

Public traffic is metered under signed contracts (cryptographic agreements that count bytes between client identities, which is how usage is settled without recording destinations), and providers participate in the UR protocol; ur.xyz documents how the rewards for that participation work.

Safety is engineered on your own machine. The connect engine's open-source inspection layer runs on your Mac at egress and blocks file-sharing (BitTorrent-class) and attack-pattern traffic before it leaves your connection. What a match produces: the packet is dropped, and a file-sharing signature additionally raises an abuse flag to the operator carrying only the sending device's id and a boolean (no destination, no domain, no contents), for which the operator ships no handler today. Attack-pattern and opaque-tunnel drops raise nothing at all. The same filter is why URnetwork is deliberately not a torrenting tool for users. Limit: no shared-exit design makes the risk exactly zero, which is why the audience is yours to choose, and every byte you carry counts against an ISP data cap, so on a metered plan provide selectively or not at all.

The post-quantum identity panel

The setting itself is Post Quantum Encryption, a toggle in the connect drawer under Connect options, and it ships on: sealed is the state a fresh install starts in, not a choice you have to make. Account then shows your client's post-quantum session identity with a share sheet for out-of-band comparison, the same idea as comparing safety numbers in a messaging app: reading the fingerprint over another channel proves the sealed session ends where you think it does. What the setting covers: your client seals traffic directly to a provider using a TLS 1.3 session negotiated with X25519MLKEM768 (hybrid classical + ML-KEM), so the operator in the middle carries bytes it cannot read, and recordings made today are designed to stay sealed even against a future quantum computer (the "harvest now, decrypt later" threat). It is fail-closed: while the setting is on the client will not send or accept application data in the clear, so a provider it cannot establish a sealed session with is skipped rather than used unsealed — you lose that provider, not your encryption. Every current provider build speaks the responder side, so that is uncommon; switch the setting off and traffic can take the standard platform path again. No app yet shows a per-connection sealed-or-not verdict. Identity signatures remain Ed25519, and "post-quantum" means this session key exchange, nothing broader.

Troubleshooting

The VPN configuration approval

First connect triggers a system dialog asking to allow a VPN configuration. If it was declined, the tunnel can never start. Approve it on the next attempt, or look in System Settings → VPN (also visible under Network), where the URnetwork configuration should be listed and enabled.

Multiple VPN profiles, and how the app manages them

Reinstalls and upgrades can leave macOS holding more than one URnetwork VPN profile. The app expects this: on connect it enumerates every profile, and when starting one fails it resets that profile and retries, then moves on to the next. If a tunnel is already running it adopts it over the device RPC instead of restarting. Broken profiles are reset or removed with a cap on removals, and every profile operation is deadline-bounded so a wedged system daemon cannot hang the app. It is automatic, described here so the entries in System Settings make sense.

"Failed to load VPN profiles" (error 12)

If connecting fails with "Failed to load VPN profiles" (error code 12), the system's VPN preference store is refusing to enumerate profiles, a state the app cannot repair from inside. Fix it by hand:

  1. Open System Settings and find the VPN configurations (System Settings → VPN, or the equivalent of General → VPN & Device Management on your macOS version).
  2. Remove the URnetwork configuration(s).
  3. Reconnect from the app and approve the fresh configuration.

Removing the configuration deletes plumbing, not data: your account, settings, and split rules are untouched, and the next connect recreates it (showing the one-time approval dialog again).

Starting at login

Launch URnetwork on system startup is a toggle in Account → Settings, under System. It registers the app with macOS's own login-items service, so it works on every version the app supports and the entry shows up in System Settings → General → Login Items, where you can also remove it by hand. Turning the toggle off unregisters it again.

How the kill switch works here

Same as on iOS: the app ships a Kill switch toggle in Account → Settings → Connections, the same SDK control every URnetwork app has. It starts off, so switching it on is a deliberate act. With it on, the client refuses to fall back to your local route, so traffic stops rather than leaking. What the Mac does not add is OS-level enforcement. The app does not set includeAllNetworks, so if the tunnel process dies unexpectedly, macOS restores normal networking rather than failing closed: your apps keep working over the underlying network with your real IP, likely without you noticing more than a blip. The menu-bar check/cross is the at-a-glance tripwire. The app supervises the tunnel and recovers profiles aggressively, but it does not currently ask the OS to hard-block traffic when the tunnel is down. If you need guaranteed fail-closed behavior, enforce it outside the Mac (a router or firewall rule that only passes tunnel traffic), or do browser-critical work through the URnetwork browser extension, whose kill switch is on by default and covers browser traffic only.

Reading the tunnel's logs

The tunnel extension logs to the unified system log: Console.app, not files.

  1. Open Console.app and select your Mac.
  2. In the Action menu, enable Include Info Messages and Include Debug Messages. The useful lines are at those levels.
  3. Filter by the network.ur.extension subsystem or search "URnetwork", then reproduce the connect.

Sleep behavior

The tunnel is configured with disconnectOnSleep off: closing the lid does not tear the session down, so you resume where you left off instead of re-handshaking on every wake. A sleeping Mac moves no traffic. It is not browsing and it is not providing; the setting only spares you the re-handshake.

Where next