Skip to content

Commit 800a3e0

Browse files
aspiersclaude
andcommitted
docs(architecture): add merge benefits and npm-version risk
Cover two further considerations: (1) merging removes privileged cross-service endpoints (HMAC callback, /_internal lookups) and yields operational simplicity, and (2) npm peer-dependency clashes are a risk only if the two *processes* merge, not if they stay separate behind path routing — bounded anyway by the pnpm non-flat workspace. Distinguish origin-merge (recommended, no version risk) from process-merge throughout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 40946a8 commit 800a3e0

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

docs/architecture.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,32 @@ endpoint to issue an AT Protocol authorization code. For new users, a handle-pic
137137
upstream already allows — so the one upstream validation that looks like a
138138
constraint actually _favors_ single-origin.
139139

140+
Beyond dissolving those costs, collapsing to one origin has **positive**
141+
benefits the split forecloses:
142+
143+
- **Fewer privileged cross-service endpoints.** The split forces the two
144+
services to talk over authenticated HTTP: the HMAC-signed
145+
`/oauth/epds-callback` and the `/_internal/*` / `/_magic/*` lookup
146+
endpoints (e.g. `account-by-email`, `check-email`), each an attack surface
147+
that has to be signed, gated, and kept in sync. Co-located on one origin,
148+
much of this can become in-process calls with no wire boundary to secure.
149+
(Whether to also merge the _processes_ — versus keep two behind path
150+
routing — is a separate decision; see the migration doc.)
151+
152+
- **Operational simplicity.** One origin means one TLS cert, one DNS record,
153+
one CSP surface, and one set of cross-origin edge cases to reason about,
154+
instead of a parent/subdomain pair whose relationship is itself
155+
load-bearing config.
156+
157+
A **countervailing risk** applies only if the two _processes_ are merged
158+
(not if they stay separate behind path routing): sharing one Node runtime
159+
could surface npm peer-dependency conflicts between `auth-service`'s
160+
`better-auth` and `pds-core`'s `@atproto/*` stack. In practice the repo is a
161+
pnpm workspace with a non-flat `node_modules`, so each package already
162+
resolves its own versions and the overlap today is minimal (`express`,
163+
aligned). The risk is real but bounded, and avoided entirely by the
164+
keep-two-processes option.
165+
140166
The remaining real risk is not any of the three benefits but external
141167
addressability of `auth.<host>`: `authorization_endpoint` is published in AS
142168
metadata and cached by clients, and `EPDS_LINK_BASE_URL` appears in live

docs/design/single-domain-migration.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,47 @@ The routing model is exactly pds-gatekeeper's: **Caddy routes by path**, sending
2828
auth-service process and everything else to the PDS. The auth-service stays a
2929
separate process; only its _origin_ changes.
3030

31+
## Two levels of "merge" — keep them distinct
32+
33+
This matters for both benefits and risks, so fix the terms up front:
34+
35+
- **Merge the _origin_ (recommended baseline).** One hostname, Caddy path-routes
36+
to two still-separate processes. Dissolves every cross-origin cost; keeps the
37+
HMAC trust boundary; carries **no** npm-version risk.
38+
- **Merge the _processes_ (optional, later).** Fold auth-service into the
39+
pds-core Node process. Adds the "fewer privileged endpoints" benefit in full
40+
(calls become in-process) but is the only variant that can surface
41+
dependency conflicts. Treat as a separate, later decision.
42+
43+
## Positive benefits (beyond deleting costs)
44+
45+
- **Fewer privileged cross-service endpoints.** The split _requires_ the two
46+
services to communicate over authenticated HTTP: the HMAC-signed
47+
`/oauth/epds-callback` plus the internal lookup endpoints (`/_internal/*`,
48+
`/_magic/check-email`, `account-by-email`). Each is an attack surface that
49+
must be signed, gated, and version-matched across the boundary. Merging the
50+
origin lets some of these relax; merging the processes lets most become
51+
in-process calls with no wire boundary at all.
52+
- **Operational simplicity.** One TLS cert, one DNS record, one CSP surface, one
53+
origin's worth of cross-origin edge cases — instead of a parent/subdomain pair
54+
whose `endsWith('.'+pdsHostname)` relationship is itself load-bearing config
55+
threaded through several modules.
56+
57+
## Risk: npm version clashes (process-merge only)
58+
59+
Applies **only** to the process-merge variant, not the origin-merge baseline.
60+
61+
- Today the repo is a **pnpm workspace** (`pnpm --recursive`) with pnpm's
62+
default non-flat `node_modules`, so `auth-service` and `pds-core` already
63+
resolve their dependencies independently.
64+
- Overlap is small: `pds-core` owns the heavy `@atproto/*` stack, `auth-service`
65+
owns `better-auth`; the only shared runtime dep is `express ^4.18.2`, already
66+
aligned.
67+
- A single Node process would force one resolution of any shared/peer dep. The
68+
realistic conflict surface is a future `express` (or a transitive peer both
69+
pull) diverging. Bounded, but a real reason to prefer keeping two processes
70+
unless the in-process-call benefit is specifically wanted.
71+
3172
## What gets deleted
3273

3374
The whole point. These exist solely because of cross-origin-same-site:
@@ -44,6 +85,10 @@ The whole point. These exist solely because of cross-origin-same-site:
4485
`session-reuse.ts:195-200`, the `parentCookieDomain` derivation in
4586
`pds-core/src/index.ts:930`, and `authOrigin` derivation in
4687
`chooser-enrichment.ts`. The two hostnames become one.
88+
4. **(Process-merge only) some privileged cross-service endpoints** — the
89+
`/_internal/*` / `/_magic/*` HTTP lookups become in-process calls. The
90+
HMAC-signed `/oauth/epds-callback` can also collapse to an in-process call
91+
if the processes merge. See "Two levels of merge" above.
4792

4893
## What stays
4994

0 commit comments

Comments
 (0)