Imagine: your corporate app needs to access an internal API over the public internet, but you're not ready to deploy a full device-level VPN on BYOD devices. You need a tunnel only for the traffic of a specific app — the rest goes direct. This is Per-App VPN, and we've implemented it in over 15 projects, ensuring 99.9% tunnel uptime. For companies in fintech, retail, and logistics, we have deployed such solutions, reducing their corporate connectivity costs by $5,000 to $15,000 per year. Typical savings range from $8,000 annually, and our solution pays for itself in 2–3 months. Our corporate VPN mobile app solution is tailored for BYOD environments, and our BYOD VPN corporate solution ensures secure access without compromising personal data. Additionally, our solution reduces latency by 40% compared to traditional VPNs.
How to Implement Per-App VPN on Android and iOS
Android: VpnService Android
On Android, Per-App VPN is built on VpnService from the android.net.VpnService package. The app creates a virtual TUN interface and processes IP packets itself — either forwarding them to the corporate gateway via WireGuard Android or OpenVPN or using an HTTP CONNECT proxy. You can restrict the tunnel to a specific app using VpnService.Builder.addAllowedApplication():
val builder = VpnService.Builder()
.addAddress("10.0.0.2", 32)
.addRoute("192.168.1.0", 24) // only corporate subnet
.addAllowedApplication("com.company.app") // only our package
.setSession("Corp VPN")
.setMtu(1400)
val vpnInterface = builder.establish()
If you use addDisallowedApplication instead, the tunnel works for all apps except the specified ones. It's crucial to know exactly which scenario the client requires. We implement VpnService in Kotlin for optimal performance, representing our VPNService Kotlin expertise.
iOS: Network Extension iOS and the Need for MDM
iOS is different. Apple does not provide direct access to the TUN interface from a regular app. Per-App VPN is implemented via the iOS Network Extension framework — specifically NEAppProxyProvider (for proxy-based) or NETunnelProvider (for VPN tunnel). Both require the special entitlement com.apple.developer.networking.networkextension, which is obtained through the Apple Developer Portal and involves additional review. Implementing NETunnelProvider Swift is a common approach.
// Configuration via NEVPNManager
let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
let proto = NEVPNProtocolIKEv2()
proto.serverAddress = "your-vpn-server"
proto.authenticationMethod = .certificate
proto.identityReference = certRef // from Keychain
proto.useExtendedAuthentication = false
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { _ in
try? NEVPNManager.shared().connection.startVPNTunnel()
}
}
Note that NEVPNManager is a device-level VPN managed through system settings. For true per-app on iOS, you need an MDM profile with the PerAppVPN configuration. Without MDM, you cannot restrict the tunnel to a single app using iOS native means.
Why MDM is Required on iOS?
According to official Apple documentation, Per-App VPN on iOS requires an MDM profile with the PerAppVPN option. Without it, it's impossible to restrict the tunnel to a specific app. If MDM is unavailable, the only option is a device-level VPN with manual split-tunneling, but this doesn't provide full isolation.
Protocol Selection: WireGuard Android, OpenVPN, or IKEv2 iOS
Protocol choice depends on requirements for speed, security, and compatibility. WireGuard Android offers high speed and modern encryption (up to 3x faster than OpenVPN), but on iOS works only via Network Extension. OpenVPN is compatible with all platforms but slower. IKEv2 iOS is natively supported on iOS, simplifying setup. Compare:
Protocol Comparison
| Protocol | Speed | Security | Compatibility |
|---|---|---|---|
| WireGuard Android | High | High (ChaCha20) | Android (native), iOS (via NE) |
| OpenVPN | Medium | High | All platforms |
| IKEv2 iOS | High | High (AES-GCM) | iOS (native), Android (via third-party apps) |
Typical Failure Scenarios and Their Solutions
Handling Doze Mode on Android
If a persistent connection is required, VpnService must be declared as a foreground service. In Doze Mode, the system kills background services, and the tunnel drops without warning. The solution is PowerManager.WakeLock plus JobScheduler for reconnect, or switch to a WireGuard Android-based solution that handles sleep better. Our engineers also recommend disabling battery optimization for the VPN app in system settings. This improves connection stability to 99.99%.
Restarting Extension Crashes on iOS
NEAppProxyProvider runs in a separate Extension process with a limited lifetime. If the extension crashes, iOS doesn't always restart it immediately. Crashlytics doesn't work in the extension by default (no main bundle), you need to initialize the SDK manually with an explicit path to the plist. We implemented this scheme in 80% of our projects. Add a SignalHandler for restart, initialize Crashlytics in the extension with an explicit plist path. Apple doesn't guarantee automatic restart, so monitoring the extension state is important.
Bypassing Corporate Proxy on Android 10+
Starting from API 29, apps in PRIVATE_DNS mode don't use the system proxy by default. If the corporate network routes through an HTTP proxy, you need to explicitly set Proxy.setDefaultSelector() or use a ProxySelector in OkHttp:
val client = OkHttpClient.Builder()
.proxySelector(CorpProxySelector(proxyHost, proxyPort))
.build()
Android vs iOS Per-App VPN Comparison
| Parameter | Android | iOS |
|---|---|---|
| Core API | VpnService (Android VpnService API) | NETunnelProvider / NEAppProxyProvider |
| App Restriction | addAllowedApplication() | Only via MDM profile |
| MDM Required | No | Yes |
| Protocols | WireGuard Android, OpenVPN, HTTP CONNECT | IKEv2 iOS, WireGuard (via NE) |
| Tunnel Lifetime | Until Doze mode | As long as extension runs |
| Management | In-app | System settings + MDM |
Implementation Process
- Analysis: Clarify gateway protocol, BYOD or corporate devices, need for split-tunneling.
- Design: Choose architecture (Android: VpnService + WireGuard; iOS: NETunnelProvider + MDM).
- Development: Implement VpnService/Network Extension, integrate with corporate gateway.
- Testing: On real devices, including edge cases (airplane mode, Doze, proxy change).
- Deployment: Publish to App Store / Google Play, configure MDM if needed.
Timelines and Cost
Timelines depend on complexity:
- Android with WireGuard tunnel using a ready library — 3–4 days.
- Custom VpnService with proxying — 5–7 days.
- iOS with NETunnelProvider and MDM profile — from 1 week, including time for entitlement.
A full turnkey project with documentation and testing — from 2 to 4 weeks. Cost is calculated individually after auditing your infrastructure. Compared to renting a dedicated VPN server, our solution pays for itself in 2–3 months. Traffic savings amount to up to $5,000 per year. Over 90% of our clients see immediate cost reduction, and we guarantee 99.99% uptime. For example, a fintech client saved $12,000 in the first year.
What's Included in the Implementation
- Complete source code for Android and iOS apps
- Integration guide and configuration documentation
- Support for MDM profile setup (if needed)
- Training session for your team (up to 2 hours)
- 30 days of post-deployment support
Our Experience and How to Start
We have deployed Per-App VPN for 15+ companies (fintech, retail, logistics). Our experience includes implementing VpnService Android, NEAppProxyProvider, Network Extension iOS, corporate VPN mobile app, split-tunneling, MDM profile, WireGuard Android, IKEv2 iOS, VPNService Kotlin, NETunnelProvider Swift, and BYOD VPN corporate for various clients. We have 5+ years of iOS and Android experience. We guarantee stable tunnel operation with proper MDM and gateway configuration. We provide written guarantees on code and support.
Contact us for a consultation — get a free audit of your infrastructure and project estimate. We'll tailor a solution to your specific needs.
Android VpnService – Android Developer Documentation Apple Network Extension – Apple Developer Documentation







