ATProto: разработчик раскритиковал протокол за разделение данных на публичные и приватные

Автор материала «Building on ATProto» (блог lukekanies.com) съездил на конференцию Local First в Берлине и обнаружил, что там едва ли не каждый обсуждает протокол ATProto, «атмосферный протокол» Bluesky, хотя ожидал в первую очередь разговоров про ИИ в разработке. Он уже несколько месяцев присматривается к тому, чтобы строить приложения на ATProto, и использовал поездку, чтобы расспросить и тех, кто уже строит на протоколе, и самих разработчиков Bluesky. Его вывод: ATProto мог бы стать основой для целого поколения совместимых друг с другом приложений с общим форматом данных, но, по его мнению, нынешнее и предлагаемое развитие протокола ведёт не туда.

Свой замысел он поясняет на примере приложений для отзывов, своего рода замены Yelp, GoodReads и Letterboxd. Дело не в функциях этих сервисов, а в их бизнес-модели: в Yelp у него скопилось больше тысячи закладок, но по сути они ему не принадлежат, их нельзя ни выгрузить, ни опубликовать где-то ещё, ни поделиться ими, ни обработать скриптом, ни вести историю их изменений: это данные Yelp, а не его. Он хочет, чтобы разные приложения, одно для написания отзывов, другое для публикации подборок, третье для личного сайта, работали с одной общей моделью данных, а не запирали их каждое у себя. Это классический случай локально-ориентированного подхода (в оригинале, local-first): пользователь сам распоряжается данными, а не отдаёт их одному сервису навсегда.

Вторая причина связана с разграничением публичного и приватного. Жена автора никогда не станет публиковать отзывы в открытую, но готова записывать их для семьи. Сам он иногда публикует отзывы открыто, а иногда нет: то, что он написал бы для себя о ресторане, отличается от того, что готов сказать всему миру, а большинство сервисов такой границы не проводят, отзыв там по умолчанию публичный и влияет на репутацию заведения, даже если автор этого не хотел. Он делит пользователей на три группы: тех, кто пишет отзывы, только если их прочитают другие; тех, кто, как он сам, готов и на публичное, и на приватное, по ситуации; и тех, кто, как его жена, согласен писать отзывы, только если уверен, что их увидят исключительно близкие или вообще никто. По его оценке, нынешние приложения обслуживают только первую группу, а вторая и третья, гораздо многочисленнее.

Сильная сторона ATProto, признаёт автор, это система идентичности: по его словам, это первый протокол, который решает задачу идентичности в масштабе, беря на себя авторизацию, подписчиков и подписки и прочее, что нужно почти любому приложению. Идеальной он её не считает (хотел бы, чтобы идентификаторы были понятнее человеку), но она достаточно зрелая, на Local First её упоминал почти каждый спикер, и она избавляет разработчиков от необходимости заново изобретать граф подписок и систему авторизации в каждом отдельном приложении.

А вот остальная часть протокола, по мнению автора, для его целей пока малоприменима. Сегодня ATProto, протокол «только для публичного»: он изначально исходит из того, что всё, что вы делаете, публикуется в открытый доступ, и это заложено на уровне и хранилища, и сервисов публикации. Сообщество сейчас проектирует то, что называет «данными с разрешениями» (permissioned data); сам автор считает такое название неудачным и предлагает называть вещи проще, «приватные данные». Проблема не в названии, а в архитектуре: по логике одного из постов о дизайне, публичные и приватные данные, это принципиально разные категории, и автор с этим категорически не согласен. Его довод: отзыв о ресторане остаётся отзывом о ресторане независимо от того, увидит его весь мир или только он сам, публикация для всех и полное молчание тут просто две крайние точки одного и того же спектра прав на чтение.

Поскольку ATProto уже обслуживает работающий вживую Bluesky как исключительно публичный протокол, встроить в него контроль доступа задним числом сложно. Вместо этого сообщество, по наблюдению автора, спроектировало для приватных данных, по сути, отдельную и независимую систему: она опирается на ту же систему идентичности и на те же lexicons (описания типов данных), но добавляет полностью новые структуры данных и новые способы их проверки. В результате разработчику приложения приходится писать фактически два приложения, одно для публичных данных, второе для приватных, хотя для пользователя это один и тот же тип контента («это отзывы о ресторанах, они должны быть вместе»). Получается неаккуратно: если приватную запись нужно сделать публичной, её не редактируют, а удаляют и создают заново уже в публичной подсистеме, неясно, сохранятся ли при этом её лайки, репосты и ссылки на неё; автор прямо пишет, что не знает ответа, но подозревает, что нет. Ситуацию усугубляет то, что хранилище ATProto, Personal Data Server (PDS), даёт прямой доступ к данным: записью и чтением потенциально захочет заниматься не одно приложение, и каждому из них придётся реализовать обе системы, скрывая от пользователя, что разница вообще существует.

Отдельно автор рассказывает о собственной ошибке: он наивно думал, что PDS работает как git-репозиторий, что у него есть собственная копия данных, с которой он работает локально, а изменения потом отправляет на сервер. Но на конференции выяснилось, что это не так: PDS, это самый настоящий удалённый сервер, с которым приложение всё время говорит по протоколу, а не локальная копия, которую скачивают и заливают обратно. «Владение данными» здесь означает лишь то, что данные и протокол доступа к ним публичны и их можно перенести на другое хранилище, а не то, что копия физически лежит у пользователя. Криптографические гарантии целостности данных, как в git, в ATProto тоже есть, но действуют только на стороне сервера, а не в протоколах, которыми приложение отправляет новые данные. По собственной оценке автора, ATProto выполняет примерно половину принципов локально-ориентированной разработки: он явно проигрывает в том, что данные не всегда под рукой и сеть нельзя сделать необязательной, офлайн-режим (записать отзыв без связи) требует, чтобы разработчик сам сделал временное локальное хранилище и синхронизацию с сервером после восстановления связи, из коробки протокол этого не даёт. С учётом ещё и раздельных систем для публичных и приватных данных получается уже четыре разных куска инфраструктуры, которые нужно писать самому: локальное хранилище для офлайн-данных, синхронизацию для их отправки на сервер, отдельный протокол синхронизации для публичных и приватных данных и отдельные системы чтения и записи для онлайн-режима, которые тоже, скорее всего, не совпадают с офлайн-синхронизацией.

Итоговый вывод автора: как разработчик, который одновременно хочет следовать локально-ориентированным принципам и дать пользователю выбор между публичностью и приватностью, он видит, что ATProto в нынешнем виде мешает этой цели ничуть не меньше, чем помогает. При этом он подчёркивает, что не знает, как это исправить, цель материала лишь в том, чтобы показать сообществу ATProto проблему, а не предложить готовое решение.

Ключевые факты

  • Автор, который присматривается к тому, чтобы строить приложения на ATProto, съездил на конференцию Local First в Берлине и расспросил и тех, кто строит поверх протокола, и самих разработчиков Bluesky.
  • Его пример, приложения для отзывов взамен Yelp, GoodReads и Letterboxd: в Yelp у него скопилось больше тысячи закладок, которые нельзя выгрузить, опубликовать, обработать скриптом или вести по ним историю изменений.
  • Сообщество ATProto проектирует «данные с разрешениями» (приватные данные) как полностью отдельную от публичных систему, с собственными структурами данных и проверкой, хотя, по мнению автора, отзыв остаётся отзывом независимо от того, кто может его прочитать.
  • Из-за этого разработчику приходится писать фактически два параллельных приложения, для публичных и для приватных данных, и скрывать эту разницу от пользователя; при переводе записи из приватной в публичную неясно, сохранятся ли её лайки, репосты и ссылки.
  • Автор также выяснил, что Personal Data Server ATProto, не аналог git с локальной копией данных, а удалённый сервер: офлайн-хранилище и синхронизацию с ним нужно реализовывать самому, поверх протокола.

Почему это важно

ATProto, протокол Bluesky, на конференции Local First в Берлине обсуждал едва ли не каждый спикер: сообщество видит в нём первый протокол, который берёт на себя идентичность, авторизацию и социальный граф для целого поколения приложений, избавляя разработчиков от необходимости строить всё это с нуля. Но если базовый дизайн для приватных данных окажется неудачным, это ударит по всем, кто планирует строить на ATProto, не только по автору материала.

Кому это важно

В первую очередь, разработчикам, которые хотят строить локально-ориентированные приложения поверх ATProto: им придётся иметь дело сразу с двумя параллельными системами хранения данных вместо одной. Также это касается самого сообщества ATProto, которое сейчас проектирует спецификацию «данных с разрешениями» и получает предметную критику дизайна снаружи. И пользователям, для которых важно свободно переключаться между приватными и публичными записями, по оценке автора, таких людей больше, чем тех, кто пишет отзывы напоказ.

Как это применить

Планируя строить на ATProto, стоит заранее закладывать в архитектуру два независимых конвейера данных, один для публичных записей, другой для «данных с разрешениями» (приватных), с разными структурами и способами проверки, и прятать эту разницу от пользователя, для которого это один тип контента. Офлайн-режим тоже придётся делать самому: Personal Data Server, это не локальная копия по образцу git, а удалённый сервер, с которым нужно постоянно говорить по протоколу, поэтому локальное хранилище и синхронизацию с сервером нужно писать отдельно. И стоит заранее учитывать, что перевод записи из приватной в публичную, это фактически удаление старой записи и создание новой: лайки, репосты и ссылки на неё, скорее всего, не сохранятся.

Можно ли доверять

Это личное эссе разработчика, а не официальное заявление команды ATProto или Bluesky, автор сам оговаривается, что не претендует на готовое решение, а хочет обозначить проблему. При этом выводы подкреплены конкретным опытом: он пообщался на конференции и с людьми, которые строят приложения на ATProto, и с разработчиками самого протокола, а также честно признаёт собственную более раннюю ошибку (считал, что Personal Data Server работает как git-репозиторий), то есть перепроверяет свои допущения, а не просто излагает мнение с ходу.

Риски и подводные камни

Главный риск, архитектурный: если дизайн «данных с разрешениями» примут в нынешнем виде, разработчикам придётся годами поддерживать две параллельные, несовместимые системы хранения ради, по сути, одной и той же сущности, отзыва, поста или записи. Второй риск, потеря данных при смене видимости записи: неясно, сохраняются ли лайки, репосты и ссылки при переводе записи из приватной в публичную. Третий, ATProto изначально спроектирован как исключительно публичный протокол, это заложено на уровне хранилища и сервисов публикации, и достроить контроль доступа поверх такого фундамента сложно в принципе, а не только в деталях реализации.

«Приватные и публичные данные, по сути, одно и то же. Отзыв о ресторане остаётся отзывом о ресторане независимо от того, вижу его только я сам или о нём раструбили на весь свет.»

— автор эссе «Building on ATProto» (lukekanies.com)