Open Free and open source, read the code Get it Donate App help Contact
Messenger
The app
Developers
Project
Legal

A flamenet.io account is not a Flamenet Messenger account. The two sign-ins are separate.

Roadmap

What is not done, in roughly the order it matters. Listed here rather than left for someone to discover in the source. Items move to features when they ship, not when they are started.

Nothing countersigns the key log

Every device key this server hands out is committed to an append-only log, and the head of that log is signed so that two people who compare heads can prove the server showed them different histories. That check works, and it is what §19.4a calls gossip.

What it does not have is a second opinion. This server holds the key that signs its own log. Against an operator who wanted to lie, that signature is not testimony, it is whatever they chose to write: it binds them only once somebody else is holding a differently-signed head of the same size. A person who has never compared heads with anyone has only our word, signed by us.

The usual answer is a witness, an independent party that countersigns each head so a client can tell somebody else saw the same tree. The route serves a witnesses field and it is always empty, because there is no way to submit a co-signature and no client reads the field. We would rather say that than leave the empty list to be discovered. Closing it needs three things and only the first is code: a submission route and a configured set of witness keys, a client that refuses to treat an unwitnessed head as though it were witnessed, and somebody other than us willing to run the witness. The third is the one that makes it real, and it is the reason this is not simply built.

Your address depends on one server staying up

Your address comes from your passphrase, which is what lets you sign in somewhere else and still be you. That is true of the passphrase and not quite true of the address: the derivation also takes a salt, the salt is generated when you register, and it is kept by the account service and handed back every time you sign in. It is never written to your phone.

So two things follow that the rest of this site does not say plainly enough. If that one service goes away, your passphrase alone does not reconstruct your address, and losing a server costs an identity rather than a mailbox. And a hostile account service can hand you a different salt: you would derive a different address, sign in successfully, and be somebody else. The app now tells you when the address it derives is not the one this device had, which makes that visible rather than silent, and visible is not the same as fixed.

The fix is a custody change and each option costs something real. Deriving the salt from your handle removes the dependency and weakens per-account salting. Keeping the salt on the device breaks signing in on a new phone with nothing but a passphrase, which is the property the whole scheme exists for. We are not going to pick quietly.

Cutting off one person without a stable name for them

Blocking a single sender used to mean changing the key everyone uses and handing the new one to every contact you still wanted to hear from, so in practice nobody ever did it. On Android, out now, each contact gets their own book of one-use tickets, and cutting one person off is tearing up their book. Nobody else notices, and the server sees a different ticket every time rather than one name it can follow you by.

What is left is the part the specification calls for and this does not do. A server that keeps a note of when each ticket was handed in could group a book together, and that is one sender; and tearing a book up tells it those tickets belonged together. Closing both needs a piece of mathematics, §21 names it, that proves you are allowed to write to somebody without revealing which permission you hold. We would want somebody who has built that before to read ours before it went near a real conversation, because the failure mode is that it quietly accepts everything.

Getting a bridge where we are blocked

Both apps have a bridge setting: paste in a bridge line and the app connects through it, disguising the connection so it does not look like a messenger. Today that line has to come from somebody who already has one. The only bridge runs on our own address, and nothing in the app lets you ask for one. On Android you can pass a line to a contact inside a chat; on iPhone that part is not wired up yet.

The plan is a pool of bridges spread across separate providers, a way to ask for one from inside the app that still works when our own servers are blocked, and taking a bridge out of circulation once it is blocked. Before any of that, we want to see a full conversation carried over a bridge from a blocked network, on both phones. That test comes first.

Traffic that does not look like a messenger

A bridge changes what the bytes look like. It does not change their rhythm: how big the packets are and when they are sent still looks like somebody messaging, and blocking systems already use traffic statistics like these to spot circumvention tools. The plan is to shape the traffic so its sizes and timing match ordinary background traffic, within a data and battery budget you choose. Every release would be measured against the kind of classifier a censor uses, and the detection rates published. A number somebody can check, not a promise.

Never falling back to a direct connection

With a bridge set, not everything goes through it yet. On iPhone, a few requests made before you sign in go direct, and if the app's own bridge component fails to start, it connects without it. For most people that is a convenience. For somebody on a network that punishes using a messenger at all, a quiet direct connection is the worst thing the app could do. The plan is a setting that makes the bridge all or nothing: if it is down, the app stops and says so.

Knowing when a bridge has been blocked

We cannot see from here whether a bridge still works in another country. Your phone can: it knows when a bridge that used to connect stopped. The plan is for the app to note that and, the next time it gets through, report which bridge failed and nothing else. No account, no location. A bridge that is reported blocked stops being handed out where it is blocked.

Getting your account back without a phone number

Signing up takes no phone number and no email, which also means there is nothing to recover an account through. Lose your passphrase and the account is gone. The plan is to let you split a recovery key among contacts you choose, so that a set number of them together can restore your account and no single contact, and no server, can. The hard parts are contacts who are offline for days, and contacts who are pressured to cooperate. We want the design read by somebody else before it ships.

Checking our own claims on every release

The security page says what we claim and what we do not. Today those claims are checked by hand. The plan is a check that runs on every release, compares what the pages say with what the code does, and publishes the result next to the release notes.

External audit

No third-party audit has been done. This is the one item on this list that cannot be closed by writing code, it needs a firm and a budget, which is what donations are for.

What has been done is the preparation: a scope document setting out the trust boundaries, the assets in order of consequence, what is deliberately out of scope, and five falsifiable claims we would like attacked. Auditors spend their first hours working out what a system is; that part is now given away rather than paid for twice.

Free and open source · No ads · No phone number · Your own server if you want one