The login screen of any web application is the equivalent of that application telling you “In order to access YOUR data in MY database, prove you are who you say you are.” You’re authenticating with the application so that you can have the privilege of giving it your data.

In a previous blog post, I covered the downside to applications controlling your data. An application’s owner can restrict your access to your own data. They can delete the data. They can sell the data to a third party. They might introduce a bug that allows other people to access the data. They might get compromised. Or they can avoid all of this just to modify their policies down the road or see changes in ownership or management.

In a word: poppycock. It’s your data! You shouldn’t have to prove to anyone else that you have the right to access it. No one should tell you how to use your own data. And no one should do anything with your data that you aren’t comfortable with.

To gain agency over your data, you have to have agency over the database in which it lives1. If you own the database, you actually own the data. But running a database is a serious undertaking that we can’t expect from the average internet user. And even if you run a personal database, how should applications interact with it?

Over the past few months, I’ve explored the concept of personal database authorization, which allows you to give an application access to a database you control. Specifically, I built an authorization flow into ayb, my project to make it easy to create databases, share them with collaborators, and query them from anywhere. Here’s a video of how you can grant an application access to a freshly created database you own. Critically, the application has no login screen, instead asking for a database where your data will live:

Authorization in action: A to-do application with no login screen that requests access to a database you control. Todos is the to-do list application I created and use as my daily driver.

Holding on to your data

Here are three principles behind what’s happening in the video:

Authorize, don’t authenticate. In traditional web applications, you authenticate with the application to log in/prove your identity. Only once you’ve proved yourself with a password/passkey/… can you get access to your data. That puts the application in charge of your data. Instead, you should authorize an application to get access to your personal database. In the video, you see Todos asking you to Connect your database (“authorize me!”) rather than Enter your password (“authenticate yourself!”). The technology to support this flow is well understood and widely used: Todos initiates an OAuth2 flow to ask ayb for a token with which to query a database. I’ve open sourced an ayb.js library that manages these OAuth2 interactions on behalf of an application, and an engineer can integrate it into a new application in under an hour.

Creating a database should be as easy as creating a document. Most users can open up Microsoft Word or Google Drive and create an empty document. On the other hand, most users don’t know how to set up a Postgres database that backs itself up periodically and can be connected to a running application. In the video, the authorization flow allows you to pick an existing database or create a new one, and creating a new database is as easy as picking a name for it. If you create a database, you’ll receive periodic snapshots/backups without any configuration, and the application knows how to speak with ayb, run migrations, and store data in it. The database creation flow is no more difficult than one to create a file on your computer or the cloud, which is a lot more than you can say for most databases today.

Applications should store as little as possible outside a user’s database. The Todos application in the video is static HTML, CSS, and JavaScript. It knows nothing about its visitors. I assume somewhere in my server logs I can find the IP address of anyone that downloads the static resource, but beyond that, the application stores no state on my servers. For added privacy, you can download a self-contained index.html file and self-host the application. When you first load Todos, it asks you to Connect to your database to get started. Once it has a token with which to query your database2, all of your intimate to-do list items are stored in that database you own. You can revoke Todos’ access any time.

Trusting your host

Having just celebrated the virtues of storing data in a database you control, I have to deflate the balloon a bit. So far, I effectively said “don’t store your data with someone else, store it in something called ayb.” ayb is open source and while you CAN host it for yourself, do you want to? I believe ayb is pretty easy to install and run, but I certainly don’t think every user should become a database administrator. This leaves users with a frustrating choice: trade their trust of third-party applications for their trust of third-party database hosts. Are we just trading one form of centralization for another?

I think there’s still benefit to separating applications from the databases that they operate on. For starters, you actually get choice: rather than implicitly having to accept that every app developer is a custodian of a slice of your data, you get to pick where your data lives one time, regardless of how many applications you use. The abstraction means that once you get the hang of a tool like ayb, you can use it for multiple applications, which hopefully amortizes the cost of regaining agency over your data. You can pick who hosts your data because ayb is open source. I dream of a day when cooperatives and organizations that want to offer users agency over their data can offer alternatives to self-hosting and compete to be the custodian of your data. Finally, ayb doesn’t invent file formats: your data is stored in boring, well-accepted file formats like SQLite’s and DuckDB’s3. I’m planning to add export and import endpoints soon to make it easier to walk away with your data and bring it to another host.

Beyond personal data: collaboration and social interactions

The “authorize, don’t authenticate” model works most smoothly for situations where you definitively “own” the data. The more the dataset is the result of collaboration or social interaction, the less clear it is who owns the data, and the harder it is to authorize access.

Collaboration is one place where the definition of “personal data” is fuzzier. If you are working on a document on your own, it’s easy to tell an application to store “my document” in “my database.” But if you’re using something like a collaborative editor, say Google Documents, and are working on a document with someone else, what does it mean to store that document in a “personal database?” ayb lets you share your database with collaborators, but each database still has an owner. It would be interesting to explore models of collaborative personal databases, where users authorize an application to keep both of their databases in sync for data that they are collaborating on, but it’s beyond anything I’ve built, prototyped, or have my head wrapped around.

Social data is another type of data based on collaboration. We’ve seen the downsides of large organizations storing our social media data and also owning the algorithms and interfaces that control how that data is displayed to us. Projects such as ActivityPub/Mastodon and AT Protocol/Bluesky offer users more choice as to where their social data is stored, in different ways (ActivityPub’s federation vs. AT Protocol’s separation of storage and aggregation). Still, there’s a catch: these projects offer options on where to store your data, but the stored data is not useful until it’s aggregated into a timeline with everyone else’s. Solutions for timeline aggregation tend to fall back to centralization, as few people want to stomach the infrastructure and operational concerns involved in keeping track of what millions of people are saying in aggregate. Given how easy it is to create a static HTML/CSS/JavaScript application that can access and update your personal database, I’d love to see a decentralized extreme that displays your social network’s recent updates aggregated across all their personal data stores without relying on a centralized aggregator.

Where we go from here

Ultimately, I hope more people build software that asks users to authorize access to personal databases rather than asking users to authenticate with a centralized database. I’ve started doing this for my own personal applications, from tracking my Todos to tracking my Streaks to even managing newsletter subscriptions on my blog. Since ayb lets me spin up a database with the click of a button, I’ve built applications I previously avoided creating because I didn’t want to store my sensitive data in someone else’s database, but also didn’t have the time to administer my own.

To build on all of this, here are a few areas I’m excited to explore from here:

  • Supporting basic collaboration, such as how multiple users like journalists or scientists might collaborate on a dataset they are curating.
  • Investigating how this all connects to the local-first community. You’re in control of your ayb database, but it’s still hosted remotely, and I’m curious how a local SQLite/DuckDB database might sync with the remote one.
  • Identifying ways to help other application developers build software in a way that leaves users with agency over their data.

But mostly, I want to see how many login screens we can replace with database authorization screens. If you want to collaborate on any of these topics, or want help building software around personal databases, reach out!

Thank you to Meredith Blumenstock for giving feedback on the blog post and video.

  1. I’m certainly not the first to argue for data agency. Sir Tim Berners-Lee’s Solid Project has been exploring the idea of personal data pods for years. The ActivityPub and AT Protocol communities are building social networks that put users in more control of their shared content. The local-first community argues that users should have more control over their own data. My aim is to show how we can string together familiar, off-the-shelf technologies to make it easier for developers to build applications that offer more control. 

  2. To accomplish this, ayb.js implements OAuth2 using PKCE, which allows an ayb token to be issued to any app, even if it’s a fully static frontend blob with no backend to serve a client secret. 

  3. I’m iterating on an open PR for DuckDB, so coming soon.