Haven Docs

VPN service

Haven uses Android's VpnService API to filter DNS on the device. This page describes exactly what that means, because "VPN" is a word that reasonably makes people cautious.

The short version#

Haven is not a VPN in the ordinary sense. It does not route the user's traffic anywhere, it has no VPN servers, and it cannot see what the user does online.

It uses the VPN API for one narrow purpose: it is the only mechanism Android offers an app to see and answer the device's DNS lookups. Haven answers "does this gambling site exist?" with "no" — and forwards everything else untouched.

How the tunnel is configured#

The tunnel assigns a virtual DNS server address and then routes only that address into the tunnel:

addAddress(<tunnel address>)          // the tunnel's own interface
addDnsServer(<virtual resolver>)      // tell the OS to ask us for DNS
addRoute(<virtual resolver>, /32)     // ...and route ONLY that address to us

The consequence of that third line is the whole privacy story:

  • DNS lookups reach Haven.
  • Everything else — web page contents, video, messages, banking traffic, uploads, downloads — does not enter the tunnel at all. It leaves the device exactly as it would if Haven were not installed.

Both IPv4 and IPv6 DNS are captured, because a v6-only resolver would otherwise walk straight past a v4-only filter. If a device rejects the dual-stack configuration, Haven retries IPv4-only so protection still comes up instead of failing silently.

What happens to a DNS query#

  1. Haven parses the IP/UDP/DNS packet and extracts the hostname.
  2. It asks the on-device matcher whether that hostname is gambling-related.
  3. Blocked → Haven synthesises an NXDOMAIN response. The site simply does not resolve.
  4. Allowed → the query is forwarded, byte for byte, to a public upstream resolver over a socket that is explicitly excluded from the tunnel, and the real answer is written back.

Haven does not modify allowed responses, does not inject anything, and does not redirect traffic to any server it controls.

What Haven can and cannot see#

Haven can seeHaven cannot see
Hostnames the device looks upThe contents of any page, message or file
Whether a lookup was blockedAnything inside an HTTPS connection
URLs, paths or query strings
Passwords, cookies, tokens or session data
What the user does on a site once it resolves

Haven never decrypts, intercepts or inspects TLS/HTTPS traffic. There is no certificate installation, no man-in-the-middle proxy, and no traffic inspection of any kind. This is an architectural rule of the project, not a current limitation.

What is stored, and what leaves the device#

  • Allowed lookups are not logged at all. Haven does not build a browsing history.
  • Blocked lookups are written to a local block log — the host, the time, the layer and the matched rule — so the user can see and audit what their own phone did.
  • The block log never leaves the device.
  • Allowed queries are forwarded to a public upstream resolver, which necessarily sees them. That resolver is named and explained in DNS resolution, because it is the one place where a hostname genuinely leaves the phone.
  • Android shows its own consent dialog, which Haven cannot skip, style or suppress.
  • Because that dialog names a VPN and says nothing about why a gambling blocker wants one, Haven explains itself first, in its own words, before handing over to the system dialog.
  • While the tunnel is up, an ongoing notification is visible, and Android additionally shows its own permanent VPN indicator. The user is never in a state where Haven is filtering invisibly.
  • The user can revoke consent at any time from Android's own settings, and Haven does not attempt to prevent or detect that.

Restart behaviour#

Two mechanisms keep protection from being silently off, and both respect consent:

  • After a reboot, protection is re-armed if the user had it enabled. If consent was never granted or has been revoked, Haven skips silently — Android requires a foreground dialog that a boot receiver cannot show, and Haven does not try to work around that.
  • On launch, if protection is enabled but the tunnel is not running (after a reinstall, a crash, or an aggressive battery optimiser), Haven restarts it — again, only if consent is already in place.

Neither mechanism can grant itself consent.

Foreground service type#

The service is declared with the specialUse foreground service type and this subtype declaration:

xml
<service
    android:name=".filter.AppBlockVpnService"
    android:exported="false"
    android:permission="android.permission.BIND_VPN_SERVICE"
    android:foregroundServiceType="specialUse">
    <property
        android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
        android:value="On-device DNS content filtering for personal protection" />
    ...
</service>

The filtering must run continuously for as long as the user wants to be protected — protection that stops when the app is backgrounded protects nobody — and none of the standard foreground service types describes on-device DNS content filtering.

Compatibility#

A small, curated set of packages is excluded from the tunnel because their connectivity is known to break under any active VPN, not because of anything Haven does. The exclusion list is kept minimal and every entry has to meet the same bar: the app must not be a gambling surface, and the gambling-app block continues to watch the device's foreground regardless.

The specific list is not published, for the same reason the detection thresholds are not.