A zero-dependency AT Protocol Personal Data Server written in JavaScript
atproto pds

Changelog#

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog.

[Unreleased]#

[0.5.0] - 2026-01-08#

Added#

  • Direct OAuth authorization without requiring Pushed Authorization Requests (PAR)
    • /oauth/authorize now accepts direct query parameters (client_id, redirect_uri, code_challenge, etc.)
    • Creates authorization request record on-the-fly, same as PAR flow
    • DPoP binding deferred to token exchange time for direct auth flows
    • Matches official AT Protocol PDS behavior

Changed#

  • AS metadata: require_pushed_authorization_requests now false
  • Extracted validateAuthorizationParameters() helper shared between PAR and direct auth

[0.4.0] - 2026-01-08#

Added#

  • Foreign DID proxying via atproto-proxy header
    • parseAtprotoProxyHeader() parses did:web:api.bsky.app#bsky_appview format
    • getKnownServiceUrl() maps known service DIDs to URLs
    • proxyToService() generic proxy utility with header forwarding
    • Repo endpoints (getRecord, listRecords, describeRepo) support explicit proxying
    • Returns appropriate errors for malformed headers or unknown services
  • Unit tests for proxy utilities
  • E2E tests for foreign DID proxying behavior

Changed#

  • Refactored handleAppViewProxy to use shared proxyToService utility

[0.3.0] - 2026-01-08#

Added#

  • Granular OAuth scope enforcement on repo and blob endpoints
    • parseRepoScope() parses repo:collection?action=create&action=update format
    • parseBlobScope() parses blob:image/* format with MIME wildcards
    • ScopePermissions class for checking repo/blob permissions
    • Enforced on createRecord, putRecord, deleteRecord, applyWrites, uploadBlob
  • Consent page permissions table displaying scopes in human-readable format
    • Identity-only: "wants to uniquely identify you" message
    • Granular scopes: Table with Collection + Create/Update/Delete columns
    • Full access: Warning banner for transition:generic
  • parseScopesForDisplay() helper for consent page rendering
  • E2E tests for scope enforcement and consent page display

[0.2.0] - 2026-01-07#

Added#

  • OAuth 2.0 authorization server with full AT Protocol support
    • Discovery endpoints (AS metadata, protected resource, JWKS)
    • Pushed Authorization Requests (PAR)
    • Authorization endpoint with dark-themed consent UI
    • Token endpoint (authorization_code + refresh_token grants)
    • Token revocation (RFC 7009)
    • DPoP proof validation and token binding
    • PKCE with S256 code challenge
    • Client metadata fetching and validation
    • Loopback client support for development
  • DPoP JTI tracking to prevent replay attacks
  • Comprehensive OAuth e2e tests

Changed#

  • BREAKING: Normalized SQL schema to snake_case convention
    • Tables: blobblobs, record_blobrecord_blobs
    • Columns: mimeTypemime_type, createdAtcreated_at, blobCidblob_cid, recordUrirecord_uri
    • Existing Durable Objects require storage reset
  • Consolidated error responses to use errorResponse helper
  • Moved OAuth types to TYPES & CONSTANTS section

[0.1.0] - 2025-01-07#

Initial experimental release.

Added#

  • Repo operations: createRecord, getRecord, putRecord, deleteRecord, applyWrites, listRecords
  • Sync endpoints: getRepo (CAR export), subscribeRepos (WebSocket firehose), getLatestCommit
  • Authentication: createSession, getSession, refreshSession with JWT tokens
  • Blob storage: uploadBlob, getBlob, listBlobs with R2 backend
    • MIME type sniffing (JPEG, PNG, GIF, WebP, MP4, AVIF, HEIC)
    • Automatic orphaned blob cleanup via DO alarms
    • Blob-record association tracking
  • Identity: Handle resolution, PLC directory registration
  • Federation: Relay notification (requestCrawl), AppView proxy for app.bsky.* endpoints
  • Infrastructure:
    • Merkle Search Tree (MST) for repo structure
    • DAG-CBOR encoding with CID generation
    • P-256 ECDSA signing via Web Crypto
    • TypeScript checking via JSDoc annotations
    • Setup script for key generation and PLC registration