> ## Documentation Index
> Fetch the complete documentation index at: https://www.floe.one/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Security and Privacy

> Learn what Floe's signaling server and TURN relay can see, how end-to-end DTLS encryption protects file bytes, and how to opt out of stats.

## The short version

Your files travel directly between devices, encrypted end-to-end. Floe's servers broker the connection but never see your file data. The relay server (when used) forwards encrypted packets it cannot read.

## What the signaling server does

The signaling server at `api.floe.one` handles one task: helping two devices find each other so they can connect directly.

It:

* Assigns each peer a role (sender or receiver) within a room.
* Relays the WebRTC offer, answer, and ICE candidates that the two devices exchange to establish a connection.
* Issues short-lived TURN credentials when a TURN server is configured.
* Registers short codes (e.g. `olive-tiger-castle`) that map to room IDs with a 10-minute TTL.
* Keeps a single anonymous running total of bytes transferred, for the public counter on the homepage (see [Aggregate statistics](#aggregate-statistics) below).

It never:

* Receives, stores, or inspects file data.
* Persists room or peer information after the session ends.
* Logs what you transfer, your file names, or to whom.

Once the WebRTC data channel is established, the signaling server plays no further part.

## Aggregate statistics

Floe's homepage shows a public, all-time counter of total bytes transferred across all users. To feed it, the receiving side reports the number of bytes it received after a transfer completes. The sender never reports. The global total is shown only in the browser; the CLI receiver contributes to it but never fetches or displays it.

What is recorded: a single cumulative integer (total bytes, the sum across everyone). Nothing else.

What is not recorded: file names, file contents, per-transfer records, who sent or received, or any link to your identity or IP address. The reported figure is just a size, added to one global running total.

The counter is an honest best-effort metric protected by lightweight guardrails (a per-IP rate limit and a per-report size cap). It is not a tamper-proof audited figure, and reporting never blocks or slows a transfer. Self-hosted instances can leave this disabled, in which case nothing is recorded at all.

**Opting out:** Both the browser receiver and the CLI receiver support opting out.

* Browser: uncheck "Contribute to global stats" on the receiver view before the transfer completes. The preference is saved in your browser and applies to all future transfers from that device.
* CLI: pass `--no-report` to `floe receive` for a single transfer, or set `FLOE_NO_STATS=1` in your environment to opt out permanently. When opted out, no request is made to the server and the counter is not incremented.

## The room secret stays in the URL fragment

Share links use a URL fragment (`https://floe.one/#room=...`), not a query string. The fragment portion of a URL is handled entirely by the browser and is never sent to any server in HTTP requests. As a result, the room secret is not included in `Referer` headers when you click outbound links, is not visible to server access logs, and is not captured by pageview analytics or third-party trackers. The signaling server only sees the room ID after the browser explicitly joins the room over the WebSocket, and even then, file bytes never reach the server.

## What the TURN relay sees

When a direct connection cannot be established (strict firewalls, carrier-grade NAT), Floe routes traffic through a TURN relay server. The relay server acts as a forwarding intermediary. On floe.one, the relay is Cloudflare's Realtime TURN network; self-hosted instances can run their own coturn relay instead.

The relay sees: encrypted DTLS packets.

It does not see: the plaintext contents of those packets. File data is encrypted before it reaches the relay, and decrypted only on the recipient's device. The relay cannot read, store, or inspect your files.

See [Relay Connection](/docs/how-it-works/relay-connection) for more detail.

## End-to-end encryption

Every WebRTC data channel is encrypted using **DTLS** (Datagram TLS), which is built into the WebRTC standard.

Key properties:

* Encryption keys are generated uniquely for each transfer session.
* Keys exist only on the two devices involved. There is no central key server.
* Keys are ephemeral. They are discarded when the connection closes and cannot be recovered.
* The DTLS handshake verifies each peer's certificate against the fingerprint exchanged during signaling, so an outside attacker on the network cannot inject a different certificate. Like every WebRTC application, Floe trusts the signaling server to relay those fingerprints faithfully. Running your own instance removes that dependency entirely (see [Self-hosted instances](#self-hosted-instances)).

See [End-to-End Encryption](/docs/how-it-works/encryption) for a deeper technical explanation.

## Self-hosted instances

All of the above applies to self-hosted instances as well. The signaling server and TURN relay are architecturally incapable of receiving plaintext file data regardless of who operates them. If you run your own instance, you get the same encryption guarantees, and you control the infrastructure entirely.

See [Self-Hosting](/docs/self-hosting/overview) to run your own instance.

## Reporting a vulnerability

If you discover a security issue in Floe, please report it privately via [GitHub Security Advisories](https://github.com/jannskiee/floe/security/advisories/new) or the contact listed in [SECURITY.md](https://github.com/jannskiee/floe/blob/main/SECURITY.md). Do not open a public issue, as that may expose the vulnerability before a fix is available.
