Skip to content

Authentication

This guide will help you add user authentication to your project. Authentication is needed when you want to perform writes. If you only want to perform queries, you do not need authentication.

Prerequisites

Authentication requires having configured a DID for your Ceramic client.

Choose your setup

DID method

The first step in adding authentication to your project is choosing which DID method you want to support for user accounts. Due to their mutability and security, it is recommended that you use 3ID DID for users.

DID Method Description Registration DID Documents Details
3ID DID A complete and flexible DID method built on Ceramic that supports key rotations and revocations Ceramic Mutable Learn
Key DID A lightweight but inflexible DID method that does not support key rotations None Immutable Learn

DID provider or wallet

After deciding on a DID method, you need to install either a wallet or a provider for that method. The most commonly used DID providers and wallets can be found below. For most browser applications, it is recommended that you use 3ID Connect.

Name DID Method Type Description Details
3ID Connect 3ID DID Wallet A hosted wallet and authentication system for browser apps using 3ID DIDs. Your application is not responsible for key management, and users can authenticate with their existing blockchain wallets. Learn
3id-did-provider 3ID DID Provider A JavaScript library for creating and interacting with 3ID DIDs. Your application is responsible for key management, and users need to authenticate with a DID seed or an auth secret. Learn
key-did-provider-ed25519 Key DID Provider A JavaScript library for creating and interacting with Key DIDs. Your application is responsible for key managemet, and users need to authenticate with a DID seed. Learn

Installation

Install a DID wallet or provider in your project using npm.

$ npm install @3id/connect
$ npm install 3id-did-provider
$ npm install key-did-provider-ed25519

Create the Provider

The authentication process varies depending on which wallet or provider you are using. Closely follow the steps below.

Import the provider

import { ThreeIdConnect,  <BlockchainAuthProvider> } from '@3id/connect'

Example using an Ethereum wallet:

import { ThreeIdConnect,  EthereumAuthProvider } from '@3id/connect'
Understanding BlockchainAuthProvider

The BlockchainAuthProvider parameter is always required but the name shown here is just a placeholder. In your application, you should substitute in the specific BlockchainAuthProvider you are using. A full list of supported BlockchainAuthProviders can be found here.

Request the user's blockchain address

const addresses = await <blockchainName>.enable()

Example using an Ethereum wallet:

const addresses = await window.ethereum.enable()

Request authentication from the user's blockchain wallet

This will prompt the user with a 3ID Connect permissions window.

const threeIdConnect = new ThreeIdConnect()
const authProvider = new <BlockchainAuthProvider>(<blockchainName>, addresses[0])
await threeIdConnect.connect(authProvider)

Example using an Ethereum wallet:

const authProvider = new EthereumAuthProvider(window.ethereum, addresses[0])
await threeIdConnect.connect(authProvider)

Create a provider instance

const provider = await threeIdConnect.getDidProvider()

Import the provider

import ThreeIdProvider from '3id-did-provider'

Get seed for DID

Generate a random seed for a new user, or somehow get the existing seed for a returning user. Seeds should be a 32 byte Uint8Array.

How to generate a seed

Here's how to securely generate a seed in the proper format:

import { randomBytes } from '@stablelib/random'
const seed = randomBytes(32)

Create a provider instance

Option 1: Using the seed
const threeId = await ThreeIdProvider.create({ getPermission, seed })
const provider = threeId.getDidProvider()
Option 2: Using an external auth method

This option is useful if you want to enable multiple secrets (seeds) that are capable of controlling the 3ID DID.

How to generate an authSecret

Here's how to securely generate a seed in the proper format:

import { randomBytes } from '@stablelib/random'
const authSecret = randomBytes(32)
const authId = 'myAuthenticationMethod' // a name of the auth method

const threeId = await ThreeIdProvider.create({ getPermission, authSecret, authId })

const provider = threeId.getDidProvider()
Understanding getPermission

The getPermission parameter is always required when creating an instance of ThreeIdProvider. It is used to give an application permission to decrypt and sign data. This function should present a dialog to the user in the wallet UI which asks for permission to access the given paths.

The function is called with one parameter which is the request object. It looks like this:

{
    type: 'authenticate',
    origin: 'https://my.app.origin',
    payload: {
        paths: ['/path/1', '/path/2']
    }
}

In the above example the app with origin https://my.app.origin is requesting access to /path/1 and /path/2. If the user approves, the function should return the paths array. If they decline, it will return an empty array. Note that a user may approve only some of the requested paths, which would return an array containing only the approved paths.

The most simple getPermission function simply grants all requested permissions.

const getPermission = async (request) => {
    return request.payload.paths
}

Import the provider

Import the Key DID provider into your project.

import { Ed25519Provider } from 'key-did-provider-ed25519'

Get seed for DID

Generate a random seed for a new user, or somehow get the existing seed for a returning user. Seeds should be a 32 byte Uint8Array.

How to generate a seed

Here's how to securely generate a seed in the proper format:

import { randomBytes } from '@stablelib/random'
const seed = randomBytes(32)

Create a provider instance using the seed

const provider = new Ed25519Provider(seed)

Set the Provider

Set the Provider instance to the DID instance used by your Ceramic client in order to perform writes.

ceramic.did.setProvider(provider)

Authenticate the DID

Now all that's left is to authenticate to the Ceramic client's DID instance using the configured DID Provider. If you're using ThreeIdConnect, this step will cause a pop-up in your browser requesting permission to authenticate the DID.

await ceramic.did.authenticate()

Usage

After authenticating, the user will now be able to perform writes on Ceramic using their DID.