Let’s get technical.
Everything the front page says, written out as the thing it was built from: the real database, how a contact is actually made, and who else touches a call.
You do not need this page to use Rilo, and nothing here contradicts the simpler version — it is the same product, described precisely.
The whole database
Everything our server knows about your family.
Not a summary. These are the seven tables, with the columns they actually have. Four of them are the account; three exist so that a phone which was switched off does not miss anything, and two of those delete themselves.
- ida hash of the public key — not a name
- public_keythe device key that is the account
- typeadult or child
- type_certthe signature proving it — a child account is signed by a parent, so there is no flag to flip
- created_at
- last_active
- account_id
- guardian_keya key allowed to act for this child
- added_at
- removed_at
- account_id
- platformapns or fcm
- tokenan opaque handle from Apple or Google
- updated_at
- nonce
- expires_at
- edge_hasha hash of the pair, not the two people
- grantthe permission being decided, and the signatures collected so far
- waiting_keywhose signature is still missing
- requested_by
- originscanned in person, or a parent acting for their child
- created_at
- expires_at
- delivered_towhich sides already have it
- id
- recipient_idrouting needs this one in the clear
- sender_idso the phone knows whose key opens it
- edge_hashthe pair, hashed, so this cannot be read as a map of who talks to whom
- sealedciphertext. There is no text column and there never will be one
- sent_at
- expires_at
- edge_hashthe pair, hashed
- revoked_at
- recordthe signed record, so a phone that was offline can verify the cut itself rather than taking our word for it
Columns that do not exist
- name
- age
- photo
- message text
- call content
- call history
- contact list
- location
- device model
Your email is checked once when you sign up and destroyed in the same breath — there is no column to put it in. Names and photos are set on each phone and handed to the other phone directly; they never reach us, which is also why you can rename Grandpa to “Opa” and we will never know. We could not show any of this to anyone if we wanted to, and we could not be made to.
This section is generated from server/src/identity/accounts.ts — the file that creates the database. If the two ever disagree, the file is right and this page is a bug.
Contacts
How a contact is actually made.
Somebody shows a one-time code on their phone; the other phone scans it, in the same room. The code expires in ten minutes and works once. That scan does two things at once: it starts the introduction, and it records the other phone’s public key, so both phones know exactly which key belongs to which person from then on. That is the part that makes a later call impossible to sit in the middle of, including for us.
Nothing connects yet. A responsible adult has to sign the contact on their own phone, behind a biometric check made at that moment. What they sign is the whole thing — who, with whom, and in which direction — and their signature is what the server checks before it will route anything. The server holds no key that can sign, so it cannot create a contact, and neither can anyone who steals the database.
When both phones hold the finished contact, the row is deleted and the contact exists only on the two devices. Cutting it later writes a signed revocation, which is the one record kept indefinitely — stored as a hash of the pair, so it says that a contact ended without saying who knew whom.
Who else is involved
Three companies touch a call. None of them can hear it.
Three companies are involved in getting a call to ring. Here is what each of them can and cannot see.
-
Apple & Google
Push notifications, so a call rings a phone that is asleep. Unavoidable on both platforms. They carry an opaque identifier and nothing else — no name, no number, no content.
-
Cloudflare
Roughly one call in six cannot connect the two phones directly — hotel Wi-Fi, some mobile networks — and is bounced through a relay. The relay forwards encrypted packets it cannot open, but it does see that two anonymous ids were connected, when, for how long, and from which addresses. That is metadata we are proud not to keep, held by somebody else. We would rather write it here than let you discover it in a policy.
-
Us
The table above. One small server in the Netherlands that introduces two phones and then gets out of the way.