-
Notifications
You must be signed in to change notification settings - Fork 0
Service API
Clients call the public Gateway host. AppView, Operations, databases, and worker traffic stay on Railway private networking.
Machine-readable contracts: OpenAPI, endpoint transport manifest, and service Lexicons.
Eligible authenticated JSON queries and procedures use
/xrpc/app.thesocialwire.*, with /v1/* compatibility routes retained.
Streaming, health/readiness, OAuth metadata, telemetry, and vendor-owned
transports stay HTTP. User-owned records use standard com.atproto.repo.*
XRPC directly on the viewer PDS.
L@tr exposes its foreign bookmark XRPC surface unchanged.
The endpoint manifest records the intended transport per operation.
| Service | Role | HTTP surface |
|---|---|---|
| Gateway | OAuth metadata, DPoP verification, sync/PDS acceleration, AppView/L@tr/Operations proxy | Public health/metadata, /xrpc/app.thesocialwire.*, and retained /v1/* adapters |
| AppView | Sidebar projection, indexed reads, unread state, bootstrap stream | Private /xrpc/app.thesocialwire.*, retained /v1/* adapters, and NDJSON bootstrap |
| Ingress Controller | Independently fenced AppView/Wire Jetstream subscription and durable inbox staging | Private aggregate and per-lane health/readiness only |
| Projection Pool | Horizontally scaled AppView/Wire durable-inbox projection | Private aggregate health/readiness only |
| Coordinator | Fenced singleton RSS/backfill/repair/rank/enrichment/cleanup | Private aggregate health/readiness only |
| Charybdis compatibility executable | Rollback-compatible AppView worker entry point | No application HTTP API |
| Operations | Operator evidence and controlled recovery | Private /v1/operations/*, proxied by Gateway; pending source adds Operations XRPC aliases |
| Group | Purpose |
|---|---|
| OAuth metadata | Web, Apple, and Operations client registrations |
/v1/sync/* |
Preferences envelope and legacy Social Wire lexicon migration |
/v1/pds/cache/* |
Short-lived single-record read acceleration |
/v1/publications/* |
Sidebar proxy, resolve/refresh, and native PDS write-through |
/v1/appview/* |
Bootstrap, feeds, entry detail, unread counts, read mutations, enrollment, purge |
/xrpc/link.latr.bookmarks.* |
Native L@tr bookmark queries, mutations, and migration proxy |
/v1/telemetry/* |
Bounded, deidentified client-performance samples |
/v1/operations/* |
Operator-only control-plane proxy |
Examples in the XRPC surface include
app.thesocialwire.sync.getPreferences,
app.thesocialwire.publication.getSidebar,
app.thesocialwire.appview.getFeed, and
app.thesocialwire.operations.getOverview. Query inputs use the URL query
string; procedures use JSON request bodies. XRPC errors use the standard
{"error":"Name","message":"..."} envelope.
AppView proxy routes mount only when APPVIEW_BASE_URL is configured. Operations routes require OPERATIONS_BASE_URL and a distinct GATEWAY_OPERATIONS_INTERNAL_SECRET. Native L@tr XRPC routes mount only when the server-side LATR_IOS_PROXY_* credentials are configured.
Gateway→AppView trust uses GATEWAY_APPVIEW_INTERNAL_SECRET, with HMAC over the request path. Gateway→Operations uses its separate Operations secret. External clients must never send or know either internal secret.
Authenticated routes accept an ATProto OAuth access token and a request-bound RFC 9449 DPoP proof. A gateway-bound DPoP proof cannot be forwarded to a PDS or L@tr origin; native write-through paths use distinct upstream proof headers.
When an authorization server publishes no usable access-token JWKS, clients also send one X-ATProto-Session-DPoP proof bound to com.atproto.server.getSession at the viewer PDS. The Gateway verifies the DID→PDS→issuer binding and confirms the active session with that proof. A non-empty JWKS signature failure never falls back to PDS attestation. PDS nonce challenges use the separate X-ATProto-Session-DPoP-Nonce response header so Gateway and route-specific DPoP nonce chains remain isolated. Attestation is cached for no more than 60 seconds and bounded globally and per PDS; admission exhaustion returns 503.
A successful fallback response includes X-ATProto-Session-Attestation-Receipt. Before a client submits a route-specific X-ATProto-Upstream-DPoP proof—or signals a prepared proof with X-ATProto-Upstream-DPoP-Prepared: true—it must first obtain that receipt from an ordinary protected safe-read request. Missing or expired receipts return 428 plus X-ATProto-Session-Attestation-Required: true before the route handler or PDS probe runs; invalid receipts return a generic 401. Receipts are HMAC-bound to the exact token, DID, and DPoP key and expire with the authoritative attestation window. Every hosted Gateway replica must share a random PDS_ATTESTATION_RECEIPT_SECRET of at least 32 bytes.
Known-client enforcement is conditional on OAUTH_GATEWAY_REQUIRE_KNOWN_CLIENT. When enabled, token claims must match the configured client-ID and/or audience allowlists. Operations routes additionally enforce OPERATIONS_OPERATOR_DIDS.
The current Gateway, AppView, and Charybdis executables reject APP_ENV=local through the shared Operations environment guard even though SQLite backends remain implemented. Use an isolated disposable Postgres database and APP_ENV=dev until that mismatch is fixed.
# Apply migrations to a disposable database first.
DATABASE_URL='postgresql://…' bash scripts/apply-database-migrations.sh
# Terminal 1: AppView
cd services/appview
APP_ENV=dev DATABASE_URL='postgresql://…' ENABLE_THIN_APPVIEW=true \
GATEWAY_APPVIEW_INTERNAL_SECRET=local-development-only swift run AppView
# Terminal 2: Gateway
cd services/gateway
APP_ENV=dev DATABASE_URL='postgresql://…' \
APPVIEW_BASE_URL=http://127.0.0.1:8081 \
GATEWAY_APPVIEW_INTERNAL_SECRET=local-development-only swift run Gateway
# Terminal 3: Charybdis (optional; connects to live public ingestion by default)
cd services/appview-worker
APP_ENV=dev DATABASE_URL='postgresql://…' ENABLE_THIN_APPVIEW=true \
swift run AppViewWorkerUse the same disposable database for these three processes. Do not point local runs at hosted Development or Production data. Charybdis consumes external Jetstream traffic unless you explicitly configure an isolated source, so start it only when that effect is intended.
-
services/gateway/bruno/— public Gateway, XRPC, compatibility, mutation, health, and metadata requests -
services/appview/bruno/— direct AppView XRPC and compatibility routes -
services/appview-worker/bruno/— post-ingestion verification notes; the worker has no HTTP API
| CI job | Packages |
|---|---|
redis |
packages/swift/SocialWireRedis with Redis integration service |
gateway |
packages/swift/GatewayCore, services/gateway
|
appview |
services/appview |
charybdis |
packages/swift/ThinAppViewCore, services/appview-worker
|
operations |
packages/swift/OperationsCore, services/operations
|
spec |
OpenAPI contract/drift tests |
Related: Thin-AppView, Operations, Deployment-and-environments, Web-app, Apple-client.