Reviewer Identities
A reviewer identity is a Decentralized Identifier (DID) whose document lists the reviewer’s signing keys. Reviews in the Mangrove dataset are signed with a key, and each key is a separate reviewer until an identity binds it. A person with a key on their phone, another in their browser, and a third held by the signer keeps one profile and one reputation once all three are bound to the same DID. The Mangrove Review Standard names the DID methods an identity may use.
The reference app avoids the word in its interface: there a key pair is an account, several accounts counting as one reviewer is what this page calls an identity, and the DID is the reviewer address. An app for a general audience may follow the same wording.
This page is for apps that hold keys themselves, and for apps that show reviews. An app that logs people in through the signer gets an identity for each of them without any of the steps below; see the login guide.
How a key binds to an identity
An identity claim is a review whose sub is the DID and whose action is identity, with no rating, opinion or images, signed by the key to bind. The reviewer server resolves the DID document and accepts the claim only when the document lists the signing key as a verification method. From then on:
- reviews by that key carry
didin the API, and thedidfilter and/issuer/<did>span every key bound to the identity; - edits and deletes may come from any key bound to the same identity;
- aggregation treats the identity as one reviewer.
The binding lasts as long as the document lists the key. Reviews the key signed before the claim count for the identity as well, since both the DID owner and the key holder signed for the link. The rules are in the Mangrove Review Standard.
Claim with a local key
The mangrove-reviews package signs and submits the claim, and gives the key in the forms a DID document takes:
import { generateKeypair, publicToPem, multikeyFromPem, didKeyFromPem, claimIdentity } from 'mangrove-reviews'
const keypair = await generateKeypair()
const pem = await publicToPem(keypair.publicKey)
multikeyFromPem(pem) // zDn..., for publicKeyMultibase in a did:web document
didKeyFromPem(pem) // did:key:zDn..., for a did:plc verification method
// Once the document lists the key:
await claimIdentity(keypair, 'did:plc:z72i7hdynmk6r22z27h6tvur')
A refused claim answers 400 with the reason, such as a key missing from the document. The claim is idempotent: a second one for the same key and DID is accepted and changes nothing.
Bind a Bluesky account
A Bluesky account is a did:plc identity whose document lists the account’s signing key under the name atproto. Adding a second verification method for the Mangrove key needs no new infrastructure: the person’s PDS signs the update, because it holds a rotation key of the DID. The four calls are part of the AT Protocol and every PDS serves them.
- Show the person their Mangrove key as a
did:keystring, fromdidKeyFromPemabove. - Request a signing token.
POST /xrpc/com.atproto.identity.requestPlcOperationSignaturewith the account’s session; the PDS emails the person a code. - Sign the update.
POST /xrpc/com.atproto.identity.signPlcOperationwith the code astokenand the fullverificationMethodsmap: the existingatprotoentry plus a new one, for examplemangrove, set to thedid:key. The current entries are in the document athttps://plc.directory/<did>. Fields left out keep their values, but a map given replaces the old map, so theatprotokey has to be repeated. The answer is the signedoperation. - Submit it.
POST /xrpc/com.atproto.identity.submitPlcOperationwith{ "operation": ... }; the PDS checks the operation and sends it to the directory. - Sign the claim.
claimIdentity(keypair, did)from the app; the reviewer server fetches the document from the directory, finds the key, and binds it.
The name of the new verification method is free. The person’s reviews now show under their Bluesky DID, and a client can display the at:// handle from the document’s alsoKnownAs next to their reviews.
The steps need the account’s own session at the PDS, so they run in a tool the person is logged in to. A Mangrove client can print the did:key and the DID to enter, and leave steps 2 to 4 to a PDS client such as the official app once it offers them, a command line tool like goat, or a script with the atproto API.
Host a did:web
A did:web identifier resolves to a document served over HTTPS on the domain it names, at the path the did:web method gives. The document lists the key with publicKeyMultibase:
{
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"],
"id": "did:web:example.com",
"verificationMethod": [{
"id": "did:web:example.com#mangrove",
"type": "Multikey",
"controller": "did:web:example.com",
"publicKeyMultibase": "zDnaeYbAfwSNFEdZ8tCcsZtnXqWK4SojUxCvNznXXuKPzTwbd"
}]
}
Publish it at that path, then claim it with the key. The reviewer server re-resolves documents fetched from outside its own registry once a day and ends the binding of a key that left the document.
Create a did:plc without Bluesky
The reviewer server is a registry for did:plc operation logs. A client that creates a DID signs the genesis operation with a rotation key it holds and files it with PUT https://api.mangrove.reviews/identity/<did>/operations; the server verifies the chain by the did:plc rules and stores it. Such an identity resolves for every Open Reviews client without ever touching the directory, and can be copied to the directory later. The signer does this for every login; the Rust crate mangrove-reviews has the operation encoding, hashing and signing in its plc module for other implementations.
Show identities
For apps that display reviews, three things change in the reviewer API:
- Each review carries
didwhen its key is bound.GET /reviews?did=<did>returns reviews from every key of the identity;issuers=trueaddsdidto each issuer. GET /identity/<did>returns the DID document, resolved from the registry first, then the PLC directory, then thedid:webhost;getIdentity(did)inmangrove-reviewsis the same call.GET /identity/<did>/logreturns the storeddid:plcoperations.GET /issuer/<did>aggregates over the identity.
A verified name for the person is the at:// handle in alsoKnownAs, when the document has one; the Bluesky handle is checked both ways by the directory and the PDS, so a client may show it as the reviewer’s name.
The reviewer server and the libraries are part of the Mangrove repository, under the Apache License 2.0.