Skip to content

Identity keys

This page covers the server’s identity: the Ed25519 key its peer ID is derived from. Keep it stable and backed up; your clients find the server by it.

The server’s identity is an Ed25519 key pair. Its peer ID, the 12D3KooW... string at the end of the server’s multiaddr, is derived from the public key. The same key:

  • authenticates the server in every Noise handshake, so clients know they reached the right server;
  • signs the server’s GossipSub messages, including its service announcements and heartbeats.

It plays no part in encrypting message payloads. End-to-end encryption uses the sending and receiving clients’ keys.

The server takes the first of these that is set:

  1. RICOCHET_SEED_HEX: an environment variable holding a 32-byte Ed25519 seed as 64 hex characters.
  2. An identity file: --identity-file <path>, or server.identity_file in the YAML file.
  3. An auto-generated key at <data-dir>/peer_identity.key. If the file exists, it is loaded. If not, a new key is generated and written there, mode 600, creating the directory with mode 700.

<data-dir> is --data-dir, or storage.data_directory, or ./sf_storage relative to the working directory. The .deb install uses /var/lib/ricochet/sf_storage, so its key is /var/lib/ricochet/sf_storage/peer_identity.key.

An identity file given with --identity-file or identity_file must already exist. The server does not create it, and fails to start with load identity: read identity file: ... if it is missing.

An identity file may hold either of:

  • a 32-byte seed: raw bytes, 64 hex characters, or 44 base64 characters;
  • the 64-byte raw private key that the auto-generation writes.

To create a seed file yourself:

Terminal window
umask 077
openssl rand -hex 32 > /etc/ricochet/keys/peer_identity.key

openssl rand -hex 32 writes 64 hex characters followed by a newline. Keep the newline: a file of exactly 64 bytes is read as a raw 64-byte private key, not as a hex seed, and does not give you the identity the seed describes. Check the size with wc -c: it should be 65.

Then point the server at it:

/etc/ricochet/config.yaml
server:
identity_file: /etc/ricochet/keys/peer_identity.key

Make the file readable by the user the server runs as, and by no one else. On the .deb install that user is ricochet.

RICOCHET_SEED_HEX takes the same 64 hex characters directly, which suits secret managers and container platforms that inject environment variables. It overrides any identity file.

The server prints Ricochet server <version> running. Peer ID: <peer-id> at startup and logs it in loaded identity and server started. The peer ID is the same on every start with the same key.

Copy the key file somewhere safe as soon as the server has generated it, or keep the seed in your secret store. The key is not in the database: a database backup does not include it.

A new key means a new peer ID. Stored data survives: mailboxes, documents, feeds and collections are keyed by their owners’ peer IDs, not the server’s, and stay in the database. What breaks is everything that names the server:

  • Clients configured with the old peer ID or multiaddr cannot reach the server until you give them the new one.
  • Other servers that list it in bootstrap_peers or security.trusted_peers need the new ID.
  • Other servers’ service-discovery entry for the old ID stops being refreshed and drops out after two hours; the new ID appears with its first announcement. Its uptime score starts again from the checks the restarted process has run.

So rotate the key only when you have to, such as after a compromise, and plan to update every client and peer that names the server.

Every connection is encrypted and mutually authenticated with the Noise protocol. A client that dials the server’s multiaddr checks that the peer it reached holds the key for the peer ID in that address. Someone who steals the key can impersonate the server, so protect it like a TLS private key.

  • The peer ID changed after a restart: the server could not find its key and generated a new one. Usually the working directory or --data-dir changed, or the data directory was wiped. Point the server back at the old key file.
  • parse RICOCHET_SEED_HEX: ... or seed must be 32 bytes, got N: the variable is not 64 hex characters.
  • invalid identity format: ...: the file is not one of the accepted formats.
  • load identity: read identity file: ... permission denied: the server’s user cannot read the file.