Run a relay
Saivo is built to be self-hosted. One relay can serve a family, a team or a community. This page is for the person who runs it.
Turn the panel on
The panel is a second, private listener. It is never reachable through the public relay port or through Caddy.
Docker Compose (deploy/relay/compose.yaml): put these in .env next to it, then docker compose up -d:
SAIVO_ADMIN_TOKEN=<32 or more letters, digits, - or _>
SAIVO_REGISTRATION=invite # or open (the default)
Open an SSH tunnel from your own computer and browse to it:
ssh -L 8766:127.0.0.1:8766 you@your-server
Then open http://127.0.0.1:8766/ and enter the token. Without Docker, run saivo-server with SAIVO_ADMIN_TOKEN set; it listens on 127.0.0.1:8766 (SAIVO_ADMIN_BIND_ADDR changes the port; anything other than loopback is refused outside a container).
What you can do
| Tab | What it does |
|---|---|
| Overview | Connected clients, people known, waiting mail and attachments, whether calls (TURN) are set up. Switch between anyone may join and invited people only. Run expiry now. |
| People | Every mailbox that has signed in: online or not, last seen, waiting mail, push on or off. Add a private label ("Anna"), disconnect, block (deletes waiting mail, refuses sign-in and mail), unblock, or remove. |
| Invites | Create a single-use code (optionally expiring in 1, 7 or 30 days) and hand it to one person. Only a hash is stored; the code is shown once. Revoke unused codes. |
| Activity | Who created, used or deleted what, newest first (the last 5000 entries). |
| Connections | Open connections per address against the per-address limit. |
A person enters their invite code under Settings → Relay Server Gateway → Relay URL in the app. The code is used once; after the relay admits that mailbox, the app forgets it. Someone who already joined does not need a code again.
With invited people only, mail for a mailbox that never joined is refused, so strangers cannot fill your disk by writing to made-up mailbox ids.
What the relay cannot do, on purpose
Saivo is end-to-end encrypted. The relay knows pseudonymous mailbox ids, not names, contact lists, groups or message text. So the panel manages who may use the relay, not what they say or which groups they are in:
- Group membership, names and content are known only to group members, and only the group's creator can add or remove members. They cannot be listed or edited from the relay.
- Blocking or removing someone stops their traffic through your relay. It does not remove them from a group, and they can use another relay.
- Labels are yours alone; nobody else sees them.
If you want the operator to see or control groups, that would mean giving up end-to-end encryption for them, which Saivo does not do.
Other settings (environment)
| Variable | Meaning |
|---|---|
SAIVO_MAX_CONNS_PER_IP | Open connections one address may hold (default 64) |
SAIVO_TRUST_PROXY=1 | Use the last X-Forwarded-For entry as the client address (only behind your own proxy). It is honoured only when the connection comes from loopback or from SAIVO_TRUSTED_PROXIES |
SAIVO_TRUSTED_PROXIES | Comma-separated proxy addresses or CIDR ranges allowed to set X-Forwarded-For besides loopback (the Compose file lists the private ranges) |
SAIVO_PUBLISH_IP_BURST, SAIVO_PUBLISH_IP_PER_SEC | Messages one address may send (default 100 at once, then 20 a second) |
SAIVO_PUBLISH_MAILBOX_BURST, SAIVO_PUBLISH_MAILBOX_PER_SEC | Messages one mailbox may receive (default 100 at once, then 20 a second) |
SAIVO_REGISTRATION_IP_BURST, SAIVO_REGISTRATION_IP_PER_SEC | New accounts from one address (default 10, then one a minute) |
SAIVO_MAX_MEMBERS | Accounts open registration may create in total (default 100000). Invite codes you issue are not limited by it |
SAIVO_MAX_VAULTS_PER_MAILBOX | Account copies one account may create (default 2) |
SAIVO_VAULT_CREATE_IP_BURST, SAIVO_VAULT_CREATE_IP_PER_SEC | New account copies from one address (default 2, then one per 10 minutes) |
SAIVO_MAX_CONCURRENT_UPLOADS | Attachment and account-copy uploads handled at the same time; more wait up to 30 s, and each upload must arrive within 4 minutes (default 8) |
SAIVO_PUSH_ALLOW_LOCAL=1 | Allow push endpoints on private addresses or plain http (test networks only) |
SAIVO_TURN_URLS, SAIVO_TURN_SECRET | Your TURN server, for calls across restrictive networks |