zds#
a zig implementation of an at protocol personal data server.
name credit: jim (
calabro.io) suggestedzds.
zds stores atproto accounts, repos, records, blobs, sessions, and identity
state. it uses zat for atproto primitives such as syntax,
did resolution, jwt helpers, dag-cbor, car, mst, repo verification, and key
encoding.
references#
the implementation is informed by:
tranquil.farm/tranquil-pdsfutur.blue/pegasusbluesky-social/pdsandbluesky-social/atproto/packages/pdsalice.mosphere.at/atproto-smokechadtmiller.com/pds.jszzstoatzz.io/pds-message-poczzstoatzz.io/pollzhaileyok/cocoon
run locally#
zig build test
zig build run -- --port 2583 --db dev/zds.sqlite3
caddy run --config dev/Caddyfile
before committing:
zig build test
zig zen
endpoints#
current server surface includes:
GET /GET /.well-known/did.jsonGET /.well-known/atproto-didGET /xrpc/_healthGET /xrpc/com.atproto.server.describeServerPOST /xrpc/com.atproto.server.createAccountPOST /xrpc/com.atproto.server.createSessionPOST /xrpc/com.atproto.server.refreshSessionGET /xrpc/com.atproto.server.getSessionGET /xrpc/com.atproto.server.getServiceAuth- repo read/write/import/blob endpoints
- sync repo/blob/status endpoints
- identity plc credential/sign/submit endpoints
- a small set of
app.bsky.*compatibility endpoints
blob uploads default to 100000000 bytes for bluesky video compatibility. set
ZDS_BLOB_UPLOAD_LIMIT or --blob-upload-limit to change it.
see docs/smoke.md for the first atproto-smoke run.
deploy#
run behind a public https origin:
ZDS_RESEND_API_KEY=... \
ZDS_EMAIL_FROM='ZDS <pds@example.com>' \
ZDS_BLOB_UPLOAD_LIMIT=100000000 \
ZDS_HANDLE_DOMAINS='.example.com,example.com' \
ZDS_JWT_SECRET='at-least-32-random-bytes-here' \
zig build run -- \
--port 2583 \
--db /var/lib/zds/zds.sqlite3 \
--public-url https://pds.example.com \
--server-did did:web:pds.example.com
configuration:
--public-url: public pds origin used in did credentials and blob urls--server-did: pds service did, usuallydid:web:<host>ZDS_HANDLE_DOMAINS: comma-separated handle domains advertised bydescribeServerZDS_JWT_SECRET: stable secret for access and refresh jwt signingZDS_RESEND_API_KEYandZDS_EMAIL_FROM: email delivery for account and plc tokensZDS_BLOB_UPLOAD_LIMIT: genericcom.atproto.repo.uploadBlobbody limit
account migration#
zds implements the pds endpoints used by browser-based migration tools such as pds moover:
- service-auth-gated
createAccountfor an existing did - repo car import/export
- missing blob reporting and blob upload
- preferences import/export
- recommended did credentials
- plc operation email token, signing, and submission
- account activation/deactivation and status checks
see docs/migration.md.
storage#
sqlite stores accounts, records, repo blocks, commits, expected blobs, imported blobs, preferences, bookmarks, and mute state. uploaded blobs are currently stored in sqlite as blob rows.
next#
com.atproto.sync.subscribeRepos- password reset and account recovery flows
- filesystem or object-store blob storage
- backup/restore docs for the sqlite database and blob store