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

@atproto/plc

v0.0.1

Published

DID Placeholder is a cryptographic, strongly-consistent, and recoverable [DID](https://www.w3.org/TR/did-core/) method.

Downloads

2

Readme

DID Placeholder (did:plc)

DID Placeholder is a cryptographic, strongly-consistent, and recoverable DID method.

Motivation

We introduced DID Placeholder because we weren't totally satisfied with any of the existing DID methods. We wanted a strongly consistent, highly available, recoverable, and cryptographically secure method with cheap and fast propagation of updates.

We cheekily titled the method "Placeholder", because we don't want it to stick around. We're actively hoping to replace it with something less centralized. We expect a method to emerge that fits the bill within the next few years, likely a permissioned DID consortium.

How it works

This is not a fully-expressive DID format. Though it adheres to the DID spec, it is domain-specific and only allows for representing specific data types in a specific manner. There is the possibility that it could be extended to be more general in the future.

Each DID document is made up of just four pieces of data (for now):

  • signingKey
  • recoveryKey
  • handle
  • atpPds (Personal Data Server for the related AT Protocol repository)

DID documents are derived from a log of signed operations, ordered by the PLC server.

There are 5 operations that can be found in each log: create, rotate_signing_key, rotate_recovery_key, update_handle, and update_atp_pds.

Each operation is of the shape:

type Operation = {
  type: string // operation type
  prev: CID | null // pointer to the CID of the previous operation in the log
  sig: string // base64url encoded signature of the operation
  ... // other operation-specific data
}

Each operation contains a reference the the immediately preceding operation in the log and is signed by either the signingKey or the recoveryKey.

The DID itself is derived from the sha256 hash of the first operation in the log. It is then base32 encoded and truncated to 24 chars.

To illustrate: did:plc:${base32Encode(sha256(createOp)).slice(0,24)}

Operations are verified, ordered and made available by the PLC server.

The PLC server is constrained in it's capabilities. The operation logs are fully self-certifying, with the exception of their ordering.

Therefore, the PLC server's attacks are limited to:

  • Denial of service: rejecting valid operations, or refusing to serve some information about the DID
  • Misordering: In the event of a fork in DID document history, the server could choose to serve the "wrong" fork

Signing and Recovery Keys

Both the signingKey and the recoveryKey are permissioned to make changes to the DID document. However, these keys are not equal.

As can be seen in the example document (below), only the signingKey is granted the ability to make assertions and invoke/delegate capabilities.

The recovery key on the other hand is capable of performing a "recovery operation"

Account Recovery

The PLC server provides a 72hr window during which the recoveryKey can "rewrite" history.

This is to be used in adversarial situations in which a user's signingKey leaks or is being held by some custodian who turns out to be a bad actor.

In a situation such as this, the recoveryKey may be used to rotate both the signingKey and recoveryKey.

If a user wishes to recover from this situation, they sign a new operation rotating the signingKey to a key that they hold and set the prev of that operation to point to the most recent pre-attack operation.

Example

Consider the following operation log:

[
  {
    type: 'create',
    signingKey: 'did:key:zDnaejYFhgFiVF89LhJ4UipACLKuqo6PteZf8eKDVKeExXUPk',
    recoveryKey: 'did:key:zDnaeSezF2TgCD71b5DiiFyhHQwKAfsBVqTTHRMvP597Z5Ztn',
    handle: 'alice.example.com',
    service: 'https://example.com',
    prev: null,
    sig: 'vi6JAl5W4FfyViD5_BKL9p0rbI3MxTWuh0g_egTFAjtf7gwoSfSe1O3qMOEUPX6QH3H0Q9M4y7gOLGblWkEwfQ'
  },
  {
    type: 'update_handle',
    handle: 'ali.example2.com',
    prev: 'bafyreih2gihqzgq5qd6uqktyfpyxqxvpdnrpu2qunnkaxugbyquxumisuq',
    sig: 'KL98ORpGmAJTqDsC9mWAYbhoDIv_-eZ3Nv0YqiPkbgx0ra96gYa3fQhIpZVxXFyNbu_4Y3JhPCvyJb8yDMe9Sg'
  },
  {
    type: 'update_atp_pds',
    service: 'https://example2.com',
    prev: 'bafyreickw7v7mwncrganw645agsmwjciolknt4f6f5an5wt3nrjepqaoiu',
    sig: 'AS-APea3xxR5-sq2i5v9IOsgbM5G5qAnB92tExZ8Z4vEy_GQbV8jmfY7zTx76P88AVXInZsO6yWX4UO7_xAIfg'
  },
  {
    type: 'rotate_signing_key',
    key: 'did:key:zDnaeh9v2RmcMo13Du2d6pjUf5bZwtauYxj3n9dYjw4EZUAR7',
    prev: 'bafyreictfsrkdt5azni355vapqka5a7erqjsa3vv7iaf52yjlqqbzkwgga',
    sig: 'VvcCoYVDluLZghv3i6ARyk1r7m1M32BPryJlTma1HTOx2CdbmIOUkVUbFa2LWi571fe-2yjTWY0IEAKfRiPAZg'
  },
  {
    type: 'rotate_recovery_key',
    key: 'did:key:zDnaedvvAsDE6H3BDdBejpx9ve2Tz95cymyCAKF66JbyMh1Lt',
    prev: 'bafyreiazzldal6642usrcowrpztb5gjb73qla343ifnt5dfbxz4swmf5vi',
    sig: 'Um1GVZZT9JgB2SKEbwoF4_Sip05QjH7r_g-Hcx7lIY-OhIg88ZKcN_N4TgzljgBGwe6qZb0u_0Vaq0c-S2WSDg'
  }
]

The log produces the following document data:

{
  did: 'did:plc:7iza6de2dwap2sbkpav7c6c6',
  signingKey: 'did:key:zDnaeh9v2RmcMo13Du2d6pjUf5bZwtauYxj3n9dYjw4EZUAR7',
  recoveryKey: 'did:key:zDnaedvvAsDE6H3BDdBejpx9ve2Tz95cymyCAKF66JbyMh1Lt',
  handle: 'ali.example2.com',
  atpPds: 'https://example2.com'
}

And the following DID document:

{
  '@context': [
    'https://www.w3.org/ns/did/v1',
    'https://w3id.org/security/suites/ecdsa-2019/v1'
  ],
  id: 'did:plc:7iza6de2dwap2sbkpav7c6c6',
  alsoKnownAs: [ 'https://ali.example2.com' ],
  verificationMethod: [
    {
      id: 'did:plc:7iza6de2dwap2sbkpav7c6c6#signingKey',
      type: 'EcdsaSecp256r1VerificationKey2019',
      controller: 'did:plc:7iza6de2dwap2sbkpav7c6c6',
      publicKeyMultibase: 'zSSa7w8s5aApu6td45gWTAAFkqCnaWY6ZsJ8DpyzDdYmVy4fARKqbn5F1UYBUMeVvYTBsoSoLvZnPdjd3pVHbmAHP'
    },
    {
      id: 'did:plc:7iza6de2dwap2sbkpav7c6c6#recoveryKey',
      type: 'EcdsaSecp256r1VerificationKey2019',
      controller: 'did:plc:7iza6de2dwap2sbkpav7c6c6',
      publicKeyMultibase: 'zRV2EDDvop2r2aKWTcCtei3NvuNEnR5ucTVd9U4CSCnJEiha2QFyTjdxoFZ6629iHxhmTModThGQzX1495ZS6iD4V'
    }
  ],
  assertionMethod: [ 'did:plc:7iza6de2dwap2sbkpav7c6c6#signingKey' ],
  capabilityInvocation: [ 'did:plc:7iza6de2dwap2sbkpav7c6c6#signingKey' ],
  capabilityDelegation: [ 'did:plc:7iza6de2dwap2sbkpav7c6c6#signingKey' ],
  service: [
    {
      id: 'did:plc:7iza6de2dwap2sbkpav7c6c6#atpPds',
      type: 'AtpPersonalDataServer',
      serviceEndpoint: 'https://example2.com'
    }
  ]
}