npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@identity.com/identity-agent

v0.2.2

Published

The Identity Agent is a Self-Sovereign Identity agent based on [DIDs](https://www.w3.org/TR/did-core/Overview.html).

Downloads

11

Readme

Identity Agent

The Identity Agent is a Self-Sovereign Identity agent based on DIDs.

The Agent is capable of communicating with other DID-based agents using end-to-end encryption, as well as requesting and resolving Verifiable Credentials.

The Agent can be run via the command line, in the browser or on a remote server, and is designed to be extensible to support various use-cases and environments.

Capabilities

  • ✅ Resolve a DID to a document with a pluggable DID resolver
  • ✅ Sign, encrypt, decrypt and verify a message using DIDs
  • ✅ Send a message E2E encrypted using a simple decentralized 'hub' API
  • ✅ Create and process long-running tasks for credential presentation

TODO for V1

  • ⏳ Integrate with a remote DID resolver (e.g uniresolver.io)
  • ⏳ A simple local credential store and presentation resolver
  • ⏳ Resolve tasks on incoming messages

Quick Start

Running as a library

yarn add @identity.com/identity-agent
const did = 'did:your-did-here'
const agent = await Agent.for(did).build()

const bob = 'did:bobs-did'
await agent.send({ message: 'hello Bob!'}, bob)

Building locally

Note: Before contributing to this project, please check out the code of conduct and contributing guidelines. Thanks!

Install

Identity-Agent uses nvm and yarn

nvm i
yarn

Start a REPL like this:

yarn repl

Agent creation

Register a DID

createIdentity()

Create a privileged agent

Creating an agent with a private key

a = await Agent.for(Alice.did).withKeys(Alice.signingKey, Alice.encryptionKey).build()

// shorter version
a = await Agent.for(Alice).build()

Create a non-privileged agent

Creating an agent with no private keys (e.g. a mediator or relay)

b = await Agent.for(Bob.did).build()

Messages

Send a message via HTTP

message = { hello: 'Bob' }
await a.send(message, Bob.did)

Sign a message

jwt = await a.sign({some: 'payload'})

Verify a message

verifiedPayload = await b.verify(jwt)

Subject operations

Resolve a verifiable presentation

presentation = {} // dummy

taskContext = a.asSubject().resolvePresentationRequest(presentation, Bob.did)

await taskContext.waitForDone()

Verifier operations

Request a verifiable presentation

request = {}

taskContext = a.asVerifier().requestPresentation(request, Bob.did)

await taskContext.waitForDone()

Running the example browser app

The example app must be linked to the library using yarn link.

yarn link
cd examples/browser
yarn
yarn link identity-agent
yarn start

Architecture

Given the variety of identity use-cases, the Identity Agent is designed to be flexible. However, it does have some core concepts and design patterns that are described in this document.

Extending the Agent

The Agent uses dependency injection to allow it to be extensible by clients.

The following example shows how to inject an alternative storage module, e.g. to store messages in a database:

import { AgentStorage } from 'identity-agent';

class MyDBStorage implements AgentStorage {
  // ...implement the interface
}

const myDBStorage = new MyDBStorage()
Agent.for(did).with<AgentStorage>(TYPES.AgentStorage, myDBStorage)

Components

The following components are used by the Identity Agent:

| Module | Description | Default | |--------------------------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| | AgentStorage | Storage interface used to store and retrieve DID documents and task state | Backed by node-localstorage.Stores data in localstorage when run in the browser,and in a scratch folder when run via node. | | DIDResolver | A function which resolves a DID to its document | Looks up an AWS S3 bucket, if credentials are provided,otherwise uses a local in-memory cache. Note - retrieved DIDdocuments are stored in the AgentStorage. | | CryptoModule | Encapsulates cryptographic functions such as encrypting, decrypting and signing | Uses tweetnacl and the X25519 curve for encryption/decryptionand bitcoin-js and the Secp256k1 Bitcoin curve for signing. | | Transport | An interface uses for communicating with other agents (including remote agentscontrolled by the same DID) | Backed by the Http module | | Http | A Http client | Backed by node-fetch (uses window.fetch on the browser) | | IssuerProxy | A client-side proxy for credential issuers. Used by the identity agent to makecredential requests. | A stub. This should be replaced by clients. An identity.comIDV Toolkit proxy is under development. | | PresentationVerification | A service that cryptographically verifies presented credentials | A stub. The implementation depends on the type of credentialsand proofs used. An identity.com-compliant implementation isunder development. | | Presenter | A service that locates and presents credentials in response to a presentationrequest | A stub. An identity.com-compliant implementation isunder development. |

Tasks

Tasks are defined as:

  • long-running
  • resumable
  • interactive
  • chainable

processes.

Examples are:

  • PresentationRequest: a verifier requests a presentation from a subject:
  • Presentation: a subject receives a presentation request from a verifier and responds with a presentation of one or more credentials.
  • CredentialRequest: a subject requests the issuance of a credential from an issuer. This usually results in a flow of information from the subject to the issuer as they validate the subject's identity.

Long-running

If a process may take longer than 1-2 seconds, it may make sense to model it as a task. The reason for this is resumability (see below).

Resumable

Since agents are often used on mobile devices, browsers, or are otherwise ephemeral, long-running tasks must be able to store and resume their own state, so that they can continue after the agent has restarted.

For example, a credential request task may be in progress with an issuer, that is performing background checks that may take days. Once complete, the credential request task should be completed, resulting in a credential stored in the AgentStorage.

Interactive

Tasks may require input from the user or some external service. For example, a credential request may require the user to answer questions from the issuer, or a remote agent may require permission from the user before presenting a credential to a verifier.

Chainable

Tasks may spawn or resolve other tasks. Consider thee following complicated but plausible example.

  • Potential employer E, asks candidate C for their university transcript (PresentationRequest Task 1)
  • C does not recognise E and asks for their "Organisation Credential" (PresentationRequest Task 2)
  • E requests an organisation credential from an issuer I1 capable of issuing such credentials (CredentialRequest Task 3)
  • I1 issues a credential to E, resolving task 3
  • E sends the credential to C, resolving task 2
  • C accepts the credential, and asks their university U to issue them with a transcript credential (PresentationRequest Task 4)
  • In order to verify they are speaking to the correct former student, U asks C to provide their passport credential (CredentialRequest Task 5)
  • C scans and sends their passport document to U as a self-signed credential, resolving task 5.
  • U accepts the self-signed credential as sufficient proof and issues the transcript credential, resolving task 6
  • Finally, C presents the transcript credential to E, resolving task 1

Task Architecture

Tasks are designed using the CQRS model and Event Sourcing, so that state can easily be stored and rehydrated when an agent is resumed.

Tasks are therefore not directly manipulated, but are updated by executing commands, which emit events. The task state is the composition of the payloads of each of these events.

Events can themselves trigger new commands, so the entire task can be modelled as a flow.

Formally a flow consists of the following:

  1. A State type: this defines the contents of the task. Each event payload is therefore a deep subset of this state.
  2. A set of command types
  3. A set of event types
  4. A set of default Command Handlers that are executed when a command is triggered
  5. A set of default Event Handlers that are called when an event of a particular type is added to the task.

Roles

By default, an agent is in neutral role, i.e. it has not assumed a role in the SSI trust triangle.

In order to keep the base API simple, most actions that an agent can perform are hidden behind the role APIs: Subject and Verifier.

To switch role, call the following functions:

agent.asSubject()

agent.asVerifier()