基于 ATProto 构建
Building on ATProto

原始链接: https://lukekanies.com/writing/building-on-atproto/

作者探讨了 Bluesky 的 ATProto 协议成为现代应用程序基础性互操作标准的潜力。尽管该协议在身份管理方面表现出色,但作者认为它目前未能满足“本地优先”(local-first)开发的需求,尤其是在隐私方面。 目前,ATProto 是基于纯公开架构构建的。其拟议的“权限数据”(Permissioned Data)更新旨在引入私有数据,但作者批评这种方法过于复杂。通过创建两个独立且不兼容的公共与私有数据系统,该协议迫使开发者构建冗余且混乱的基础设施,却未能将公开与私有内容视为具有不同访问控制的本质相同的数据类型。 此外,作者指出 ATProto 并未真正体现“本地优先”原则,因为它依赖于持续的远程服务器连接,而非类似 Git 那种真正支持离线、由用户拥有的数据存储库。最终,作者担忧除非该协议能进化到统一数据处理并优先考虑用户控制的隐私,否则它将重蹈其试图取代的企业平台那种封闭、割裂的模式。作者仍抱有希望,认为通过社区反馈,该设计可以得到修正,以支持一个更开放、更灵活的数字生态系统。

最近的一场 Hacker News 讨论探讨了基于 AT Protocol (ATProto) 构建应用程序的潜力与局限性。 一位开发者分享了构建游戏社交平台的经验,称赞了 ATProto 的开放性。由于游戏状态和回放会公开广播,第三方开发者无需专有 API 即可构建 AI 分析工具或自定义界面。 然而,这引发了关于该协议设计理念的激烈辩论。批评者认为,ATProto 是为公开数据而构建的,对于需要隐私的应用程序来说,这无异于“方枘圆凿”。虽然一些用户认为隐私对于大规模采用至关重要,但另一些人则认为,强行将私密的加密数据塞入一个为公开、可互操作记录设计的协议中,从根本上就是有缺陷的。 这场对话凸显了去中心化技术中的核心矛盾:用户自主拥有的公开数据可移植性需求,与实际对私密、受控空间需求之间的冲突。尽管目前有一些旨在弥合这一差距的“权限数据”提案,但参与者对于 ATProto 是否是构建私密应用的合适基础,或者开发者是否应该寻找其他在核心层面内置了更强访问控制的系统,仍存在分歧。
相关文章

原文

Bluesky’s Atmosphere Protocol has the chance to become the base for a whole generation of applications. But it’s developing in surprising and disappointing ways.

I spent part of last week at the Local First Conference in Berlin. I was not surprised to find that AI coding was on everyone’s minds. Less expected was how pervasive ATProto was.

I’ve been considering trying to build on ATProto for a few months, so this was a great chance to ask a bunch of questions from both people building on it, and the people actually building it (multiple key Bluesky people were there).

I want ATProto to be the answer for me. I want to again live in a world where application developers use public, community driven standards to create interoperable applications with common data standards. I think it can be. But unfortunately I think it’s not on track to be that right now.

In this post I’m going to describe what I have been wanting to build, and how ATProto’s current and proposed designs do and don’t work with that. And I’ll also throw in some comments about what’s been surprising to me.

I’m probably trying to do too much here. But my main goal is to provide feedback on the proposed design, and it’s hard to do so without being clear about what I want to build and why.

The smallest version of what I want to build is a suite of applications for recording reviews. In an ideal world, these applications would supplant Yelp, GoodReads, Letterboxd, and a bunch of similar applications for just about anything you might consider reviewing. (Yes, I know there are already people building versions of these on ATProto; I’d want to collaborate with them.)

I want to replace these applications not because of their function, but because of their business models. Neither my wife nor I will use them the way they’re intended, and I think most people are like one or the other of us.

For me, I don’t want these companies to own my data. We have more than a thousand bookmarks in Yelp, but… they’re stuck in Yelp. I can’t do anything else useful with them: I can’t publish them, I can’t share them, I can’t write scripts across them, I can’t version control them. They belong to Yelp, not me. And, frankly, the experience they provide for managing lists of bookmarks kinda sucks.

This is a classic local first use case. I could adopt one tool that was great for writing reviews, another that used the same data but was better at publishing best-of lists for my friends, and another that made it easy to share “best business books” lists on my web site. No single app is going to do all of these, but a shared, public data model allows everyone to have what they want.

I’ve lost the willingness to give big corporations a permanent right to control how I use my own data. (That’s why I’m writing this in plain text and publishing via Hugo.) The apps only get worse over time. And if I’m going to invest that much time in recording my opinions, I want to control its use, not let Yelp do it.

As to my wife, she will just never publish anything online. Never. If I want her to review books or restaurants or recipes, it has to be in a place where I – and maybe the rest of our family – will see it, but no one else.

Personally, I am willing to publish public reviews. And sometimes I specifically want to, like sharing books I found useful as a founder. But doing so is complicated. The information I would record about a restaurant for myself is quite different from what I would want the wider world to know. Yet… most apps don’t allow you to draw this distinction. Reviews are public. Your opinion affects the subject’s reputation, even if you didn’t want it to. (I’m vegetarian and autistic, so a place working for me is not necessarily relevant for other people.)

Fundamentally, most of these applications are built to enable influencers: People who want to build a following online for their reviews. “Oh man, she has the best book recommendations!” “If he likes the restaurant, I know I will too!”

But most of us don’t want to become influencers. If anything, we’ve generally learned the lesson that it sucks to be followed by a bunch of people online. I want to keep my stuff private. I don’t want my opinions to matter to anyone else.

I mean sure, when someone comes to town I want to be able to give them a list of restaurants they should visit and activities they should do. But I want to send it to them, not the rest of the world.

We can split the world into three kinds of people:

  • Those who would only record a review if other people will read it. These are the influencer-wannabes
  • People like me, who would provide a mix of public and private reviews, depending on the circumstance
  • People like my wife who will only ever record reviews if they can be confident it will be private to just their friend group, or even just to themselves

The current crop of applications works fine for the first group. But it leaves the latter two out in the cold.

And I bet anything that those other two groups are much larger.

So, what we need is a system that allows application developers to easily let their users choose how public or private they want to be – entirely public, entirely private, or sharing piecemeal with individual groups.

Let’s start with what’s great about ATProto: It seems to be the first protocol designed to solve identity at scale, enabling any application to build ATProto identities into their application for authentication, tracking followers and following, and the other related features that basically every application needs.

Its identity system not perfect (I wish it were more human readable, especially). But it seems to be close enough today that nearly every speaker at Local First this year mentioned it. No more does every app developer have to create their own social graph, their own identity and authentication systems, their own means of finding friends.

Unfortunately, at least for now, the rest of the protocol is of limited use for my goals.

Today, ATProto is public-only: It assumes that everything you do will be published online for the whole world to see. That design decision is baked into everything from the storage systems to the structure of the publishing services.

The community is currently designing what they call “permissioned data”. (I think this is a silly name, and it should just be called “private data”, which is better both because “private” is actually a word, and also because it describes user behavior instead of technical implementation, which is a far better naming practice).

Unfortunately, while most of the assumptions driving the design seem reasonable, the resulting design looks very hard to build on. A lot of where I think it goes wrong is captured perfectly in the above linked post:

Before we get into it, the through-line on all of this is that public broadcast data is substantially different from permissioned data.

I fundamentally disagree with this. (I am not the only one.)

Private and public data are basically identical. A restaurant review is a restaurant review whether I am the only one who ever sees it or it gets shouted to the rooftops. A book review I share with my book club is identical to a book review I share with my wife or publish on my web site.

Data I publish to the world is just a special case: The permission is world-read. Just like data I never publish is a special case: It has no readers other than me.

Unfortunately ATProto is already used out in the wild for Bluesky, and it is designed and built as a public-only protocol. It would be hard to change it to support access control, limited distribution, and the other features you need with private data.

So, instead, the community has, from what I can tell, just… designed a completely independent system for private data.

Permissioned Data relies on the existing identity system and lexicons (for defining data types). But adds entirely new data structures, plus new methods for managing and validating that data. (Note that the link above is to one in a series of posts on the design; you can get to all of them from there.)

So, as an app developer, you have to essentially write two applications: One for public data, and one for private. But, your users don’t think of it as two apps. “These are restaurant reviews. All the restaurant reviews should go together.” So your job, as the developer, is to support these two data systems, and two protocols, but never let the user see that they’re totally different.

That gets messy real fast. You’ve got a private post you want to make public? You’re not modifying it – you’re deleting the old one and making a new one in the public subsystem. Does it keep its likes? Its reposts? Links to it? 🤷‍♂️ No idea, but… probably not.

It’s actually worse than that. ATProto’s storage subsystem, the “Personal Data Server”, provides direct access to your data. In other words, you should expect more than one application to want to read and write your data. So now, anyone who is interested in this data has to write two versions, but lie to their users and hide any differences.

Because, again, there aren’t actual differences. The actual data being stored is the same. The way the user thinks about it is the same.

To me this is a sign that the current proposal is flawed.

I don’t know how to fix it. I’m nowhere near close enough to conversation to think I can propose solutions yet. But hopefully I can help people see problems, at least.

I only had a high-level understanding of ATProto went I went to Local First, so I learned a lot while I was there. One thing I was definitely wrong about was how the PDS worked.

I naively assumed it worked a lot like a git repository. The ATProto community regularly says that I own my own data. I tend to assume that means that I have a copy of it, and that when I make changes, I am operating against my copy then distributing it. This is exactly how git works: I clone a repository, make my changes, then push them back up to the server for distribution. I have a hard time imagining “owning” my data without always having a copy of it.

But no, that’s not at all how ATProto works. The PDS is “your” server, but… it’s actually a server. You do not push data up and pull it down; you speak a protocol to it. You only “own” your data because it and the protocols for accessing it are public, and you can change where it is stored.

It does use cryptography-based data integrity guarantees like git does, which is one more reason I assumed I could easily manage the data like git does. But those guarantees are only used on the server, not in the protocols you use to provide new data.

ATProto meets about half of the design principles in the Local First essay linked above. But it clearly misses on the data being at your fingertips or the network being optional, and also misses out on a lot of implied abilities because you’re always talking to a remote server.

If you want to record a review while you’re offline… best practice is to essentially store those reviews in a temporary area, then push them to the server when you’re back online. In other words, you have to build your own custom storage and sync system if you want offline support. Obviously not impossible, but also obviously not local-first.

If you then cross this with the current design for Permissioned Data, I’ve got a bit of a mess:

  • Custom local storage for offline data
  • Custom sync system for emptying offline data
  • Sync system must use different protocols for public and private data
  • Online app usage must also use separate read and write systems for private and public data, and is likely different from the system used for offline support

As an application developer committed to both local first principles and letting the user choose between public and private, ATProto is working at least as much against me as with me. Am I really better off building on this, versus designing my own system? That question is doubly scary when you recognize that the protocol designer and I are so far apart philosophically.

If I believe public and private data are fundamentally the same, just with different access rights, but the community believes they are and should be different… I am fighting the protocol, storage system, and community every step of the way. I’ve done this before, and it sucks.

I’m still excited about ATProto. And thankfully, the Permissioned Data design is early enough that it can still be improved. And I’m not the only person out there pushing back on the existing design and its goals.

Even if the proposed design goes through, I can build at least somewhat on ATProto, maybe using its identity and lexicon systems.

But I came up in the 90s, when the entire internet was built on standardized protocols that were internet-scale, resilient, maintained by the community and a standards group, and built to empower its users rather than enrich whoever could build the biggest moat. I want that world again.

I think ATProto has the opportunity to be the first new protocol of this type in decades. I hope they go for it, and build something every application developer (but especially me!) wants to build on.

联系我们 contact @ memedata.com