Security & Threat Model
Last updated: 2026-08-02
Relayium is built so that the people transferring files or temporary text — not the server — hold the keys. This page describes exactly what is protected, how it works, and the limits of that protection.
The short version: on the same network, realtime files and messages move directly between devices; across networks, browser sessions use a relay that carries only end-to-end encrypted ciphertext and holds no content key. Fresh session keys are always used; an optional out-of-band verification code lets the two people also detect signaling interception. The detail follows.
Browser realtime file encryption (X25519 + AES-256-GCM)
For realtime file transfers in the browser, each transfer generates a fresh, ephemeral X25519 key pair on each device. The two browsers perform a key exchange to derive a shared AES-256-GCM key. Every file chunk is encrypted under that key with a unique nonce, so the signaling server — and any relay — sees ciphertext rather than file plaintext. CLI transfers use a different direct TLS 1.3 protocol described below.
- Keys are ephemeral and per-transfer — nothing is reused across sessions.
- The shared key is derived on the two devices; it is never sent to, or stored on, any server.
- Encryption is applied at the application layer, on top of WebRTC's own transport security, so it holds even if the transport layer is compromised.
The verification code (SAS) — detecting a malicious server
WebRTC's built-in encryption (DTLS) exchanges key fingerprints through the signaling server, so a dishonest server could sit in the middle and swap keys. To catch this, Relayium derives a 6-digit Short Authentication String (SAS) from both sides' public keys and can show it on both screens. Matching codes provide the strongest interception check only when the two people compare them out of band. Showing that code and stopping to compare it is a preference — “advanced verification”, off by default, and `--verify` in the CLI. Turning it off changes what is displayed and which steps pause for confirmation; it does not change the encryption. The commit-then-reveal handshake below still runs on every connection and still refuses one whose reveal does not match, keys are still generated on your device and never sent to us, the relay still carries only ciphertext, and in the browser, receiving files still asks you before anything is saved — the native macOS app writes into its configured destination (Downloads by default) instead of asking. That prompt is about unsolicited writes to your disk, not about who is on the other end; only comparing the code establishes that.
A plain 6-digit code (about 20 bits) could in principle be brute-forced by a relay racing to force a matching code. Relayium closes that gap with a commit-then-reveal handshake: each side first commits to its key by sending a hash, and only reveals the key after receiving the other side's commitment. CLI transfers use a separate SAS derived through a commit-then-reveal exchange of the pinned TLS certificate fingerprints; it too detects nothing unless someone actually compares it out of band, which is what `--verify` stops for.
- For the strongest guarantee, turn on advanced verification and compare the code out of band — in person or over a voice call.
- If the two codes differ, stop the transfer: someone may be intercepting the connection.
Plaintext the server cannot see or decrypt
The service is designed so that our servers cannot see or decrypt the following plaintext:
In browser realtime mode on the same network, file and message bytes flow directly between the two devices. Across networks they pass through TURN as ciphertext, and the relay holds no content key. The signaling service still handles connection-setup data and can see metadata such as public IP addresses, room membership, timing, a chosen device nickname, and presence.
- The contents of your files.
- The names of your files.
- The plaintext of your text messages.
- Your encryption keys.
When browser files and text are relayed (TURN)
Browser file and text transfers across networks — pairing-code sessions, including their join links — run through a TURN server by design, not as a fallback. Restrictive NATs and firewalls make a genuinely direct path unlikely there, so the app forces the relay route outright. Same-network browser sessions receive no relay credentials and connect directly. CLI file and text transfers never use TURN: they are direct-only and fail if no direct path can be found.
- The relay forwards only ciphertext — it cannot read your files or messages, which stay end-to-end encrypted.
- We record the number of relayed bytes per account, to enforce a monthly relay allowance and prevent abuse — we never inspect what is relayed, only the byte count.
- We never inspect relayed content.
Temporary text transfer
Browser text sessions use the Web protocol: the peers perform an ephemeral X25519 exchange and derive direction-separated AES-256-GCM subkeys in a domain separate from file-transfer keys. Each valid UTF-8 message is authenticated and encrypted as its own frame. Across networks, browser sessions use TURN by design; the relay carries ciphertext and has no message key. With advanced verification on, comparing the SAS out of band also detects signaling interception.
CLI text is a different, direct-only protocol over pinned TLS 1.3. It does not use the browser X25519/AES message framing or TURN, and it fails when no direct path can be established. Message bodies are not stored by Relayium, but either endpoint can copy, log, screenshot, or otherwise retain text after receiving it.
- Both people must be online; Relayium provides no offline text delivery or server-side message history.
- Servers necessarily handle connection metadata such as IP addresses, room membership, timing, device nickname and presence for browser sessions, and the account association used to create a pairing code where applicable.
- For TURN sessions, Relayium may record relayed byte counts for allowance enforcement and abuse prevention, but does not inspect message plaintext.
Stored download links — the key never leaves your browser
The optional download-link mode is for when the recipient is not online. Your browser encrypts the files with AES-256-GCM before anything is uploaded, and the decryption key is placed only in the URL fragment — the part after the # — which browsers never send to the server.
- The server stores only ciphertext, plus the ciphertext size and timestamps for quota and cleanup — never plaintext, filenames, or keys.
- Anyone with the full link can decrypt, so treat the link like the file itself and share it over a trusted channel.
- Links can be set to expire (from 1 hour up to 14 days, depending on your plan) or to burn after the first complete download.
File integrity (SHA-256)
Beyond confidentiality, each file's integrity is verified. Every chunk carries an AES-GCM authentication tag, and a per-file SHA-256 hash is checked end-to-end on the receiving side, so a corrupted or tampered file is detected rather than silently accepted.
What Relayium does not protect against
End-to-end encryption protects data in transit between two honest endpoints. It cannot, by design, protect against:
- A compromised device or browser on either end — malware, a hostile browser extension, or someone reading the screen.
- Metadata the server necessarily handles: session timing, relayed byte counts, and — for a stored download link or a pairing-code session — the account that created the link or code.
- A recipient choosing to retain, copy, or forward files or messages after receiving them.
- Sharing a download link over an untrusted channel, since the decryption key travels inside the link.
Browser support and its limits
Relayium runs in any modern browser with WebRTC over HTTPS. A few capabilities differ by browser:
- Desktop Chrome and Edge have the File System Access API and stream large files straight to disk, with no practical memory ceiling.
- Firefox, Safari and every mobile browser (on iOS every browser is WebKit) lack that API and assemble the file in memory on the realtime path, so the app warns above roughly 256 MB — a deliberately conservative estimate, not a measured hard limit. For files that size, prefer desktop Chrome/Edge, or use the download-link mode, whose download page can additionally stream to disk through a service worker.
- WebRTC requires a secure context (HTTPS); the app will not connect over plain HTTP.
Open source and reporting issues
The protocol design and all client and server code are public on GitHub, so anyone can audit the cryptography, run their own server, or contribute. If you find a security issue, please report it privately through GitHub's vulnerability reporting on the repository, rather than opening a public issue.