Skip to content

Latest commit

 

History

History

identity-agent

Web5 Identity Agent

A library for building Web5 identity management applications

NPM Package NPM Downloads

Build Status Open Issues Code Coverage



The Identity Agent SDK is a component of the Web5 JS platform, created to simplify the development of applications that manage multiple Web5 identities on behalf of a single entity. Identity agents, sometimes called "wallets", are typically native desktop (e.g., Electron) or mobile (e.g, React Native) apps that are installed by end users to manage one or more decentralized identities.

Getting Started

This JavaScript library was designed for modern development runtimes, including Node.js, web browsers, and React Native. The package is distributed as @web5/identity-agent via npmjs.com, jsdelivr.com, unpkg.com, and github.com.

Node.js

This library is designed and tested for the active (v20) and maintenance (v18) LTS releases of Node.js

Install the latest version of @web5/identity-agent using npm or your preferred package manager:

npm install @web5/identity-agent

Example ESM import:

import { Ed25519 } from "@web5/identity-agent";

Example CJS require:

const { Ed25519 } = require("@web5/identity-agent");

Web Browsers

A polyfilled distribution is published to jsdelivr.com and unpkg.com that can imported in a module <script> tag:

<!DOCTYPE html>
<html lang="en">
  <body>
    <script type="module">
      // Example import from JSDELIVR
      import { Web5IdentityAgent } from "https://cdn.jsdelivr.net/npm/@web5/identity-agent/dist/browser.mjs";
    </script>
  </body>
</html>

Important

The @web5/identity-agent library depends on the Web Crypto API in web browsers. Web Crypto is available in all modern browsers but is accessible only in a secure context.

This means you will not be able to use many @web5/identity-agent features in a browser unless the page is served over https:// or wss://. Locally-delivered resources such as those with http://127.0.0.1, http://localhost, or http://*.localhost URLs are also considered to have been delivered securely.

React Native

For React Native, you may need a polyfill for crypto.getRandomValues.

import "react-native-get-random-values";

Contributing

We welcome you to join our open source community. Whether you're new to open source or a seasoned contributor, there's a place for you here. From coding to documentation, every contribution matters. Check out our contribution guide for ways to get started.

For help, discussion about best practices, or to chat with others building on Web5 join our Discord Server:

discord-badge

Remember, contributing is not just about code; it's about building together. Join us in shaping the future of the Web!

Core Concepts

Launching an Identity Agent

An agent is software that acts on behalf of a user to manage identity, public or private data, and interactions with other apps or services in a network. Identity Agents are a specific type of agent focused on simplifying the management of a person's online identities, since they often have several.

Many people already use multiple personas when interacting with others online depending on whether the context is family, career, or social. This might take the form of a work issued email that you use for career apps and a personal email that you use when interacting with family and friends. The same is true with Web5 identities except that the unique identifier is a Decentralized Identifier (DID) rather than an email address. Developers can create identity management apps, sometimes called "wallets", that focus on making it easy to connect Web5 apps to one or more identities and keep track of which apps have access to your data.

Every time an Identity Agent app runs on a computing device, whether desktop or mobile, the following should occur:

  1. Check whether the agent was previously initialized.
  2. If this is the first run on this device, initialize the agent.
  3. Load the agent's DID and keys to prepare for use.

An example implementation of these steps would be:

import { Web5IdentityAgent } from '@web5/identity-agent'

// Create a Web5 Identity Agent instance.
const agent = await Web5IdentityAgent.create();

// Prompt the end user to enter a password, which prevents unauthorized access to the encrypted
// identity vault that secures the Agent's DID and cryptographic keys.
const password = /* input by user */


// If its the first launch, initialize the identity vault for the agent, and if not provided, return
// the generated recovery phrase.
let recoveryPhrase: string;
if (await agent.firstLaunch()) {
  // Unless provided, a 12-word recovery phrase will automatically be generated and the Agent's
  // cryptographic keys deterministically generated from the phrase.
  recoveryPhrase = await agent.initialize({ password, recoveryPhrase });
}

// On every launch unlock the identity vault using the provided password and load the Agent's DID
// and keys from encrypted vault storage.
await userAgent.start({ password });

Creating an End User Identity

In Web5 apps, a user’s unique identifier - like an email address - is called a Decentralized Identifier (DID). You can think of an Identity as an isolated space uniquely identified by a DID that stores and manages the data relevant to a particular context or use case.

For example, a person might have one identity for work-related apps and data, another for personal/family, and yet another for their social media persona.

By organizing cryptographic keys, profile information, data, and credentials into separate identities, an Identity Agent can help users maintain greater control over their personal information and how it is shared with others. Users can choose which identity to share with different parties, depending on the context and level of trust.

The follow code example walks through how to create a new identity, manage it with the Identity Agent, and store data in the Decentralized Web Node (DWN) data store controlled by the newly created identity.

import { getTechPreviewDwnEndpoints, Web5 } from "@web5/api";

// Retrieve publicly addressable DWNs that other network participants can use to exchange messages
// and data with the new Identity.
const serviceEndpointNodes = await getTechPreviewDwnEndpoints();

// Generate a new Identity for the end-user.
const careerIdentity = await agent.identity.create({
  didMethod: "dht",
  metadata: { name: "Alice" },
  didOptions: {
    services: [
      {
        id: "dwn",
        type: "DecentralizedWebNode",
        serviceEndpoint: serviceEndpointNodes,
        enc: "#enc",
        sig: "#sig",
      },
    ],
    verificationMethods: [
      {
        algorithm: "Ed25519",
        id: "sig",
        purposes: ["assertionMethod", "authentication"],
      },
      {
        algorithm: "secp256k1",
        id: "enc",
        purposes: ["keyAgreement"],
      },
    ],
  },
});

Writing Data to an Identity's Data Store

The Web5 API makes it simple to store data in an identity's DWN data store by handling all of the message and data preparation and processing steps. Using the careerIdentity created earlier, a simple message payload can be written as follows:

// Instantiate a Web5 instance with the "Career" Identity.
const web5Career = new Web5({ agent, connectedDid: careerIdentity.did.uri });

// Write a simple text record.
const { record, status } = await web5Career.dwn.records.write({
  data: "Message",
  message: {
    dataFormat: "text/plain",
  },
});

console.log(status.code); // Output: 202

const recordData = await record?.data.text();
console.log(recordData); // Output: Message

Customization

Using Non-default Data Stores

By default, Web5IdentityAgent uses a LevelDB store for both the agent's identity vault and the DID resolver cache. For testing and prototyping purposes it may be desirable to use an in-memory store that doesn't persist data. There are also runtime environments, such as React Native, that don't support using the level package. Any implementation of the KeyValueStore interface can be substituted for the default identity vault and DID resolver cache.

For example, to use the in-memory KeyValueStore implementation from @web5/common:

import { MemoryStore } from "@web5/common";
import { DidDht, DidJwk } from "@web5/dids";
import { Web5IdentityAgent } from "@web5/identity-agent";
import { AgentDidApi, DidResolverCacheLevel, DwnDidStore } from "@web5/agent";

// Instantiate Identity Vault with an in-memory store.
const agentVault = new HdIdentityVault({
  keyDerivationWorkFactor: 210_000,
  store: new MemoryStore<string, string>(),
});

// Instantiate DID API with an in-memory resolver cache.
const didApi = new AgentDidApi({
  didMethods: [DidDht, DidJwk],
  resolverCache: new DidResolverCacheMemory(),
  store: new DwnDidStore(),
});

// Create a Web5 Identity Agent instance.
const agent = await Web5IdentityAgent.create({ agentVault, didApi });

Project Resources

Resource Description
CODEOWNERS Outlines the project lead(s)
CODE OF CONDUCT Expected behavior for project contributors, promoting a welcoming environment
CONTRIBUTING Developer guide to build, test, run, access CI, chat, discuss, file issues
GOVERNANCE Project governance
LICENSE Apache License, Version 2.0