Running an XMPP server means holding some of your users' data. Honesty about what is stored, what transits in memory and what could be compromised is not optional — it is the foundation of trust. This document is a full disclosure of what our Prosody instance handles, and what an adversary with full server access could extract.
Data Stored on Disk
Persistent database (Prosody internal storage)
Passwords
Stored as salted hashes via SCRAM-SHA-256. The original password cannot be recovered from the stored data. A brute-force attack against weak passwords remains theoretically possible.
hashed
Roster (contact list)
Stored in plaintext. An adversary with database access can see who is a contact of whom. This is a social graph and constitutes metadata.
plaintext
Message Archive (MAM)
Messages sent without OMEMO are stored in plaintext. OMEMO-encrypted messages are stored as opaque ciphertext the server cannot decrypt.
conditional
Offline messages
Queued when the recipient is offline, delivered and deleted upon reconnection. Without OMEMO, content is briefly stored in plaintext. With OMEMO, only ciphertext is stored.
transient
OMEMO keys (public)
Public identity keys and pre-keys published via PEP. These are designed to be public and do not compromise privacy. Private keys never leave the user's device.
public keys
vCard / Avatar
Display name, avatar image and optional profile fields. Stored in plaintext. If a user sets their real name or photo, this is directly identifying information.
plaintext
MUC room bookmarks
Stored via PEP Native Bookmarks (XEP-0402). Reveals which group chats a user has joined. Metadata only, no message content.
metadata
Data in Memory Only (Runtime)
Present while the server is running — never written to disk with our configuration
IP addresses
Known to the server during an active session for TCP routing. Never written to any log file. Lost on disconnection. Nginx access logs are disabled (access_log off).
not logged
Connection timestamps
The server knows when a user connects and disconnects. This information exists only in process memory and is never persisted.
not logged
Message routing metadata
The server must know sender and recipient JIDs to deliver messages. This is held in memory for the duration of delivery and then discarded.
not logged
Client software / resource
The server sees the client name (Gajim, Profanity, etc.) and resource string during the session. Not persisted.
not logged
Presence status
Online/away/DND status and optional status message. Broadcast to subscribed contacts in real time, not stored.
not logged
Data the Server Never Sees
Protected by end-to-end encryption (OMEMO)
OMEMO message content
Encrypted on the sender's device, decrypted on the recipient's device. The server transports ciphertext it cannot read. Even with full database access, an adversary cannot recover message content.
encrypted
OMEMO private keys
Generated and stored exclusively on the user's device. The server has no mechanism to request or access them.
client-side
File content (OMEMO-encrypted transfers)
When files are sent via OMEMO + HTTP Upload, the server stores an encrypted blob. Without the symmetric key (shared via OMEMO), the file content is unrecoverable.
encrypted
Worst Case: Full Server Compromise
If an adversary gains root access to the server, they can extract:
What is exposed
User list
All registered JIDs (usernames) are visible in the database.
Social graph
The roster reveals who is a contact of whom. This is the most sensitive metadata the server holds.
Profile data
Any vCard information the user has published (display name, avatar).
Unencrypted MAM messages
Only if the user enabled MAM and sent messages without OMEMO. Expires after 7 days.
What remains protected even with full server access
OMEMO-encrypted messages
Ciphertext only. Useless without client-side private keys.
Passwords
Hashed. Weak passwords could be cracked offline, strong passwords cannot.
Historical IP addresses
Never logged. No forensic trail exists.
Historical connection times
Never logged. No session history exists.
Bottom line
With OMEMO enabled, the server is a blind relay. It transports ciphertext it cannot read, between users it does not log. The only actionable data an adversary could extract is the social graph (roster) and any unencrypted MAM content within its 7-day window. Use OMEMO. Always.
User recommendations
Enable OMEMO encryption in your client for all conversations. Do not enable MAM unless you need multi-device sync, and if you do, ensure OMEMO is active so the archive contains only ciphertext. Use a pseudonymous JID. Do not put identifying information in your vCard or avatar. A server can only protect what it does not have.