microcosm

Weekly 2025-09-05

A us-east drop-in jetstream replacement, and a working demo for microcosm Pocket: non-public per-user per-app preference data storage!

September 09, 2025

Short week after a holiday weekend. Last week I wrote a bunch about the current state of indie relay operation, and then fell into a trap set by @baileytownsend.dev to build private user preference data storage over service proxying!

But before that was the unplanned launch of the newest microcosm firehose service:

microcosm: atproto building blocks's avatar
microcosm: atproto building blocks
5mo

New microcosm hosted infra: `jetstream1.us-east.fire.hose.cam` This is a drop-in replacement for Bluesky's own hosted jetstream instances in us-east! It's subscribed to the *Bluesky* production relay, so it will emit exactly the same events.

Bluesky's own Jetstream instances in us-east have significantly suffered over the last few weeks, with frequent server disconnects, long firehose lag, and high error rates. As far as I'm aware there has been no official communication from Bluesky about service issues with their Jetstream instances, except for confirmation of awareness in the ATProto dev discord.

The situation over that weekend got bad enough (events lagging up to 30 minutes) that I went ahead and launched a drop-in microcosm replacement instance in the us-east region.

This new instance differs from the other microcosm Jetstreams by subscribing to Bluesky's own production relay (bsky.network) instead of the microcosm indie relays.

Ideally the upstream relay choice shouldn't matter, but see my update from last week for why, at the moment, it kind of does.


Pocket is the demo that Bailey got me building in the later part of last week!

fig (aka:[phil])'s avatar
fig (aka:[phil])
5mo

friday microcosm demo: pocket! lets any atproto app put/get a bit of non-public per-user data. application preferences etc. auth: you get it for free from the PDS, just put the `atproto-proxy` header in permissions: can be scoped to the app via `aud`, so users are in control of access, not apps

Thumbnail from embedded video. Go to Bluesky to see the full post.
This media is not supported...
See the full post on Bluesky!

It can privately store user preferences for apps. It uses atproto http service proxying to authenticate user requests without prior app coordination, and subdomain mapping in the service identifier to segment application storage spaces. These combine with OAuth Scopes to give users control of access by app.

Bailey's original challenge was to implement app.bsky.actor.getPreferences and .putPreferences after Bailey spotted a change to the PDS putPreferences handling making it support service proxying (which was confirmed as the intent!)

Unfortunately, while proxying getPrefrences does work, putPreferences still cannot actually be proxied by the PDS: it winds up going through pipethrough.ts and getting rejected for trying to pipethrough while being a procedure.

Since we currently do not use pipethrough() with procedures, proxying of request body is not implemented.

Additionally, the handling of the aud claim in the service token in this proxying is different, and the change also affected third-party appviews. A few rough edges, hopefully with fixes in PDS coming soon.

But anyway! The pocket demo has its own lexicon as a workaround, and adds per-app data segmentation by putting an app identifier into the did:web as a dynamic subdomain used for service proxying. And it works! And when proxying is fixed in the PDS for Bluesky preferences, pocket will be able to support that too.


Building on microcosm

  • red dwarf now uses slingshot to fetch pds records

  • a client-side feed hydration experiment by @whey.party with live-updating interaction counts via self-hosted spacedust

  • a client-side custom feed hydration experiment by @whey.party

Conversations

  • the Donut algorithm blog post by @l4.pm about building a feed algorithm (uses constellation)

  • an atproto link bag on connected-places

  • oauth scopes aud wildcard question (not much of a conversation)


Weekend (rip)

  • switched spacedust from jetstream2.us-east.bsky.network to jetstream2.us-west.bsky.network due to disconnects, lag, and general instability of Bluesky's us-east jetstream instances.

Monday (holiday, what were you doing fig)

  • launched a public us-east bsky.network-listening jetstream instance for microcosm

  • switched spacedust to this instance

Tuesday

  • finished up last week's notes

    • wrote much more of an essay about relays than i had intended to

  • can we just use the atproto private prefs api? (w/ bailey)

  • source code review of rsky-relay to try to see if it will reproduce the active status issues seen in bluesky's indigo relays: it should not show the issue, since it doesn't locally track active state per repo.

Wednesday

  • closing in on 8 billion constellation backlinks

    • 8 billion reached!

  • got nerd-sniped by @baileytownsend.dev into building a bluesky-compatible preferences storage appview, since he spotted a PR to make it possible

Thursday

  • extended the microcosm us-east jetstream instance's replay window from 24h to 48h (Bluesky's jetstream instances keep 36h)

  • created reflector, a tiny web service to dynamically generate did:web did docs for arbitrary subdomain ids, and deployed it with caddy for dynamic https certificate registration.

    • (for use with the preferences storage thing)

Friday

  • got pocket working, the per-user per-app private storage over service proxy demo.

    • unfortunately it doesn't work with bluesky's preferences lexicon because that's still a bit broken on the PDS

      • putPreferences can't be proxied at all and

      • the aud claim in the token for the proxied request includes a #service fragment which appears to be special-cased for

  • requested spec clarity for how the aud field is rendered for service-proxied xrpc requests (whether the #service_id fragement is included in the aud claim or not, which the current PDS does inconsistently)

Subscribe to microcosm
to get updates in Reader, RSS, or via Bluesky Feed
Adversarial PLC directory migration
Weekly 2025-08-29