feat(registry): add label signing#1922
Conversation
|
| Name | Type |
|---|---|
| @emdash-cms/registry-moderation | Patch |
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
Scope checkThis PR changes 669 lines across 7 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 625b173 | Jul 10 2026, 03:35 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | 625b173 | Jul 10 2026, 03:39 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | 625b173 | Jul 10 2026, 03:35 PM |
a01683b
into
feat/plugin-registry-labelling-service
There was a problem hiding this comment.
This is a focused, well-structured addition of ATProto label v1 signing/verification to @emdash-cms/registry-moderation and I don’t see any blocking issues.
Approach judgment: The change matches the PR description and the referenced RFC #694. Requiring runtime-verified labels before release eligibility evaluation (via a module-private symbol brand) is the right defensive posture for a moderation package, and keeping the verify/evaluate split lets callers that already have verified labels skip redundant crypto work. Binding the signer’s private scalar against the issuer DID’s exact #atproto_label Multikey before signing, and round-trip-canonicalizing labels on verify, aligns with how ATProto signing is meant to work.
What I checked:
- Full source file, tests, fixture,
package.json,pnpm-lock.yaml, and the rootpnpm-workspace.yamlcatalog versions. - No other repo consumers call
evaluateReleaseModeration/verifyAndEvaluateReleaseModerationyet, so the breaking change to the evaluator input type (ModerationLabel[]→VerifiedModerationLabel[]) has no in-tree fallout. - Validation paths for DIDs, URIs, CID round-trips, RFC 3339 timestamps, printable UTF-8 label values, and the P-256 scalar range look correct.
- The signature path signs canonical DRISL CBOR produced by
validateLabelObjectand verifies the same canonical bytes on the other side, so the signer/verifier pair is internally consistent. - The
@atproto/cryptocross-check inlabel-crypto.test.tsexercises the produced signature against a separate implementation. - Package dependencies use workspace catalog versions already pinned at the desired releases; the lockfile churn is just deduplication of
@atcute/cboronto the catalog version. - Conventions: tabs/format match the repo, changeset is present, no admin UI strings to localize, no SQL/routes/migrations involved.
Unverified statically: I can’t run the test suite from this environment, so I’m taking the author’s reported test/lint/type results at face value. I also can’t independently assert that @atcute/cbor’s default encode() emits the exact byte-for-byte canonical form the broader ATProto ecosystem expects, but the signer and verifier use the same encoder and the cross-verification checks that the produced signature is valid for those bytes.
All told, this looks ready to land.
What does this PR do?
Adds real ATProto label v1 signing and verification to
@emdash-cms/registry-moderation.#atproto_labelkey before issuing labels.@atproto/cryptocross-verification against the implemented signer.Implements W1.4 from #1909. No routes or consumers are integrated in this PR.
Related to #1909 and #694.
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runmessages.pochanges except in translation PRs — a workflow extracts catalogs on merge tomain.Admin i18n is not applicable because this package has no user interface.
AI-generated code disclosure
Screenshots / test output
pnpm buildpassespnpm --filter @emdash-cms/registry-moderation typecheckpassespnpm --filter @emdash-cms/registry-moderation test: 60 passedpnpm test:unit: 4,599 passed, 3 skippedpnpm lintpassespublintpassesgit diff --checkpassesattw --packretains its existing internalfilenamecrash afterpublintsucceeds; the same crash reproduces in@emdash-cms/registry-client.