Identity

The atproto identity system has a number of requirements:

  • ID provision. Users should be able to create global IDs which are stable across services. These IDs should never change, to ensure that links to their content are stable.
  • Public key distribution. Distributed systems rely on cryptography to prove the authenticity of data. The identity system must publish their public keys with strong security.
  • Key rotation. Users must be able to rotate their key material without disrupting their identity.
  • Service discovery. Applications must be able to discover the services in use by a given user.
  • Usability. Users should have human-readable and memorable names.
  • Portability. Identities should be portable across services. Changing a provider should not cause a user to lose their identity, social graph, or content.

Using the atproto identity system gives applications the tools for end-to-end encryption, signed user data, service sign-in, and general interoperation.

Identifiers

We use two interrelated forms of identifiers: handles and DIDs. Handles are DNS names while DIDs are a W3C standard with multiple implementations which provide secure & stable IDs. AT Protocol supports the DID PLC and DID Web variants.

The following are all valid user identifiers:

alice.host.com
at://alice.host.com
did:plc:bv6ggog3tya2z3vxsub7hnal

The relationship between them can be visualized as:

┌──────────────────┐                 ┌───────────────┐
│ DNS name         ├──resolves to──→ │ DID           │
│ (alice.host.com) │                 │ (did:plc:...) │
└──────────────────┘                 └─────┬─────────┘
       ↑                                   │
       │                               resolves to
       │                                   │
       │                                   ↓
       │                            ┌───────────────┐
       └───────────references───────┤ DID Document  │
                                    │ {"id":"..."}  │
                                    └───────────────┘

The DNS handle is a user-facing identifier — it should be displayed in user interfaces and promoted as a way to find users. Applications resolve handles to DIDs and then use the DID as the canonical identifier for accounts. Any DID can be rapidly resolved to a DID document which includes public keys and user services.

Handles
Handles are DNS names. They are resolved using DNS TXT records or an HTTP well-known endpoint, and must be confirmed by a matching entry in the DID document. Details in the Handle specification.
DIDs
DIDs are a W3C standard for providing stable & secure IDs. They are used as stable, canonical IDs of users. Details of how they are used in AT Protocol in the DID specification.
DID Documents

DID Documents are standardized JSON objects which are returned by the DID resolution process. They include the following information:

  • The handle associated with the DID.
  • The signing key.
  • The URL of the user’s PDS.

DID Methods

The DID standard describes a framework for different "methods" of publishing and resolving DIDs to the DID Document, instead of specifying a single mechanism. A variety of existing methods have been registered, with different features and properties. We established the following criteria for use with atproto:

  • Strong consistency. For a given DID, a resolution query should produce only one valid document at any time. (In some networks, this may be subject to probabilistic transaction finality.)
  • High availability. Resolution queries must succeed reliably.
  • Online API. Clients must be able to publish new DID documents through a standard API.
  • Secure. The network must protect against attacks from its operators, a Man-in-the-Middle, and other users.
  • Low cost. Creating and updating DID documents must be affordable to services and users.
  • Key rotation. Users must be able to rotate keypairs without losing their identity.
  • Decentralized governance. The network should not be governed by a single stakeholder; it must be an open network or a consortium of providers.

When we started the project, none of the existing DID methods met all of these criteria. Therefore, we chose to support both the existing did-web method (which is simple), and a novel method we created called DID PLC.

Handle Resolution

Handles in atproto are domain names which resolve to a DID, which in turn resolves to a DID Document containing the user's signing key and hosting service.

Handle resolution uses either a DNS TXT record, or an HTTPS well-known endpoint. Details can be found in the Handle specification.

Example: Hosting service

Consider a scenario where a hosting service is using PLC and is providing the handle for the user as a subdomain:

  • The handle: alice.pds.com
  • The DID: did:plc:12345
  • The hosting service: https://pds.com

At first, all we know is alice.pds.com, so we look up the DNS TXT record _atproto.alice.pds.com. This tells us the DID: did:plc:12345.

Next we query the PLC directory for the DID, so that we can learn the hosting service's endpoint and the user's key material.

await didPlc.resolve('did:plc:12345') /* => {
  id: 'did:plc:12345',
  alsoKnownAs: `https://alice.pds.com`,
  verificationMethod: [...],
  service: [{serviceEndpoint: 'https://pds.com', ...}]
}*/

We can now communicate with https://pds.com to access Alice's data.

Example: Self-hosted

Let's consider a self-hosting scenario. If it's using did:plc, it would look something like:

  • The handle: alice.com
  • The DID: did:plc:12345
  • The hosting service: https://alice.com

However, if the self-hoster is confident they will retain ownership of the domain name, they can use did:web instead of did:plc:

  • The handle: alice.com
  • The DID: did:web:alice.com
  • The hosting service: https://alice.com

We can resolve the handle the same way, resolving _atproto.alice.com, which returns the DID: did:web:alice.com

Which we then resolve:

await didWeb.resolve('did:web:alice.com') /* => {
  id: 'did:web:alice.com',
  alsoKnownAs: `https://alice.com`,
  verificationMethod: [...],
  service: [{serviceEndpoint: 'https://alice.com', ...}]
}*/