Security Reviews & Status
This page states what is in place in VeilMesh today, what is not active yet, and what we are still hardening. Every statement here was checked against the current source code. It is the result of an internal review by the VeilMesh team, not an independent third-party audit.
Review Metadata
1. How We Review
We read the security-relevant code paths end to end — key exchange, message encryption, storage, the relay and the mesh transport — and check each claim about them against the code and its tests. Findings are tracked internally and fixed in order of risk.
- Dependency scans (
cargo audit,npm audit) are run manually and are not yet part of the automated CI pipeline. - We describe issues that are not fixed yet only in general terms, so this page does not become a guide for attackers. Details are published after the fix ships.
2. In Place Today
Verified in the current code of the Rust core, the relay server and the apps.
One-to-One Encryption
In place- Sessions start with an X3DH handshake over X25519 and continue with the Double Ratchet.
- Messages are encrypted with XChaCha20-Poly1305 under a fresh random 24-byte nonce from the OS CSPRNG.
- Keys are derived with HKDF-SHA256 (X3DH output and root chain) and HMAC-SHA256 (message chains).
- The initiator accepts a peer’s signed prekey only with a valid Ed25519 signature that binds it to the peer’s Veil ID.
Identity checks on the responding side and authentication of ratchet header metadata are being strengthened (section 4).
Group Chats
In place- Group chats use MLS (RFC 9420) via OpenMLS 0.8 with the MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 ciphersuite.
- The group key advances whenever membership changes.
Group chats are newer than one-to-one chats. Binding of group members to their Veil IDs and protection of group control messages are being hardened, and automatic periodic key updates are not scheduled yet.
Attachments
In place- In one-to-one and group chats, files are encrypted with AES-256-GCM in STREAM mode (64 KiB chunks).
- Each file gets a random key and nonce from the OS CSPRNG; every chunk’s authentication tag is checked on decryption.
Attachments posted to public channels are not encrypted. Protection of thumbnails and re-sent files is being hardened.
On-Device Storage
In place- The local database is encrypted with SQLCipher under a random 256-bit key.
- The key is stored in the iOS Keychain (this device only, available after first unlock) or in Android Keystore-protected storage.
- New attachments are stored encrypted on disk under a per-chat storage key.
The Secure Enclave only supports NIST P-256 keys, so the Ed25519 and X25519 keys VeilMesh uses cannot live inside it; they are kept in the iOS Keychain, whose items are protected by a hardware-bound device key, and items marked this-device-only are not restored to other devices from a backup. Cleanup of some temporary media files and further key-handling hardening are in progress.
Mesh Packets
In place- Every mesh packet carries an Ed25519 signature and a small fixed proof-of-work that is checked before the signature. The proof-of-work is a cheap pre-filter, not an anti-spam control.
- Protocol V2 obfuscates the sender key and packet ID in each header with ChaCha20 under a fresh random 12-byte nonce, so these fields do not appear as plain bytes in a raw capture.
Header obfuscation uses a key built into the app, so it only hides these fields from casual capture; it is not anonymity. Devices that relay a mesh message can read the sender’s Veil ID and the chat identifier in its envelope — the message text stays end-to-end encrypted. V1 packets from older builds are still accepted on receive.
Call Setup
In place- Call setup messages (SDP offers and answers, and ICE candidates, which contain IP addresses) are end-to-end encrypted before they reach any transport.
- Call signaling that arrives unencrypted is refused.
Ghost Mode
In place- Ghost Mode keeps message delivery on the local mesh (Bluetooth and local Wi-Fi) and stops the app from sending through the relay — for conversations you do not want our relay to route at all.
Nearby devices that relay your messages still see the envelope metadata described under Mesh Packets.
Delivery Acknowledgements
In place- Mesh delivery and read acknowledgements carry an HMAC-blinded message identifier and a short random delay, so an acknowledgement does not reveal which message it confirms.
This covers the message identifier only and is not a general defense against traffic analysis.
Relay Server
In place- The relay forwards end-to-end encrypted payloads it cannot decrypt and holds no end-to-end private keys.
- Database queries use sqlx with bound parameters; SQL text is not built from user input.
- Account registration and public channel endpoints (directory, post history, attachment downloads) are rate-limited per client IP.
The relay does see routing metadata — sender and recipient identifiers, connection times and addresses — and some signals that are not yet end-to-end encrypted, such as typing indicators, read receipts and group names set at creation.
Randomness & Key Material
In place- Keys and nonces come from the operating-system CSPRNG (OsRng).
- Identity keys and Double Ratchet state are zeroized when released; X3DH intermediate secrets are wiped right after use.
- Log statements are reviewed so that private keys, seeds, ratchet state and session tokens are not written to logs.
Some short-lived copies, such as serialized session state and per-message keys, are not wiped yet.
Gateway & WisBlock Nodes
In place- The gateway’s TCP backhaul requires mutual TLS (tokio-rustls, client certificates checked against an operator-provided CA) and refuses to start without certificates unless an explicit insecure test flag is set.
- WisBlock firmware takes packet nonces and IDs from the nRF52840 hardware RNG and reads a per-device Ed25519 key from UICR memory when one is provisioned.
The LoRa radio link is outside the TLS layer, and WisBlock telemetry payloads are signed but not encrypted.
3. Metadata Protections: What We Use, Build and Retire
The mechanisms below protect metadata — who talks to whom and when — not the content of messages, files or calls, which is end-to-end encrypted in any case. Earlier versions of VeilMesh carried prototypes of some of them; here is where each one stands.
Onion Routing on the Mesh
Not usedRetired in September 2026. Building onion routes required every device to announce its nearby neighbors and to ask the mesh for keys by recipient, and padding each packet to 2 KB is impractical over Bluetooth and LoRa — it exposed more metadata than it hid. Mesh messages are flooded to nearby devices instead, with no recipient in the radio header; the leftover onion-era traffic (neighbor announcements and dummy cover packets) is being removed.
Sealed Sender
In progressNot active yet. Every connection to our relay is authenticated, so today the relay can see which account sends a message — never what it says. We are starting with push notifications: the sender and chat identifiers they carry are being moved into an envelope encrypted to your device, so push providers such as Apple and Google no longer learn who messages whom. If you do not want the relay involved in a conversation at all, Ghost Mode keeps delivery on the local mesh.
Anonymous Rate-Limit Tokens (VOPRF)
Not usedNot used, and the prototype is being removed. Anonymous tokens only make sense together with sealed sender; since connections are authenticated, abuse limits are tied to accounts and IP addresses instead: registration and public endpoints are limited per IP, per-account sending limits are being rolled out, and app attestation (Firebase App Check) raises the cost of automated clients.
Post-Quantum Key Exchange & Encrypted Client Hello
Not usedHybrid post-quantum key exchange (such as X25519 + ML-KEM) and TLS Encrypted Client Hello are not implemented and are not currently scheduled. Connections to the relay use standard TLS.
4. Being Hardened
Open areas found in the September 2026 review. They are described in general terms until the fixes ship.
- Session setup: identity binding on the responding side of the handshake, and authentication of Double Ratchet header metadata through a new message envelope version rolled out in stages.
- Group chats: binding of group members to their Veil IDs and validation of group control messages.
- Relay: retiring legacy identifier-based sign-in, enforcing app attestation (Firebase App Check) on all account and messaging endpoints, per-account sending limits, and stricter access checks on attachment routes.
- Server-side deletion: removing orphaned attachment copies and queued message copies when messages, chats or accounts are deleted.
- Mobile apps: app lock and duress-wipe behavior, privacy of the lock screen and app switcher, and cleanup of temporary media files.
- Metadata: moving the identifiers in push notifications into an envelope encrypted to your device, reducing identifiers in operational logs, and removing leftover mesh traffic from the retired onion routing.
- Dependencies: removing an unused dependency, upgrading transitive dependencies with open advisories, and adding dependency scanning to CI.
5. Dependency Health
Rust core & relay server (Cargo)
Rust dependencies are scanned with cargo audit against the RustSec Advisory Database. The September 2026 scan reports open advisories in several transitive dependencies of the core and the relay, including TLS, HTTP/2 and cryptographic helper crates. Some of them come from an unused dependency that is being removed, and some are lock-file entries that are not compiled into the apps; the rest are being upgraded. We do not claim an advisory-free state.
Website (npm)
This site is a static, pre-rendered bundle. Its build tooling (Vite 5.4) runs only on developer machines and during the build, and is not part of what your browser loads. An upgrade of the build tooling to a current major version is pending.
6. Previous Review — July 2026
Internal review of the code as of July 13, 2026, updated July 27, 2026. Items it delivered:
- crossbeam-epoch upgraded to 0.9.20 in the core workspace (RUSTSEC-2026-0204); the same upgrade for the relay server is pending.
- Protocol header nonces taken directly from OsRng; WisBlock firmware moved to the nRF52840 hardware RNG and a per-device key from UICR.
- Mutual TLS on the gateway backhaul.
- Per-client-IP rate limiting on the public channel directory, post-history and attachment-download routes.
- Wiping of the PBKDF2-derived key and password buffers after a successful seed backup export or import.
- The spent-token store of the (inactive) token scheme moved to a shared Redis instance.
Correction (September 28, 2026)
The earlier version of this page presented the July review as a completed audit by “Bison Tech Solutions Security Lab”. Bison Tech Solutions Inc. is the company behind VeilMesh, and the review was internal. That version also marked several items as passed or resolved that were not active or not accurate: sealed sender, onion routing and its timing mitigations, VOPRF rate limiting, “zero vulnerabilities” in dependencies, hardware Secure Enclave key storage, and a Q4 2026 target for post-quantum key exchange and ECH. The sections above replace those statements with the current state.
7. Reporting a Vulnerability
If you believe you have found a security issue in VeilMesh, email support [at] veilmesh.com with the details and steps to reproduce. Please give us a chance to fix it before disclosing it publicly.