Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Identity Agent Guide #1149

Merged
merged 36 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b3d4281
initial guide; code snippets and tests need to be added
blackgirlbytes Jan 12, 2024
c912494
update wording
blackgirlbytes Jan 12, 2024
b6dd161
move to dwn
blackgirlbytes Jan 12, 2024
8cb8ad8
put apps back to 4th position
blackgirlbytes Jan 12, 2024
b1950d2
typo
blackgirlbytes Jan 12, 2024
e71aa21
updating based on review
blackgirlbytes Jan 12, 2024
fdc1e1b
linking agents guide
blackgirlbytes Jan 12, 2024
f2b04f5
Update site/docs/web5/build/decentralized-web-nodes/using-identity-ag…
blackgirlbytes Jan 12, 2024
12db33c
passphrase update; users can use whatever they want
blackgirlbytes Jan 12, 2024
9f158b1
Update site/docs/web5/build/decentralized-web-nodes/using-identity-ag…
blackgirlbytes Jan 12, 2024
2da72ce
using identity agent wrapper instead
blackgirlbytes Jan 13, 2024
d5dc8b6
Merge branch 'main' into create-idenity-agent-guide
blackgirlbytes Jan 13, 2024
cc84425
update test descriptions
blackgirlbytes Jan 13, 2024
d0754df
more details in guide
blackgirlbytes Jan 16, 2024
496187d
adding for more clarity
blackgirlbytes Jan 16, 2024
bc7bd9c
Merge branch 'main' into create-idenity-agent-guide
blackgirlbytes Jan 16, 2024
a290b2d
capitalization
blackgirlbytes Jan 16, 2024
8353376
fix typo
blackgirlbytes Jan 16, 2024
9b2ebb4
remove unnecessary wording
blackgirlbytes Jan 16, 2024
cb8c650
combine create identities code snippet
blackgirlbytes Jan 16, 2024
f4581ec
agent tests
blackgirlbytes Jan 16, 2024
dcb4abb
Merge branch 'main' into create-idenity-agent-guide
blackgirlbytes Jan 16, 2024
cd95000
Merge branch 'main' into create-idenity-agent-guide
angiejones Jan 18, 2024
ad40860
how the agent connects to web5
blackgirlbytes Jan 19, 2024
633ca54
pinning version
blackgirlbytes Jan 19, 2024
ffce08f
Merge branch 'main' into create-idenity-agent-guide
blackgirlbytes Jan 19, 2024
8b9a556
updating lock file to match packagejson
blackgirlbytes Jan 19, 2024
6025097
Update site/code-snippets/web5/build/decentralized-web-nodes/use-iden…
blackgirlbytes Jan 19, 2024
c2996a6
Update site/docs/web5/build/decentralized-web-nodes/using-identity-ag…
blackgirlbytes Jan 19, 2024
cbefcfb
separate apps
blackgirlbytes Jan 19, 2024
91d06ba
Update site/docs/web5/build/decentralized-web-nodes/using-identity-ag…
blackgirlbytes Jan 19, 2024
348dbab
bolding the word separate to emphasize separate apps
blackgirlbytes Jan 19, 2024
c1c6a34
italic to bold
blackgirlbytes Jan 19, 2024
5165a7f
Update site/docs/web5/build/decentralized-web-nodes/using-identity-ag…
blackgirlbytes Jan 19, 2024
7e8b890
Update site/docs/web5/build/decentralized-web-nodes/using-identity-ag…
blackgirlbytes Jan 19, 2024
c1af9dd
connectToWeb5 snippet
blackgirlbytes Jan 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@web5/api": "0.8.4",
"@web5/credentials": "0.4.1",
"@web5/dids": "0.2.3",
"@web5/identity-agent": "0.2.5",
"font-awesome": "4.7.0",
"googleapis": "128.0.0",
"node-fetch": "3.3.2",
Expand Down
21 changes: 21 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { test, expect, describe } from 'vitest';
import {
getDwnEndpoints,
} from '../../../../code-snippets/web5/build/decentralized-web-nodes/use-identity-agents';

let agent;

describe('create identity agent', () => {
// TO DO: add more tests for each code snippets after the team determines how to conditionally run tests for Web5.connect() vs. the Identity Agent
test('createDidOptions returns an object with cryptographic keys and service endpoints', async () => {
const didOptions = await getDwnEndpoints();

expect(didOptions).toHaveProperty('keySet.verificationMethodKeys');
expect(Array.isArray(didOptions.keySet.verificationMethodKeys)).toBe(true);
expect(didOptions).toHaveProperty('services');
expect(Array.isArray(didOptions.services)).toBe(true);
didOptions.services.forEach(service => {
expect(service).toHaveProperty('id');
expect(service).toHaveProperty('serviceEndpoint');
expect(service).toHaveProperty('type');
expect(service.type).toBe('DecentralizedWebNode');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { IdentityAgent } from '@web5/identity-agent';
import { getTechPreviewDwnEndpoints } from '@web5/api';
import { DidIonMethod } from '@web5/dids';


export async function createIdentityAgent() {
const agent = await IdentityAgent.create();
return agent;
}

export async function authenticateIdentityAgent(agent) {
await agent.start({ passphrase: 'default-passphrase' });
return agent.agentDid;
}

export async function getDwnEndpoints() {
// selects DWN endpoints that are provided by default during the Web5 tech preview period
const serviceEndpointNodes = await getTechPreviewDwnEndpoints();
// generates key pairs used for authorization and encryption when interfacing with DWNs
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
const didOptions = await DidIonMethod.generateDwnOptions({ serviceEndpointNodes });
return didOptions;
}

export async function createSocialMediaAndCareerIdentity() {
const socialMediaIdentity = await agent.identityManager.create({
name: 'SocialMedia',
didMethod: 'ion',
didOptions,
kms: 'local'
});

const careerIdentity = await agent.identityManager.create({
name: 'Career',
didMethod: 'ion',
didOptions,
kms: 'local'
});

return { socialMediaIdentity, careerIdentity };
}

export async function connectIdentityToWeb5() {
const { web5 } = await Web5.connect({
connectedDid: socialMediaIdentity.did,
agent,
});
return web5;
}
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
sidebar_position: 9
---

import CodeSnippet from '@site/src/components/CodeSnippet';

# Using Identity Agents

Identity Agents are a specialized type of [agent](https://developer.tbd.website/docs/web5/learn/agents/) that act as personal identity managers. Similar to how a password manager securely stores login credentials for different web apps, Identity Agents manage your [DIDs](https://developer.tbd.website/docs/web5/learn/decentralized-identifiers).

## Doesn't Web5.connect() create a DID for me?
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved

Yes, the `Web5.connect()` function generates a **new** identity and a local User Agent. However, Identity Agents allow you to connect a web app to an **existing** identity. This is useful for maintaining a cohesive online presence.

This guide will walk you through creating an Identity Agent to manage multiple user identities and connect to a Web5 application.



<details>
<summary>Prerequisites</summary>

**Install the following packages**

```bash
npm i @web5/dids @web5/identity-agent @web5/api
```

**Import the following modules**

```js
import { DidIonMethod } from '@web5/dids';
import { IdentityAgent } from '@web5/identity-agent';
import { Web5, getTechPreviewDwnEndpoints } from '@web5/api';
```

</details>

## Initialize the Agent
Start by creating an instance of the `IdentityAgent`.

<CodeSnippet functionName="createIdentityAgent" />

## Prompt Users to Authenticate

The first time you launch an Identity Agent, you will be prompted to authenticate with a one-time passphrase for security purposes.
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
<CodeSnippet functionName="authenticateIdentityAgent" />

## Connect User DIDs to DWNs
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
Next, enable the Identity Agent to manage user DIDs by connecting each DID to a [DWN](https://developer.tbd.website/docs/web5/learn/decentralized-web-nodes/). Below is an example using TBD-hosted DWN endpoints:
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved

<CodeSnippet functionName="getDwnEndpoints" />


<details>
<summary>Expected Output of didOptions</summary>

```js
{
keySet: { verificationMethodKeys: [ [Object], [Object] ] },
services: [
{
id: '#dwn',
serviceEndpoint: [Object],
type: 'DecentralizedWebNode'
}
]
}
```

</details>

## Create Identities
Now that `didOptions` contains cryptographic key pairs and service endpoints, you can create as many identities as necessary.

Each identity, linked to a unique DID, represents and compartmentalizes different aspects of a user. For example, a user can have an identity for social media interactions and another for professional engagements.

<CodeSnippet functionName="createSocialMediaAndCareerIdentity" />

:::note
* The `name` field serves as a friendly name for reference.
* The `kms` field stands for Key Management Service and can securely store and manage the cryptographic keys associated with a DID. If you don't specify a particular key management service, such as AWS Key Management Service or Google Cloud Key Management, Web5 will default to an in-memory key manager.
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
:::

## Use your Identity in a Web5 Application
Once your Identity Agent is set up to manage multiple identities, you can use it to help you login to Web5 application. Here's the typical workflow:

1. The Web5 application may display a QR code or a deep link for login purposes.
2. Use the Identity Agent to scan the QR code or click the deep link to establish a connection between your Identity Agent and the Web5 application.
3. The Identity Agent then prompts you to select the identity you prefer to use for authentication.

## Connect to Web5
Finally, the Web5 application can use the DID linked to your identity, so that you can interact within the Web5 application as your chosen identity.

```js
blackgirlbytes marked this conversation as resolved.
Show resolved Hide resolved
const { web5 } = await Web5.connect({
connectedDid: socialIdentity.did,
agent,
});
```

5 changes: 5 additions & 0 deletions site/src/util/code-snippets-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
"sendProtocolToRemoteDWNs": "const { protocol } = await web5.dwn.protocols.configure({\n message: {\n definition: protocolDefinition\n }\n});\n\n//immediately send protocol to user's remote DWNs\nconst {status} = await protocol.send(userDid);",
"sendRecordToDWNOfRecipient": "const { record } = await web5.dwn.records.create({\n data: \"this record will be created but not saved to DWN\",\n store: false, //remove this line if you want to keep a copy of the record in the sender's DWN\n message: {\n dataFormat: 'text/plain'\n },\n});\n\n//send record to recipient's DWN\nconst {status} = await record.send(recipientDid);",
"updateDwnRecord": "// Get the record\nconst { record } = await web5.dwn.records.read({\n message: {\n filter: {\n recordId: createdRecord.id\n }\n }\n});\n\n// Update the record\n// highlight-next-line\nconst {status} = await record.update({ data: \"Hello, I'm updated!\" });",
"createIdentityAgent": "const agent = await IdentityAgent.create();",
"authenticateIdentityAgent": "await agent.start({ passphrase: 'default-passphrase' });",
"getDwnEndpoints": "// selects DWN endpoints that are provided by default during the Web5 tech preview period\nconst serviceEndpointNodes = await getTechPreviewDwnEndpoints();\n// generates key pairs used for authorization and encryption when interfacing with DWNs\nconst didOptions = await DidIonMethod.generateDwnOptions({ serviceEndpointNodes });",
"createSocialMediaAndCareerIdentity": "const socialMediaIdentity = await agent.identityManager.create({\n name: 'SocialMedia',\n didMethod: 'ion',\n didOptions,\n kms: 'local'\n });\n\n const careerIdentity = await agent.identityManager.create({\n name: 'Career',\n didMethod: 'ion',\n didOptions,\n kms: 'local'\n });",
"connectIdentityToWeb5": "const { web5 } = await Web5.connect({\n connectedDid: socialMediaIdentity.did,\n agent,\n });",
"createTextRecord": "const { record } = await web5.dwn.records.create({\n data: 'Hello, Web5!',\n message: {\n dataFormat: 'text/plain',\n },\n });",
"createJsonRecord": "// Create a JSON record\nconst { record } = await web5.dwn.records.create({\n data: {\n content: \"Hello Web5\",\n description: \"Keep Building!\"\n },\n message: {\n dataFormat: 'application/json'\n }\n});",
"uploadImage": "// Create a blob record\n async function upload(event) {\n const blob = new Blob(event.currentTarget.files, { type: \"image/png\" });\n const { record } = await web5.dwn.records.create({\n data: blob,\n message: {\n dataFormat: \"image/png\"\n }\n });\n \n }",
Expand Down
Loading