rilo
Lis, maskotka Rilo, stoi obok tarczy z kłódką

Przejdźmy do techniki.

Wszystko, co mówi strona główna, wypisane jako to, z czego powstało: prawdziwa baza danych, sposób, w jaki naprawdę powstaje kontakt, i kto jeszcze styka się z rozmową.

Nie musisz czytać tej strony, żeby używać Rilo, i nic tu nie przeczy prostszej wersji. To ten sam produkt, opisany dokładnie.

Cała baza danych

Wszystko, co nasz serwer wie o twojej rodzinie.

To nie streszczenie. To siedemnaście tabel, które ma serwer, z kolumnami, które w nich są. Cztery dotyczą twojej rodziny: kim są, kto może działać za dziecko, z jakich telefonów mówią i gdzie do nich zadzwonić. Cztery przechowują coś dla telefonu, który był wyłączony, i wszystkie cztery same się usuwają. Trzy mówią o tym, kto może działać za dziecko i który telefon przestał być zaufany. Dwie to podpisane zapisy końca, zerwanego kontaktu albo kogoś, kto odszedł. Zostają, żeby telefon, który był offline, mógł je sprawdzić, a nie wierzyć nam na słowo. Jedna to zużyte jednorazowe liczby, sprzątane, gdy tracą ważność. Jedna to subskrypcja i nie ma w niej niczego, co kogokolwiek nazywa. Jedna to zgłoszenie, które przysłał nam dorosły, i tylko ta jedna tabela istnieje po to, żeby coś się stało. Ostatnia w ogóle nie dotyczy twojej rodziny.

accounts przechowywane, dopóki tego nie usuniesz
  • idskrót klucza publicznego, nie imię
  • public_keyklucz urządzenia, który jest kontem
  • typedorosły albo dziecko
  • type_certpodpis, który to potwierdza. Konto dziecka podpisuje rodzic, więc nie ma tu żadnej flagi do przestawienia
  • created_at
  • last_activeostatni raz, kiedy któryś z twoich telefonów powiedział cześć
  • dormant_warned_atpuste
  • consent_sealedtwój e-mail z rejestracji, zapieczętowany kluczem, który leży na papierze u założyciela. Żaden serwer go nie odczyta
  • uncovered_sincepuste, chyba że twój plan przestał obejmować to dziecko — wtedy dzień, w którym to zauważyliśmy, żeby miesiąc przed tym, jak cokolwiek przestanie działać, liczył się od tego dnia
Wiersz twojego konta zostaje, dopóki go nie usuniesz, a usunięcie w aplikacji zabiera ten wiersz i wszystko, co do niego przypięte. Pracujemy nad sprzątaniem rodzin, które przestały używać Rilo w ogóle. Dopóki tego nie włączymy, nic tutaj nie odchodzi samo.
server_state przechowywane
  • keyco jest zapamiętywane
  • valuei co z tego wynika
Jedyna tabela, która w ogóle nie dotyczy twojej rodziny. Dziś jest w niej jedna rzecz, moment, w którym ta wersja serwera uruchomiła się po raz pierwszy. Każde pytanie o to, kto zamilkł, liczy się od tamtej chwili, więc baza zapisana wcześniej, gdy nie umieliśmy tego zauważyć, nigdy nie zostanie odczytana jako miesiące ciszy.
guardians przechowywane
  • account_id
  • guardian_keyklucz, który może działać za to dziecko
  • added_at
  • removed_at
Usunięcie zostaje odnotowane, nie wymazane. Kontakty sprawdzamy wobec tego, kto był opiekunem w chwili podpisania kontaktu, więc rodzic odchodzący z konta nie zrywa po cichu każdej przyjaźni, na którą kiedyś się zgodził.
devices przechowywane
  • account_id
  • device_keywłasny klucz jednego telefonu. Człowiek może mówić z więcej niż jednego
  • agreement_keyklucz, którym pieczętuje się wiadomość, żeby otworzył ją tylko ten telefon
  • certpodpis, który wpuścił ten telefon, zachowany słowo w słowo, żeby twój telefon mógł go sprawdzić, a nie wierzyć nam na słowo
  • kindtelefon albo wydrukowana kartka odzyskiwania
  • added_at
  • removed_at
Telefony i tablety, z których mówi jedna osoba. Mówi, ile urządzeń ma twoja rodzina, i zupełnie nic o tym, z kim rozmawiacie, dokładnie tak jak dwie tabele powyżej. Telefon wpuszcza podpis urządzenia, które już jest na liście, nigdy my, a ten podpis zostaje tutaj, żeby każdy telefon mógł go sprawdzić, a nie wierzyć liście. Wycofanie telefonu odnotowuje wiersz, zamiast go wymazywać, z tego samego powodu, dla którego odnotowujemy odejście dorosłego: wszystko, co podpisał, gdy był twój, musi dać się dalej sprawdzić.
push_tokens przechowywane
  • account_id
  • device_keyktóry z twoich telefonów ten dzwonek uruchamia
  • platformapns albo fcm
  • tokennic nieznaczący identyfikator od Apple albo Google
  • updated_at
Jeden na urządzenie, żeby połączenie mogło zadzwonić w śpiącym telefonie. Powiadomienie nie nosi ani imienia, ani treści.
used_nonces sprzątane
  • nonce
  • expires_at
Lista jednorazowych liczb, które już zostały zużyte, żeby przechwycone żądanie nie dało się odtworzyć drugi raz. Usuwana, gdy traci ważność.
denied_edges sprzątane
  • edge_hashskrót pary, nie dwóch osób
  • denied_at
  • expires_at
Kiedy dorosły mówi nie na przedstawienie kogoś, to nie zostaje zapamiętane na trzy dni, żeby telefon drugiego rodzica, wtedy wyłączony, nie dokończył sprawy przez przypadek. Świeże zeskanowanie między tymi samymi rodzinami czyści to wcześniej. Bez imion, bez kluczy: skrót i dwie daty.
pending_grants sprzątane
  • edge_hashskrót pary, nie dwóch osób
  • grant_recordzgoda, o której się rozstrzyga, i podpisy zebrane do tej pory
  • waiting_keyczyjego podpisu jeszcze brakuje
  • requested_bytelefon, który zapytał, żeby jeden telefon nie zalał rodziny pytaniami
  • originzeskanowane na miejscu albo rodzic działający za dziecko
  • delivered_toktóre telefony już to mają
  • declaredwłasna nazwa strony, która pyta, zapieczętowana tak, że odczyta ją tylko rodzina, którą zeskanowano
  • created_at
  • expires_at
To jedyne miejsce, w którym serwer trzyma cokolwiek podobnego do sieci znajomości, i trzyma to tylko dopóki poznanie jest niedokończone. Nikt nie odpowiedział w ciągu 72 godzin: sprawa przepada. Ktoś odpowiedział, ale telefon, dla którego to było, nigdy nie wszedł do sieci: 30 dni. Gdy oba telefony mają już gotowy kontakt, wiersz jest usuwany. Dlatego na tej stronie nie ma tabeli kontaktów. Nie ma żadnej tabeli kontaktów.
messages usuwane po dostarczeniu
  • id
  • recipient_idżeby coś przekazać, ta jedna musi być czytelna
  • recipient_devicedla którego z ich telefonów paczka jest zapieczętowana. Każdy telefon ma własny klucz, więc każdy dostaje własną paczkę
  • sender_idżeby telefon wiedział, czyim kluczem to otworzyć
  • sender_devicektóry z ich telefonów to zapieczętował, żeby właściwa kopia trafiła na właściwy zamek
  • edge_hashpara, w postaci skrótu, żeby nie dało się tego odczytać jako mapy tego, kto z kim rozmawia
  • sealedszyfrogram. Nie ma tu kolumny z tekstem i nigdy nie będzie
  • sent_at
  • expires_at
Telefon jest wyłączony przez większość dnia, a wiadomość, która po cichu znika, to zepsuty produkt. Więc zapieczętowana paczka czeka tutaj: najwyżej 30 dni i usuwana w chwili, gdy odbiorca potwierdzi, że ją ma. Nie umiemy jej otworzyć.
revocations przechowywane
  • edge_hashpara, w postaci skrótu
  • revoked_at
  • recordpodpisany zapis, żeby telefon, który był offline, mógł sam sprawdzić zerwanie, a nie wierzyć nam na słowo
Jedyna rzecz, którą trzymamy bez końca. Zapisuje, że kontakt został zerwany, nie będąc czytelną listą tego, kto kogo znał.
roster_changes przechowywane
  • id
  • account_idczyja lista telefonów i dorosłych się zmienia
  • kinddołącza albo jest usuwany
  • subject_keytelefon albo dorosły, o którego chodzi
  • subject_kindktóre z tych dwóch
  • agreement_keydrugi klucz, którego potrzebuje telefon, puste dla papieru
  • recordsam podpis, zachowany słowo w słowo, żeby telefon mógł go sprawdzić, a nie wierzyć nam na słowo
  • signed_byktóry klucz to podpisał
  • by_authorityczy podpisała to kartka odzyskiwania, i to właśnie każe temu czekać
  • issued_atmoment, który podaje podpisujący, nigdy nasz zegar
  • reasonpuste, chyba że podpisujący coś napisał
  • proposed_at
  • effective_atkiedy staje się prawdą, dwie noce po zaproponowaniu
  • contested_at
  • contested_bykto się sprzeciwił i podpis, którym to zrobił
  • contest_record
  • resolved_at
  • resolutionzastosowane albo odwołane, gdy się rozstrzygnie
Te dwie noce między podpisaniem zmiany wśród dorosłych dziecka a chwilą, w której zmiana staje się prawdą. Telefon dołączający do rodziny albo wyrzucany z niej czeka tutaj, gdzie każdy inny telefon na koncie może go zobaczyć i zaprotestować. Wiersz zostaje po rozstrzygnięciu, bo telefon, który był wyłączony, musi umieć sprawdzić, co się stało, a nie wierzyć nam na słowo. Trzyma konto i klucze, o które chodzi, czyli więcej niż większość tabel tutaj.
roster_change_votes przechowywane
  • change_idktórej czekającej zmiany
  • voter_keyktóry dorosły
  • decisionprzepuścić albo zatrzymać
  • recordjego podpis
  • at
Jeden wiersz na dorosłego, a nie licznik. Większość dorosłych dziecka może zakończyć dwunocne czekanie wcześniej, a pytanie o większość trzeba zadać na nowo, wobec dorosłych, którzy są teraz. Ktoś, kto odszedł, nie jest głosem, a licznik nie umiałby tego odróżnić.
device_revocations przechowywane
  • account_idczyj to był telefon
  • device_keyklucz, który został ukradziony
  • revoked_at
  • recordpodpisany dowód, żeby telefon mógł go sprawdzić, nie pytając nas
Ukradziony telefon, i różnica między tym a wycofaniem telefonu. Wycofanie znaczy, że od teraz nie może działać, i to jest właściwa odpowiedź dla telefonu, który ktoś wymienił. To znaczy: nie ufaj niczemu, co kiedykolwiek podpisał, a inne telefony muszą umieć to sprawdzić, nie pytając nas. Wiersz dostaje tylko kradzież.
retirements przechowywane
  • account_idkonto, którego już nie ma
  • retired_at
  • recordpodpisany dowód, zrobiony własnym kluczem tego konta, zanim klucz został zniszczony
Lista nieobecności, a dobra wiadomość jest w drugiej kolumnie. Kiedy ktoś odchodzi z Rilo, telefony jego znajomych dostają podpis zrobiony własnym kluczem tej osoby. Rodzina dowiaduje się o odejściu z dowodu, a nie z naszego zapewnienia. Nic, co powiemy sami z siebie, nie zdejmie twarzy z ekranu twojego dziecka. To jedyna tabela bez odnośnika do konta, bo musi przetrwać to konto, którego dotyczy.
entitlements przechowywane
  • account_id
  • storeapple, google albo na koszt firmy
  • store_refnic nieznaczący identyfikator ze sklepu. Tylko on pozwala nam zadać sklepowi pytanie później
  • store_ref_hashodcisk identyfikatora powyżej. To on nie pozwala, żeby jeden paragon obejmował dwa konta
  • environment
  • stateaktywna, w okresie łaski, wygasła, wygasły okres próbny albo wyłączona
  • seatsile dzieci obejmuje. Liczba, nigdy ich imiona
  • expires_at
  • acts_at
  • updated_at
Nic tutaj nie wskazuje na osobę: żadnego konta w sklepie, żadnego Apple ID, żadnego konta Google, żadnego imienia, e-maila ani karty. To, które dzieci obejmuje płatność, wylicza się z tabeli opiekunów, kiedy trzeba, i nigdy nie zostaje zapisane.
roster_notices sprzątane
  • device_keytelefon, któremu jeszcze tego nie powiedziano
  • change_ido której zmianie mowa
  • whatzaproponowane, zakwestionowane albo rozstrzygnięte
  • account_idczyja lista telefonów się zmieniła. Gdy dorosły dowiaduje się czegoś o swoim dziecku, tutaj jest dziecko
  • subject_keytelefon, który doszedł albo odszedł
  • effective_at
  • created_at
  • expires_at
  • delivered_atkiedy udało się to powiedzieć, albo puste, bo się nie udało
Kolejka, i powód, dla którego dodanie albo usunięcie telefonu dzieje się na głos. Słyszy o tym każdy telefon w rodzinie, a przy dziecku także każdy dorosły, który za nie odpowiada, włącznie z telefonem właśnie usuniętym. Tak ktoś, kto nie powinien go mieć, dowiaduje się, że to zauważyliście. Powiadomienie nie zawiera niczego, czego nie ma sama zmiana, i jest usuwane, gdy traci ważność, niezależnie od tego, czy udało się je dostarczyć.
reports przechowywane
  • id
  • about_keykogo dotyczy zgłoszenie. Czytelne, żeby ktoś mógł coś z nim zrobić
  • reasonktóra z sześciu rzeczy się stała, tak jak wybrał to zgłaszający dorosły
  • csa
  • sealedco zostało napisane, zapieczętowane na telefonie, który to wysłał, kluczem leżącym na papierze u założyciela. Żaden serwer tego nie odczyta
  • sealed_digestodcisk zapieczętowanej części, żeby to, co ktoś otworzy później, dało się udowodnić jako to, co przyszło
  • received_at
  • edge_snapshotkto miał pozwolenie sięgnąć do kogo i który dorosły na to pozwolił, w takim stanie, w jakim było w tamtej chwili. Tego jednego nie da się później odtworzyć
  • reporter_keykto to wysłał, albo zupełnie nic, gdy wysłano bez nazwy
  • source
  • sealed_key
  • receiptnumer, który zostaje u wysyłającego. To jedyny sposób, żebyśmy mogli komuś odpowiedzieć w sprawie zgłoszenia, którego nie umiemy otworzyć
  • acknowledged_at
  • decided_at
  • actioned_at
  • escalated_at
  • decided_by
  • outcome
Jedyna tabela, która istnieje po to, żeby coś się stało. Większość zgłoszenia jest zapieczętowana na telefonie, który je wysłał, i nie umiemy tego otworzyć. Czytelne zostaje to, kogo dotyczy, bo zgłoszenie, z którym nikt nic nie może zrobić, nie chroni nikogo. Przetrwa konto, którego dotyczy. Inaczej każdy mógłby usunąć siebie z takiego zgłoszenia. Nie ma w nim nagrania żadnej rozmowy, ani tu, ani nigdzie, bo żadne nigdy nie powstaje.

Kolumny, których nie ma

  • e-mail
  • imię
  • wiek
  • zdjęcie
  • treść wiadomości
  • treść rozmowy
  • historia połączeń
  • lista kontaktów
  • lokalizacja
  • model urządzenia

Twój adres e-mail sprawdzamy raz przy rejestracji i w tym samym ruchu pieczętujemy kluczem, który leży na papierze u założyciela i nigdy nie dotknął żadnego serwera. Prawo wymaga, żebyśmy umieli dowieść, że zgodę wydał dorosły. Sami nie odczytalibyśmy tego z powrotem. Imiona i zdjęcia ustawia się na każdym telefonie osobno i przekazuje wprost na drugi telefon. Nigdy do nas nie docierają, i dlatego możesz zmienić dziadkowi imię na “Dziadzio”, a my nigdy się o tym nie dowiemy. Nie moglibyśmy tego nikomu pokazać, nawet gdybyśmy chcieli, i nikt nie może nas do tego zmusić.

Ta sekcja jest generowana ze schematu samego serwera, z plików accounts.ts i roster-changes.ts, tych dwóch, które tworzą bazę danych. Jeśli kiedyś się rozejdą, racja jest po stronie plików, a ta strona jest błędem.

Kontakty

Jak naprawdę powstaje kontakt.

Czyjś telefon tworzy jednorazowe zaproszenie. Drugi telefon je odczytuje, zeskanowane z ekranu w tym samym pokoju albo otwarte z linku, który wysłał dorosły. Odczytanie zaczyna poznanie i w tej samej chwili zapisuje klucz publiczny drugiego telefonu, więc od tego momentu oba telefony wiedzą dokładnie, który klucz należy do której osoby. To właśnie ta część sprawia, że w późniejszą rozmowę nie da się wcisnąć nikomu, także nam. Nic z tego nie zostaje połączone, dopóki dorosły z drugiej strony nie powie tak.

To jeszcze nie kontakt. Odpowiedzialny dorosły musi podpisać kontakt na własnym telefonie, za sprawdzeniem odciskiem palca albo twarzą wykonanym w tej właśnie chwili. Podpisuje całość. Kto, z kim i w którą stronę. Serwer sprawdza ten podpis, zanim cokolwiek przekaże. Serwer nie ma żadnego klucza, którym mógłby podpisać, więc nie stworzy kontaktu, i nie stworzy go też nikt, kto ukradnie bazę danych.

Gdy oba telefony mają gotowy kontakt, wiersz jest usuwany, a kontakt istnieje tylko na tych dwóch urządzeniach. Późniejsze zerwanie zapisuje podpisane unieważnienie, i to jedyny zapis, który trzymamy bez końca. Leży jako skrót pary, więc mówi, że kontakt się skończył, nie mówiąc, kto kogo znał.

Kto jeszcze bierze w tym udział

Trzy firmy stykają się z rozmową. Żadna jej nie usłyszy.

Z usługą styka się sześć innych firm i wszystkie są wypisane w polityce prywatności. Trzy z nich biorą udział w tym, żeby rozmowa mogła zadzwonić, i tak wygląda to, co każda z tych trzech widzi, a czego nie.

  • Apple & Google

    Powiadomienia push, żeby połączenie zadzwoniło w śpiącym telefonie. Na obu platformach nie da się ich uniknąć. Niosą nic nieznaczący identyfikator i nic więcej. Bez imienia, bez numeru, bez treści.

  • Cloudflare

    Mniej więcej jedna rozmowa na sześć nie łączy dwóch telefonów wprost, na hotelowym Wi-Fi albo w niektórych sieciach komórkowych, i idzie przez przekaźnik. Przekaźnik przekazuje zaszyfrowane pakiety, których nie umie otworzyć, ale widzi, że dwa anonimowe identyfikatory zostały połączone, kiedy, na jak długo i z jakich adresów. To metadane, których my nie przechowujemy, trzymane przez kogoś innego.

  • My

    Tabela powyżej. Jeden mały serwer w Holandii, który przedstawia sobie dwa telefony i potem schodzi im z drogi.