- Read the current nonce.
- Build the operation’s canonical payload.
- Sign the exact payload bytes with an authorized Ed25519 key.
- Send the public fields, encoded payload, and signature.
Nonces prevent replay
A nonce is a counter associated with a DID authorization domain. Once a nonce is used successfully, another request cannot reuse it. Fetch current values with:
Existing Persona operations have separate counters. Fetch them with:
404 before initial registration. For registration, use the challenge_nonce and operator_nonce returned by the DNS-challenge response. For an existing Persona, use persona_nonce for DNS challenge and attestation replay protection, operator_nonce for signed Persona registration-state operations, and policy_nonce for that Persona’s policy and delivery constraints. operator_nonce belongs to the operator DID rather than one Persona, so another Persona operation under the same operator can make it stale. A Persona transfer challenge binds both the current persona_nonce and the current operator’s operator_nonce.
Expiration limits stolen requests
valid_until is an unsigned 64-bit Unix timestamp in milliseconds for SCALE authorization payloads. Use a short future window and make sure the machine signing the request has an accurate clock.
Canonical payloads are bytes
For each signed chain-state mutation that carries a proof,canonical_payload is the exact SCALE-encoded authorization structure. DNS challenge creation and verification prepare these operations but do not themselves carry a caller signature. Send a canonical payload as:
- Hex beginning with
0x, or - Standard or URL-safe Base64
Each endpoint page identifies which optional item is populated.
Alias payloads use this field order:
Root-public-key rotation uses a distinct payload:
Device and deactivation payloads use:
The operation schema identifies add, tombstone, update, and remove device actions and DID deactivation. Use the schema version returned by the Directory or current SDK; do not reuse the removed policy-link action encoding.
Delivery-policy payloads bind the complete replacement or deletion to its scope:
The operation value carries the canonical DID or Persona scope and the complete policy or requested constraints where applicable. The current Policy V2 actions set or delete one DID- or Persona-scoped policy or update DID or Persona delivery constraints. Tag-scoped actions have been removed; a tag is a rule condition.
A Persona registration payload binds the canonical DNS name, action, proposed controller set and threshold, optional delivery constraints, DNS validation attestation, challenge nonce, operator nonce, and
valid_until. Renewal binds the same fields except a replacement controller set: it preserves the finalized controllers, which can change only through the rotation endpoint. Persona v1 requires controller_threshold: 1. Initial registration is signed by one proposed controller that is already a signing key on the operator DID; renewal is signed by one active Persona controller.
A Persona transfer has two nested authorization layers. The new operator signs the Directory-returned acceptance_payload with a proposed new controller. The Directory then binds that signature and the DNS attestation into canonical_payload, which an active current Persona controller signs. The chain verifies both signatures and the attestation before replacing the operator and controller set. Use the returned bytes exactly; neither payload is JSON.
The Directory submits only DID-key proof calls. Account-owner pallet calls remain available to developers who
interact with the chain directly, but they are not Directory HTTP endpoints.
Sign the bytes, not their printed encoding
Ifcanonical_payload is Base64, decode it and sign the decoded bytes. Do not sign the Base64 characters. The resulting Ed25519 signature is sent as Base64 in signature.
Signer selection
Setsigner_key_id to:
rootto use the record’s root public key, or- A complete authorized verification-method ID such as
did:openpayload:...#signing
Why the body repeats the DID and action
The path selects the resource. The signed body binds the authorization to the same DID and one exact operation. The Directory rejects a mismatch rather than guessing what the caller intended.Straight to the point
private_key, a mnemonic, or a seed phrase.
