proto.broker

Run confidential AT Protocol OAuth clients on local domains without a tunnel.

Your app on https://app.test gets a real confidential client: private_key_jwt client authentication, signed client assertions and confidential-client session lifetimes, exactly as it will run in production. No tunnel, no deploy, no account.

Why it exists

A confidential client needs its metadata on a public HTTPS URL, and authorization servers refuse redirects to local domains like .test. An app on your machine can do neither, so until now the choice was a tunnel, or developing as a public client and finding out how the confidential flow behaves after you deploy.

proto.broker hosts the metadata and relays the callback, so the confidential flow you test locally is the one you ship.

How it works

  1. You generate a P-256 keypair locally. The private key never leaves your machine.
  2. Your public key, callback and scopes are encoded into the client id itself, so this service stores nothing.
  3. The authorization server fetches https://proto.broker/v1/<blob> and gets your metadata, public key included.
  4. After consent it redirects to https://proto.broker/v1/<blob>/callback, which sends you on to your local app.

Create a client

bun run client --callback https://app.test/oauth/callback --scope "atproto transition:generic"

Callbacks are limited to local development hosts on this instance, so a client can only ever send a code back to the machine that approved it.

Self-hosting

It runs as a Cloudflare Worker or as a Bun server in Docker, with no database. See the README for setup and for widening the allowed callback hosts.