afterwrd

How it works

afterwrd is a social network with no company in the middle. Each person's site runs in their own Cloudflare account, holds only their own data, and talks to nothing but Cloudflare, the place it gets updates from, and the friends they've chosen. This page explains how, and how to check it for yourself.

The code is public

Everything afterwrd runs is in one public repository on GitHub: https://github.com/stemill/afterwrd. That's the code that runs on your site, the code that installs and updates it, this install page, and the end-to-end tests. Anyone can read it, and the people who wrote it would rather you did than took their word for it.

Two ways to check what the code talks to, without reading all of it:

Once installed, the code running on your site is visible in your own Cloudflare dashboard (Workers & Pages → your Worker → Edit code). What you see there is what runs; there's no other server involved.

Where your site lives

An afterwrd site is a Cloudflare Worker plus two kinds of storage, all inside your Cloudflare account and all on the free plan:

The Worker

Small JavaScript that answers every request to your address: it checks who's asking, reads the database, and builds the pages. It runs in Cloudflare's data centres, near whoever is looking.

D1: the database

An SQLite database holding your posts, comments, albums, the people named in your Facebook download, your connections, and the site's own keys.

Durable Objects: the photos

Photos and videos, stored by the fingerprint of their contents in Cloudflare's SQLite-backed objects, which the free plan includes. They're only ever served through the Worker.

Static files

The stylesheet, fonts and the browser-side scripts (import, posting, download), published with each release and checked against its fingerprint.

There is no afterwrd server. The address afterwrd.app hosts only this install page, as plain files on GitHub Pages; it never hears from your site. Nobody who works on afterwrd can see your site, reset your password (there isn't one), or sign in as you. The flip side is that nobody can recover your site for you either: your Cloudflare account is the only key, which is why the install page asks you to turn on two-factor authentication there.

Costs: Cloudflare's free plan covers a personal site comfortably, including the 5 GB of photos and videos the free Durable Objects storage allows. Cloudflare may change its plans; afterwrd deliberately uses nothing that needs a card.

What it talks to

Your site callsWhenWhat's sent
Cloudflare (its sign-in, then its API)Installing, updating, and making or deleting a groupThe release's files, and the hour's token Cloudflare gave when you pressed Allow (over HTTPS, to Cloudflare only)
GitHub (afterwrd's releases)Installing, updating, and a check for a newer version at most every six hoursNothing about you: it's a download
A friend's afterwrd siteOnly once you've both connected: when you open Home or their page, when you comment, and when you post or replyThe key for that connection, your comments on their posts, and a short note when there's something new (the start of a new post, or of a comment on something they've commented on too)

What it never talks to

  • Facebook. afterwrd never signs in to Facebook, never fetches anything from it, and never sends anything to it. It only reads the download file Facebook gives you, on your own computer.
  • afterwrd.app, or anyone who makes afterwrd. There's no registration, no licence check, no usage report.
  • Analytics, advertising or error-reporting services. None are included.

Browsers help you check this: open your site, open the browser's developer tools (Network), and watch. Every request goes to your own address, except photos from friends' sites, which come from their addresses.

Signing in

Only one person signs in to an afterwrd site: its owner. There's no password and no email address to steal, reuse or reset. Instead, each phone or computer you use has a passkey: a key pair made by the device itself, unlocked by its own face, fingerprint or PIN. Passkeys are the WebAuthn standard, the same thing banks and Apple, Google and Microsoft accounts use.

Friends don't sign in to your site at all. They see your posts from their own site, through a connection you approved (below).

How it's locked down

The Worker checks every request before it does anything else. Without the owner's session, the only things it will serve are the sign-in and setup pages, the fonts, and photo links that carry a valid signature. Everything else redirects to sign-in or is refused.

The code has had independent read-only security reviews before each major release, and the fixes are in the public history. The end-to-end tests in the repository drive real copies of the site with a browser and a virtual passkey, and include tests that try to break in: forged sign-ins, cross-site posts, impersonating a friend's site, and hostile data from a connected site.

Friends between sites

Two afterwrd sites connect directly to each other. There's no directory, no central account, and no third site involved.

  1. You make a one-time Connect link on your site and send it to a friend however you like.
  2. Your friend opens it, says where their site is, and confirms on their own site. Their site makes a random key for yours and hands it over; your site checks, by calling their site back, that the key is really theirs and meant for you, then gives them a key in return.
  3. Nothing is shared yet. The request appears on your Friends page with their site's address; you approve or decline. A link that was passed on to a stranger gets them no further than this.
  4. Once approved, each site can ask the other, using its key, for posts and photos written on afterwrd, and can leave comments. Each key works for one connection only, and disconnecting from either side ends it at once.

The Facebook import

Facebook will give you a copy of everything you've put on it (Download your information). afterwrd reads that file, and nothing else, and it does the reading in your browser, on your computer: the zip file is never uploaded as a whole.

  1. You pick the zip file(s) on the Import page. The browser opens them locally and works out your posts, photos, comments, likes and friends from the JSON inside.
  2. You tick which sections to publish. The default is posts and photos; likes, the friends list and the rest stay on your computer unless you tick them. Only what the ticked sections need is sent to your site.
  3. Each photo and video is fingerprinted and a thumbnail made, in the browser. Only files your site doesn't already have are uploaded, so importing a newer download sends almost nothing.
  4. The new import replaces the old one in a single step, so your site never shows a half-finished archive.

Installing and updating

The installer is a small Worker you deploy first. To create your site's database and upload afterwrd into your account it needs Cloudflare's permission, which it asks for through Cloudflare's own sign-in for apps: you press Connect Cloudflare, Cloudflare shows what afterwrd is asking for (making, changing and deleting Workers, which Cloudflare calls Workers Admin; making, changing and deleting databases; reading the account's workers.dev name) and you press Allow. Cloudflare then gives your installer a token that lasts an hour, kept only in a cookie on that page, used only against Cloudflare's API over HTTPS, and never shown, logged or sent anywhere else. afterwrd never asks for permission to make longer-lived tokens. The installer downloads the release from GitHub and checks every file against the fingerprint built into it, so what's installed is exactly the published release and can't be swapped on the way. Then it removes itself.

On the way, Cloudflare sends your browser through afterwrd.app/connect/, the one address registered for afterwrd. That's a static page with no server behind it (this whole site is files on GitHub Pages): it shows you which site is being connected and asks you to continue, sends you to Cloudflare, and on the way back hands the one-time code to that site, in your browser, keeping nothing. It only ever hands codes to sites at workers.dev addresses, where afterwrd lives. Only your own site holds the secret that turns the code into a token (the PKCE standard), so the code is useless to anything else. One thing to check for yourself: Cloudflare's page says what afterwrd is asking for, but not which site it's for. The afterwrd page before it does, so make sure the address it shows is your own site's. The page's code is in the repository with everything else.

Updates work the same way, from your site's Update page: connect, press Allow, and your site fetches the newer release, checks it, and installs it over itself, keeping your passkeys, connections, photos and database. Nothing is remembered between updates. Updates only ever go forward: an older release can't be installed over a newer one.

To see for yourself what the installer did, Check your install lists what should be in your account afterwards and the trail it leaves in Cloudflare's audit log.

What Allow covers, plainly: for that hour, every Worker and database in the Cloudflare account, not just afterwrd's, and the account's basic settings. Not your domains, other Cloudflare services, billing or login. That's why, if you use Cloudflare for anything else, it's best to make an account just for afterwrd. What you've allowed is listed, and can be revoked, under My Profile → Connected Applications.

When an update fixes a security problem, your site says so on Home. To hear about every release, follow the releases feed or Watch the repository on GitHub (Custom → Releases).

Trust, stated plainly: an installed site trusts the GitHub repository it updates from, and the afterwrd.app pages, which come from the same repository. Read each release's notes and changes before updating if you'd rather check.

Your data stays yours

What it can't protect against

Being honest about the edges:

← Back to installing