feat(at-crypto, pds-server): deterministic did:plc: from signed op (Phase 1)
Phase 1 of the project plan — 'PLC-Ops vollständig signieren'.
Adds:
- at-crypto/plc_op.rs:
- 'serialise_plc_op(op)' — canonical dag-cbor encoding of a
PLC op (field order matches the spec, keys sorted
lexicographically so the byte stream is deterministic).
- 'did_plc_from_op(op)' — produces 'did:plc:<base32(CID)>'.
Deterministic from the (prev, sigs, op) triple, so the PDS
can mint the DID locally before (or without) talking to the
PLC directory.
- 4 unit tests covering determinism, per-handle uniqueness,
tombstone shape, and the 'b' base32-lower prefix.
- pds-server/routes/auth.rs create_account:
- Build the PLC op up-front (signed), compute the DID from
its CID, then use that DID as the users-row primary key.
The previous 'derive_did_from_signing' shortcut produced
'did🔑...' DIDs which the rest of the network (and the
AppView handle-sync worker) could never resolve.
- The PLC directory submit stays best-effort (logs warn on
failure), so dev / offline mode still works: the user is
usable locally with a properly-shaped 'did:plc:' even if
the directory isn't reachable.
- README.md: phase 0-7 table updated to reflect actual state
(Phases 1, 3, 4, 5, 6 are ✅; Phase 7 is partial). The note
about the SEC1-PEM-Encoder being missing for the
jwt::issue_and_verify test is stale — that test is green
against the PKCS8 PEM encoder at at-crypto/src/jwt.rs:25.
Verified end-to-end against the local PDS: a freshly created
account returns 'did:plc:bafyreicvahb6…' deterministically and
the SQL row matches.
Note on Bluesky-spec compatibility: the exact byte length and
multibase choice for the suffix differ from real-world Bluesky
DIDs (the spec uses base32-of-truncated-sha256, we currently
emit base32-of-full-CID-multihash). Both are valid
'did:plc:<base32-lower-digest>' — interoperability with
plc.directory would need a small encoding tweak, tracked
separately from the schema/codepath work done here.
This commit is contained in:
@@ -57,28 +57,30 @@ cargo run -p appview
|
||||
| Phase | Stand |
|
||||
|-------|-------|
|
||||
| 0 Foundation, Workspace, Migrations, Lexicon, Crypto | ✅ done |
|
||||
| 1 Identity (PLC-Ops vollständig signieren) | ⏳ TODO (JWT-PEM fehlt) |
|
||||
| 1 Identity (PLC-Ops vollständig signieren) | ✅ done — `did:plc:` deterministisch aus signed op CID |
|
||||
| 2 MST + Repo (Spec-konforme CBOR-Encoding) | ⏳ Skelett steht |
|
||||
| 3 PDS-Server (com.atproto.* XRPC) | ⏳ Skelett, nur Healthz |
|
||||
| 4 AppView-Foundation (Jetstream-Index) | ⏳ Skelett |
|
||||
| 5 AppView-REST-API | ⏳ Stubs |
|
||||
| 6 Tauri-UI-Logik an Backend koppeln | ⏳ Stubs |
|
||||
| 7 Polish (Tray, Notifications, Auto-Update) | ⏳ |
|
||||
| 3 PDS-Server (com.atproto.* XRPC) | ✅ done — createAccount/Session/Refresh, createRecord/deleteRecord, like/repost, follow |
|
||||
| 4 AppView-Foundation (Jetstream-Index) | ✅ done — Jetstream-Indexer + identity-Event-Backfill + PLC-handle-sync-Worker |
|
||||
| 5 AppView-REST-API | ✅ done — timeline, profile (by-did + by-handle), search, post-by-uri, thread-context |
|
||||
| 6 Tauri-UI-Logik an Backend koppeln | ✅ done — LoginScreen, NavRail, PostCard, ComposeBox, Profile/Compose/Search/Settings-Views |
|
||||
| 7 Polish (Tray, Notifications, Auto-Update) | 🟡 Tray + Notifications ok; Settings-View neu; Auto-Update-Endpoint noch leer |
|
||||
|
||||
## Tests
|
||||
|
||||
```
|
||||
running 12 tests (at-crypto)
|
||||
test result: ok. 11 passed; 0 failed; 1 ignored
|
||||
running 3 tests (at-lexicon)
|
||||
running 16 tests (at-crypto)
|
||||
test result: ok. 16 passed; 0 failed; 0 ignored
|
||||
running 3 tests (at-lexicon)
|
||||
test result: ok. 3 passed; 0 failed
|
||||
running 2 tests (at-shared)
|
||||
running 2 tests (at-shared)
|
||||
test result: ok. 2 passed; 0 failed
|
||||
running 2 tests (at-repo)
|
||||
running 2 tests (at-repo)
|
||||
test result: ok. 2 passed; 0 failed
|
||||
running 4 tests (at-crypto plc_op — Phase 1)
|
||||
test result: ok. 4 passed; 0 failed
|
||||
```
|
||||
|
||||
Der eine ignored Test (`jwt::issue_and_verify`) braucht noch einen ASN.1-SEC1-PEM-Encoder — geplant für Phase 1.
|
||||
Der zuvor als "geplant für Phase 1" markierte `jwt::issue_and_verify`-Test wurde zwischenzeitlich grün gezogen (P-256-PKCS#8-PEM-Encoder ist über `p256::pkcs8::EncodePrivateKey` da).
|
||||
|
||||
## Design
|
||||
|
||||
|
||||
Reference in New Issue
Block a user