chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
# space-reference
Tests permissioned data against the reference implementation
(`bluesky-social/atproto` at `704b9e2ac`, published as
`@atproto/space@0.0.0-spaces-alpha-20261105160032`), in both directions:
- **pds.js produces, reference verifies.** `gen-artifacts.mjs` drives the space
handlers as a syncer would: getRepo, getLatestCommit and getRecord, each with
an `Atproto-Space-Want-Mac` key share against the author's KEM key, and a
credential issued by a pds.js authority through getSpaceCredential.
`ref-verify.test.ts` runs the reference's `decapsulate`, `verifyRepoStarFull`,
`verifyCommit`, `verifyRecord`, `verifySpaceToken` and `verifyCredentialSig`
over them. Passing means the KEM, both MACs, BLAKE3, LtHash, the STAR layout,
record CIDs (a blob ref included), the tokens and the credential signature
all agree.
- **Reference produces, pds.js verifies.** `ref-generate.test.ts` builds a repo,
MACs and tokens with `@atproto/space`; `test/space-reference.test.js` verifies
them with `@pdsjs/spaces`. It also serves the reference's record from pds.js
holding the reference's KEM key, presented with the reference's credential
and `createSpaceSigHeaders` signature, and checks that pds.js answers the
same MAC the reference computed.
Both directions carry negative cases (wrong repo, wrong space, wrong key,
wrong token type), so a pass cannot be vacuous.
## Running
The second direction also runs in the plain test suite, against fixtures
committed under `test/fixtures/space-reference-*` — no atproto checkout needed.
The full two-directional run needs a worktree of the pinned reference, the same
one `scripts/gen-space-vectors.md` uses:
```bash
git -C ~/code/atproto worktree add ~/code/atproto-space-ref 704b9e2ac
cd ~/code/atproto-space-ref
pnpm install --frozen-lockfile
pnpm --filter '@atproto/space^...' run build
# atproto's root vitest config imports this plugin, so vitest cannot start
# until it is built. Nothing @atproto/space depends on pulls it in.
pnpm --filter '@atproto-labs/rolldown-plugin-bundle-manifest' run build
# vitest resolves every project in the workspace before it runs one, and
# oauth-provider-ui's vite config imports this package. Without it the run
# ends in a startup error naming a package the space tests never touch.
pnpm --filter '@atproto/oauth-provider-api' run build
```
Then:
```bash
npm run test:reference
npm run test:reference -- --refresh-fixtures # also update committed fixtures
```
`--refresh-fixtures` records the upstream SHA in the manifest; regenerating the
fixtures is how they track upstream, the same ritual as
`test/fixtures/space-vectors.json`.
Each alpha release moves upstream. Read `generatedFrom.sha` in the manifest to
see which upstream commit the committed fixtures came from, and move the
worktree to the new release before trusting a run against it. `pnpm install`
and the builds have to run again afterwards.
## Notes
- Keys are generated fresh per run, and ECDSA signing faults can be
probabilistic (atproto rejects high-S signatures, which `crypto.subtle.sign`
emits about half the time) — run it a few times when touching crypto.
- Committed token fixtures are always expired, so the fixture-based test checks
parsing and signatures, and sets the clock to the credential's issue time for
the request it serves; expiry is exercised by unit tests and the live run.
- Not covered: the reference PDS as a running server (this exercises its
verification library, not its HTTP endpoints), secp256k1 keys, blob bytes,
and oplog replay over time.