This guide gives us one repeatable way to validate experimental browser support on macOS without drifting between ad hoc commands.
- launch the browser by its real inner executable, not
open -a - use a fresh profile for each validation run
- keep WrapGuard logs in a known location
- distinguish "browser never starts", "browser starts but does not browse", and "browser browses through the VPN"
- run on macOS
- build the repo-root artifacts with
make build - use a non-SIP target application
- use a real WireGuard config file that already works with a CLI probe
Validate the tunnel path first:
./wrapguard --config=../NL-US-PA-16.conf -- /opt/homebrew/opt/curl/bin/curl https://icanhazip.comIf that does not return the VPN IP, stop there. Browser validation is not the next thing to debug.
Use the new make smoke-macos-browser target.
LibreWolf / Firefox-style example:
make smoke-macos-browser \
WG_CONFIG=../NL-US-PA-16.conf \
BROWSER_APP="/Applications/LibreWolf.app/Contents/MacOS/librewolf" \
BROWSER_ARGS_TEMPLATE="--no-remote -profile __PROFILE__" \
WG_LOG_FILE=/tmp/wrapguard-librewolf.logBrave / Chromium-style example:
make smoke-macos-browser \
WG_CONFIG=../NL-US-PA-16.conf \
BROWSER_APP="/Applications/Brave Browser.app/Contents/MacOS/Brave Browser" \
BROWSER_ARGS_TEMPLATE="--user-data-dir=__PROFILE__ --no-first-run --no-default-browser-check --new-window" \
WG_LOG_FILE=/tmp/wrapguard-brave.logHow it works:
__PROFILE__is replaced with a fresh temporary profile directory unlessBROWSER_PROFILE_DIRis provided- WrapGuard is rebuilt first so the binary and dylib stay in sync
- WrapGuard logs go to
WG_LOG_FILE - the target browser is launched directly through WrapGuard with debug logging enabled
After launch:
- open
http://icanhazip.com - confirm the page shows the VPN IP, not the host IP
- refresh several times
- open DevTools and confirm the browser remains stable
- compare the browser result against a direct CLI probe if anything looks wrong
Record each run in one of these buckets:
startup-failed- browser never reaches a usable window
- log focus: handshake, helper startup, GPU/compositor failures
startup-only- browser window opens, but pages do not load
- log focus: intercepted
CONNECTtraffic versus local IPC-only noise
tunneled- browser reaches a page and the public IP is the VPN IP
- keep notes on refresh behavior and DevTools stability
regressed- browser used to work in the same setup but no longer does
- capture the exact command, app version, and log path
- repeated
AF_UNIX/ local IPC logs are expected and are not proof of a network leak - GPU/helper warnings may still appear even when browsing works
- browser-visible host IP after a soft refresh can still indicate cache, service-worker, or QUIC / HTTP3 behavior rather than a total loss of TCP interception
- on macOS today, UDP is not a supported tunneled transport; WrapGuard only tries to suppress likely browser QUIC traffic enough to push browsers back toward the proven TCP path
Current experimental known-good validation on Apple Silicon:
- LibreWolf launches via its inner executable
http://icanhazip.comshows VPN IP146.70.156.18- repeated refreshes keep showing the VPN IP
- DevTools opens without the earlier recursion crash
That is a real breakthrough, but it is still not the final product bar for all GUI apps. Broader app coverage and automated regression checks are still open.