Please feel free to check out our FAQ for the Technically Inclined.
Client developers are required to comply with the Security Guidelines.
This page describes the security and transport architecture of VMP Chat — the standards-based cryptographic stack that protects messages, calls, and media end-to-end. See also:
The VMP Chat protocol is built on industry-standard cryptography and transport primitives — the same building blocks used by every modern secure messenger. There are no custom cipher constructions and no proprietary wire formats; every layer is something a security auditor can recognize and verify against published specifications.
The architecture is subdivided into three virtually independent components:
The iOS Swift Package and Android Kotlin app share the same domain model, the same Socket.IO event contract, and the same encryption wire format. A message encrypted on iOS decrypts byte-for-byte on Android with the same room key — and vice versa. The two clients are functional 1:1 mirrors of each other.
Sign-in uses OAuth 2.0 with PKCE — the modern standard for native-app authentication. The flow eliminates the entire authorization-code interception attack class that historically affected public OAuth clients.
The server issues a pair of JWTs: a short-lived access token and a longer-lived refresh token. Both are persisted in hardware-rooted secure storage on your device:
The client maintains two independent token contexts (one for chat, one for the community surface), so a token issued for one cannot accidentally authorize a request to the other.
Access tokens are refreshed proactively — the network layer refreshes them before they expire, avoiding the round-trip cost of a failed request followed by a re-attempt. Refreshes are serialized so simultaneous expired requests trigger exactly one refresh, not many.
Sign-out revokes the refresh token server-side, so a stolen device with cached tokens cannot continue to access the account once the user has signed out from anywhere else.
Real-time delivery runs on Socket.IO with horizontally-scaled servers behind a load balancer, so a message published on one instance reaches a client connected to any other instance transparently.
The clients implement a custom reconnect handler: on disconnect, the client refreshes the auth token first, then reconnects with the fresh token. Backoff is exponential, capped at 30 seconds per attempt for up to 10 attempts.
Messages are de-duplicated client-side with a small in-memory cache of recent message IDs, so even when the server fans out for delivery guarantees, you never see duplicate bubbles in a busy group chat.
The clients share the same set of real-time events: new and updated messages, message status, typing indicators, presence, reactions, block changes, room and member updates. Both platforms observe the same vocabulary, so a feature shipped on one client behaves identically on the other.
If a corporate firewall blocks WebSockets, Socket.IO transparently degrades to long-polling — most “this app does not work on my office Wi-Fi” complaints disappear as a result.
Message contents are encrypted on your device before they reach the server. The cipher is AES-256-GCM — the authenticated-encryption construction defined in NIST SP 800-38D and standardized as a default cipher suite in TLS 1.3.
Room keys are themselves wrapped under a Key Encryption Key (KEK) deterministically derived per-user, and the KEK never leaves your device. The server stores the wrapped key envelopes — so a new device can sync your history after sign-in — but cannot unwrap them. A database leak yields ciphertext only.
The encryption service refuses to encrypt at all when a key is missing — there is no silent fallback to plaintext. The server can never receive a message in the clear because of a client-side error.
Voice and video calls run on LiveKit, a Selective Forwarding Unit (SFU) built on WebRTC. The SFU architecture means each additional participant adds O(1) cost per client — the same architecture as Google Meet and Zoom, and substantially cheaper than a peer-to-peer mesh past four participants.
Every WebRTC media stream is encrypted end-to-end with DTLS-SRTP, as mandated by the WebRTC specification. Room access tokens are short-lived (15 minutes) and bound to a single room — a token captured in transit expires quickly and cannot be replayed elsewhere.
Each client integrates with the platform’s native call surface:
Audio routing detects Bluetooth and wired headsets automatically, uses the earpiece for voice calls and the speakerphone for video, and applies echo cancellation and microphone gating during the call.
Every byte that leaves the device — API call, real-time frame, or media upload — travels over TLS 1.2 or higher. The transport layer provides the standard guarantees: confidentiality, integrity, and forward secrecy of the channel itself. The application layer adds end-to-end encryption on top.
Both clients add a defense-in-depth layer above TLS:
The HTTP client distinguishes mutable from immutable resources via cache-control headers: media URLs are cached for 24 hours (they are content-addressed and immutable), user profiles for 10 minutes, and sensitive mutable state is never HTTP-cached. Room and message data is never HTTP-cached either — the local on-device store is the source of truth for those.
The real-time layer negotiates the best available transport: WebSocket where possible, HTTP long-polling as fallback. On Android, the client waits for the OS to confirm real internet reach before reconnecting, so reconnect attempts do not fire on a captive-portal Wi-Fi where the OS has not yet confirmed real internet access.
The app is offline-first. The chat list, message history, contacts, drafts, and unread counts open instantly on cold start — even on a plane.
On the server side, state is split across the database that best fits each access pattern: a relational store for accounts, contacts, devices, and room metadata; a wide-column store for message bodies, sharded per room and ordered by recency — the same workload pattern WhatsApp and Discord use; and an in-memory cache for presence, typing, and short-lived hot data.
Uploaded media is encrypted at rest on the server with AES-256-GCM and expires after 30 days. Users may opt into Google Drive backup, in which case the encrypted file lives in the user’s own Drive — not the platform’s storage.
VMP Messenger is built on industry-standard cryptography and transport — the same building blocks used by every modern secure messenger:
Every layer maps to a published specification — there are no proprietary cipher constructions and no closed wire formats.