Decentralized ID (DID)

Decentralized ID (DID) tokens are used as cryptographically-generated proofs that are used to manage user access to your application's resource server.

What is a DID Token?

By adapting W3C's Decentralized Identifiers (DID) protocol, the DID token created by the Magic client-side SDK (see getIdToken) leverages the Ethereum blockchain and elliptic curve cryptography to generate verifiable proofs of identity and authorization. These proofs are encoded in a lightweight, digital signature that can be shared between client and server to manage permissions; protect routes and resources, or authenticate users.

The DID token is encoded as a Base64 JSON string tuple representing [proof, claim]:

  • proof: A digital signature that proves the validity of the given claim.
  • claim: Unsigned data the user asserts. This should equal the proof after Elliptic Curve recovery.
const claim = JSON.stringify({ ... }); // Data representing the user's access
const proof = sign(claim); // Sign data with Ethereum's `personal_sign` method
const DIDToken = btoa(JSON.stringify([proof, claim]));

Decentralized ID Token Specification

iatIssued at timestamp (UTC in seconds).
extExpiration timestamp (UTC in seconds).
nbfNot valid before timestamp (UTC in seconds).
issIssuer (the signer, the "user"). This field is represented as a Decentralized Identifier populated with the user's Ethereum public key.
subThe "subject" of the request. This field is populated with the user's Magic entity ID. Note: this is separate from the user's Ethereum public key.
audIdentifies the project space. This field is populated with the application's Magic entity ID.
addAn encrypted signature of arbitrary, serialized data. The usage of this field is up to the developer and use-case dependent. It's handy for validating information passed between client and server. The raw data must already be known to the developer in order to recover the token!
tidUnique token identifier.

Generating a DID Token (Pseudo-code)

// Construct the user's claim
const claim = JSON.stringify({
iat: Math.floor( / 1000),
ext: Math.floor( / 1000) + lifespan,
iss: `did:ethr:${user_public_address}`,
sub: subject,
aud: audience,
nbf: Math.floor( / 1000),
tid: uuid(),
// Sign the claim with the user's private key
// (this way the claim is verifiable and impossible to forge).
const proof = sign(claim);
// Encode the DIDToken so it can be transported over HTTP.
const DIDToken = btoa(JSON.stringify([proof, claim]));