VPN containment without root: what Android actually allows
One of the most common questions we get about Baselyt is: "How can you block an app's network access without root?" The answer lies in Android's VpnService API, a system-level interface that lets any app create a local VPN tunnel with the user's permission.
This post explains how VpnService works, what it enables for Baselyt, and where the real limitations are. We believe in being transparent about constraints, not hiding them behind marketing.
How Android VpnService works
Since Android 4.0 (API 14), any app can request VPN permission from the user. Once granted, the app can:
- Create a virtual network interface (tun device) on the phone
- Route all network traffic through that interface
- Inspect connection metadata: destination IP, port, protocol, originating app (via UID)
- Decide per-packet or per-connection whether to allow, block, or redirect traffic
The key insight: this all happens locally on the device. The VPN tunnel does not need to connect to a remote server. It is a local processing pipeline for network traffic.
What you can do with a local VPN
With VpnService, Baselyt can:
- Block network access per-app: If an app drifts from its baseline, we can cut its network access entirely
- Allow specific domains: Let an app reach its known-good servers while blocking new or suspicious destinations
- Enforce DNS policies: Route DNS queries through filtered resolvers
- Log connection metadata: Record which apps connect to which domains, how often, and when, without reading the actual data being transmitted
- Implement a kill switch: If the VPN service stops unexpectedly, Android can be configured to block all traffic until the VPN restarts
What you cannot do
Transparency about limitations matters more than marketing claims:
- One VPN at a time: Android allows only one active VPN connection. If you are already using a VPN for privacy or geo-unblocking, Baselyt's VPN service cannot run simultaneously. This is an Android platform limitation, not a Baselyt limitation.
- No payload inspection: HTTPS traffic is encrypted end-to-end. We can see that an app connected to tracker-network.xyz, but we cannot see what data it sent. We deliberately chose not to implement TLS interception (MITM), which would require installing a root certificate.
- Cannot kill apps: Android does not let one app force-stop another without system privileges. We can block network access, but the app will still run on the device.
- Cannot prevent all data exfiltration: An app could potentially use non-network channels (Bluetooth, NFC, or encoding data in DNS queries) to leak information. VPN-based containment covers network traffic only.
How Baselyt uses VpnService
Our implementation focuses on reliability and minimal overhead:
- Local tunnel only: Traffic enters and exits the VPN on the same device. No remote servers, no cloud processing, no data leaving your phone.
- Per-app routing rules: Each app gets its own containment policy based on its current trust level and baseline compliance.
- Foreground service with notification: Android requires VPN apps to show a persistent notification. We use this to display current protection status.
- Kill switch: Configurable always-on VPN with lockdown mode so traffic is blocked if Baselyt's service is interrupted.
- Graceful degradation: If the VPN service crashes, Baselyt logs the event and restarts. Containment policies are restored from local storage.
Battery and performance
Running a local VPN adds processing overhead because every network packet routes through the Baselyt service. In our testing:
- Battery impact is typically under 5% additional daily drain
- Network latency increase is negligible (under 1ms for local processing)
- Memory footprint is approximately 30-50MB depending on the number of monitored apps
These numbers will vary by device, Android version, and number of active apps. We'll publish detailed benchmarks during beta testing.
Android version considerations
VpnService behavior varies across Android versions:
- Android 10+: Per-app VPN restrictions are more granular. This is our primary target.
- Android 12+: Stricter foreground service requirements change how we manage the VPN lifecycle.
- Android 14+: New APIs for credential management and per-app network policies provide additional capabilities.
We're targeting Android 10+ for initial beta. Supporting older versions would require significant workarounds for limited additional benefit.
The honest assessment
VPN-based containment is the best tool available for per-app network control on non-rooted Android devices. It works well for its intended purpose: letting you decide which apps get network access and which do not.
But it is not omnipotent. It cannot read encrypted content, cannot run alongside another VPN, and cannot force-stop misbehaving apps. We think being upfront about these constraints is more valuable than pretending they do not exist.
If you are evaluating Baselyt, this is the enforcement mechanism we use. It is effective, well-documented by Android, and requires no special privileges beyond the user granting VPN permission.