A minimal web editor for managing standard.site records in your atproto PDS
std.pub#
A minimal web UI for managing standard.site publications and documents in a Bluesky PDS.
Project Structure#
src/
server.ts - Main Hono server entry point
lib/
oauth.ts - ATProto OAuth client setup with SQLite persistence
session.ts - Session management
routes/
auth.ts - Authentication routes (login, callback, logout)
publication.ts - Publication CRUD routes
documents.ts - Document CRUD routes
views/
home.ts - Home page view
layouts/
main.ts - Main layout template
public/
styles.css - Application styles
data/
oauth.db - SQLite database for OAuth state and sessions
private-key.json - ES256 private key for confidential client auth
Running#
# Development with hot reload
bun run dev
# Production
bun run start
Environment Variables#
PORT- Server port (default: 8000)PUBLIC_URL- Public URL for OAuth callbacks (MUST be HTTPS without custom port for production)DATA_DIR- Directory for persistent data (default: ./data)
ATProto OAuth Implementation#
This app is a confidential client using:
- ES256 key for client authentication (stored in data/private-key.json)
- SQLite for session and state persistence
- DPoP bound access tokens
- PAR (Pushed Authorization Requests)
OAuth Endpoints#
GET /client-metadata.json- OAuth client metadataGET /jwks.json- JSON Web Key Set for client authenticationGET /auth/login- Login formPOST /auth/login- Initiate OAuth flowGET /auth/callback- OAuth callback handlerGET /auth/logout- Logout and revoke session
ATProto Collections#
site.standard.publication- Blog/publication metadatasite.standard.document- Individual documents/posts
Key Dependencies#
hono- Web framework@atproto/oauth-client-node- ATProto OAuth (production-ready)@atproto/api- ATProto API client@atproto/jwk-jose- ES256 key generation and managementbun:sqlite- SQLite for session persistence