> ## Documentation Index
> Fetch the complete documentation index at: https://help.xitter.space/llms.txt
> Use this file to discover all available pages before exploring further.

# Encrypted chat

> End-to-end encrypted messages and passcode recovery with Juicebox.

Chat encrypts messages and attachments in the browser. Xitter keeps only ciphertext, public keys, membership and event history.

* Images, videos and files are stored as multipart ciphertext under `MEDIA_DIR/chat`. Downloads require membership.
* Requests from accounts you don't follow stay separate until accepted.
* Group creation, membership changes, edits, reactions, read receipts and typing use the pinned client's XChat events.

## Passcode recovery

Passcode recovery requires a [Juicebox](https://github.com/juicebox-systems) software realm. `deploy/juicebox` builds upstream commit `2e485aac584a6c9ada1fb9f156dc4d7cad3ab338` with a PostgreSQL provider patch. It is also AGPL.

The realm stack has its own persistent PostgreSQL volume and binds the realm to `127.0.0.1:8580`, with no public database port.

**1. Generate chat secrets**

Start Xitter once. It writes `data/chat-secrets.json`.

**2. Prepare the realm configuration**

From the project root:

```sh theme={null}
bun scripts/prepare-realm.ts deploy/juicebox
```

This writes `realm.env`, which is ignored by Git. The script refuses to overwrite an existing configuration.

**3. Start the realm**

```sh theme={null}
docker compose -f deploy/juicebox/compose.yaml -p xitter-juicebox up --build -d
```

With [Docker Compose](/self-hosting/docker), you can instead add `--profile keybackup` to `docker compose up`.

If Xitter runs inside Docker, connect it to the realm's network and set `JUICEBOX_URL=http://realm:8580`. Browsers keep using Xitter's authenticated same-origin proxy at `/juicebox/`.

> [!WARNING]
>
> Keep the realm ID, signing secret and database password stable, and back up the realm's PostgreSQL volume together with its configuration. Changing the realm ID or losing its database prevents recovery of existing chat keys.

The local development realm and a server realm have separate record stores. Starting a server realm does not transfer local backups.

## Moving accounts

Encrypted chats stay behind when an [account moves](/self-hosting/moving-accounts), since their keys never leave the browser.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.