A VPN client looks simple from the outside: a big toggle. Under the hood it touches the most sensitive APIs on the platform, and Google Play treats VPN apps with extra scrutiny. I built and shipped a cross-platform WireGuard client — Zerova / Zystra — through the full lifecycle, including a rebrand. Here's what actually matters.
Start with the native tunnel, not the UI
The tunnelling must live in the platform layer. On Android that means implementing a
VpnService; on iOS, a NetworkExtension packet-tunnel provider. WireGuard gives you
the crypto and the protocol, but you still own the service lifecycle: start, stop, reconnect, and the
foreground notification.
In Flutter I keep the UI thin and push all tunnel control across a platform channel. The UI should never assume the tunnel is up — it renders the state the native layer reports, including transitions.
// Conceptual platform channel shape
setState(method: "connect", server: "sg-01", config: wgConfig)
// native side: create TUN, apply routes, start WireGuard, post notification
onStateChanged: { status: "connecting" | "connected" | "disconnected" }
The VPN service declaration is mandatory
Google Play requires any app using VpnService to complete a VPN service declaration
and use the app as its core functionality. This is a policy gate, not a formality: misdeclaring gets the app
removed. You must explain how the VPN works, that you use the platform's VpnService, and that you follow the
secure-handling requirements.
Non-negotiable: declare the VPN service, use the Android VpnService API, and never redirect or inspect traffic you don't need. Play reviewers verify all three.
Data safety is where VPN apps get rejected
A VPN sees traffic metadata by nature, so the data-safety form must be precise. For a client that only tunnels and stores no logs, the declaration is minimal — but it has to match your actual behaviour exactly. Common rejection triggers I've seen:
- Declaring "no data collected" while shipping analytics that send device IDs.
- Not disclosing the crash-reporting SDKs bundled by a Flutter plugin.
- A privacy policy that contradicts the data-safety form.
- Missing account-deletion flow when the app has accounts.
Audit your dependency tree before you fill the form. The plugins you inherited count as your data collection.
Signing, rebranding, and versioning
If you're shipping under an organisation, you need an organisation account, a D-U-N-S number, and a verified developer identity — get this in place early because verification takes time. For the rebrand, the important detail is app signing continuity: keep the same signing key so Play treats the new build as an update, not a new app. Bundle IDs and signing keys are for life.
Store assets you'll need to produce for each release:
- App icon, feature graphic, and at least 2 phone screenshots (4+ recommended).
- A short and full description that leads with the core VPN functionality.
- Content rating questionnaire — VPN apps answer sensitive questions here.
- A public privacy policy URL that matches the data-safety form.
Handle the review feedback loop gracefully
Even a clean VPN submission often gets one round of questions. The winning approach is a precise, factual reply: quote the policy, point to where your app satisfies it, and attach evidence when asked. Vague responses slow review to a crawl. I keep a short "compliance dossier" per app — declarations, policy excerpts, and screenshots — so answers take minutes, not days.
Reliability is the real feature
A VPN that disconnects when the screen locks is worthless. After shipping, the work that keeps users is unglamorous: reconnect-on-network-change, kill-switch behaviour, reliable foreground notification, and battery-friendly keep-alive. Users judge a VPN on whether the toggle stays green, not on the crypto.
Takeaways
- Put the tunnel in the native layer; keep the UI a thin state reflector.
- Complete the VPN service declaration — it's a hard requirement.
- Make the data-safety form match reality, including every SDK.
- Preserve your signing key through any rebrand.
- Answer reviewers factually and fast with a compliance dossier ready.
Do this and a VPN app is very shippable. Skip it and you'll meet the rejection queue — repeatedly.