···4949The local server currently exposes:
50505151- `GET /`
5252+- `GET /.well-known/did.json`
5353+- `GET /.well-known/atproto-did`
5254- `GET /xrpc/_health`
5355- `GET /xrpc/com.atproto.server.describeServer`
5456- `POST /xrpc/com.atproto.server.createAccount`
5557- `POST /xrpc/com.atproto.server.createSession`
5858+- `POST /xrpc/com.atproto.server.refreshSession`
5659- `GET /xrpc/com.atproto.server.getSession`
5760- `GET /xrpc/com.atproto.server.getServiceAuth`
5861- migration-oriented repo, blob, account-status, email, and PLC submission endpoints
···7174ZDS_RESEND_API_KEY=... \
7275ZDS_EMAIL_FROM='ZDS <pds@example.com>' \
7376ZDS_BLOB_UPLOAD_LIMIT=100000000 \
7777+ZDS_HANDLE_DOMAINS='.example.com,example.com' \
7878+ZDS_JWT_SECRET='at-least-32-random-bytes-here' \
7479zig build run -- \
7580 --port 2583 \
7681 --db /var/lib/zds/zds.sqlite3 \
···8287DIDs, real repo writes with per-account signing keys, verified repo CAR import,
8388repo export, blob import checks, account activation state, recommended DID
8489credentials, PLC operation signing/submission, and email delivery via Resend
8585-with local log fallback.
9090+with local log fallback. Deployment also serves the PDS `did:web` document and
9191+handle `/.well-known/atproto-did` resolution.
86928793The next production risks are operational rather than fake core shortcuts:
8894sequenced subscription events, durable session/recovery flows, and a filesystem
+11-1
docs/production-migration.md
···2727- `com.atproto.server.checkAccountStatus`
2828- `com.atproto.server.activateAccount`
2929- `com.atproto.server.deactivateAccount`
3030+- `com.atproto.server.refreshSession`
3031- `com.atproto.repo.importRepo`
3132- `com.atproto.repo.listMissingBlobs`
3233- `com.atproto.sync.getRepo`
···4243The migration-critical implementation details are also in place:
43444445- `createAccount` verifies migration service JWTs against the migrating DID
4646+- session tokens are signed with the configured `ZDS_JWT_SECRET`
4747+- stored passwords use salted PBKDF2-SHA256 hashes
4548- repo writes produce signed commit blocks and MST updates, not synthetic refs
4649- imported repo CARs are verified against the account DID and signing key
4750- each account has its own signing key for repo commits and PLC credentials
4851- `uploadBlob` defaults to 100,000,000 bytes and is configurable with
4952 `ZDS_BLOB_UPLOAD_LIMIT` or `--blob-upload-limit`
5353+- the server serves `/.well-known/did.json` for the PDS service DID and
5454+ `/.well-known/atproto-did` for hosted handles
50555156Still to harden after a throwaway migration:
52575358- `com.atproto.sync.subscribeRepos` and real sequenced account/identity events
5454-- durable session storage, password reset, and account recovery paths
5959+- password reset and account recovery paths
5560- filesystem or object-store blob backend with backup/restore tooling
56615762## Deployment Requirements
···6267ZDS_RESEND_API_KEY=... \
6368ZDS_EMAIL_FROM='ZDS <pds@example.com>' \
6469ZDS_BLOB_UPLOAD_LIMIT=100000000 \
7070+ZDS_HANDLE_DOMAINS='.example.com,example.com' \
7171+ZDS_JWT_SECRET='at-least-32-random-bytes-here' \
6572zig build run -- \
6673 --port 2583 \
6774 --db /var/lib/zds/zds.sqlite3 \
···7380and `ZDS_EMAIL_FROM` enable real email delivery; without them, token emails are
7481logged to stdout for local development. `ZDS_BLOB_UPLOAD_LIMIT` controls the
7582generic `com.atproto.repo.uploadBlob` request body ceiling.
8383+`ZDS_HANDLE_DOMAINS` is what `describeServer` advertises to clients.
8484+`ZDS_JWT_SECRET` signs app-session access and refresh JWTs; keep it stable
8585+across deploys or existing sessions will be invalidated.
76867787The AT Protocol uploadBlob lexicon does not define one universal byte limit; it
7888says blob restrictions are enforced when a record references the uploaded blob.