AtprotoのIDシステムには、いくつかの要件があります。
- IDプロビジョニング。ユーザーは、サービス間で安定したグローバルIDを作成できる必要があります。これらのIDは、コンテンツへのリンクが安定していることを保証するために、ほとんど変更されない必要があります。
- 公開鍵の配布。分散システムは、データの信頼性を証明し、エンドツーエンドのプライバシーを提供するために暗号化に依存しています。IDシステムは、強力なセキュリティで公開鍵を公開する必要があります。
- 鍵のローテーション。ユーザーは、IDを中断することなく鍵マテリアルをローテーションできる必要があります。
- サービスの検出。ユーザーと対話するには、アプリケーションは、特定のユーザーが使用しているサービスを検出できる必要があります。
- 使いやすさ。ユーザーの名前は、人間が読みやすく、覚えやすいものにする必要があります。
- 移植性。IDはサービス間で移植可能である必要があります。プロバイダーを変更しても、ユーザーがID、ソーシャルグラフ、またはコンテンツを失うことはありません。
このシステムを採用すると、エンドツーエンドの暗号化、署名されたユーザーデータ、サービスサインイン、および一般的な相互運用のためのツールがアプリケーションに提供されるはずです。
識別子
私たちは、ハンドルとDIDという2つの相互に関連する識別子形式を使用します。ハンドルはDNS名ですが、DIDは安全で安定したIDとして機能する新しいW3C標準です。
以下はすべて有効なユーザー識別子です。
alice.host.com
at://alice.host.com
did:plc:bv6ggog3tya2z3vxsub7hnal
これらの関係は次のように視覚化できます。
┌──────────────────┐ ┌───────────────┐
│ DNS name ├──resolves to──→ │ DID │
│ (alice.host.com) │ │ (did:plc:...) │
└──────────────────┘ └─────┬─────────┘
↑ │
│ resolves to
│ │
│ ↓
│ ┌───────────────┐
└───────────references───────┤ DID Document │
│ {"id":"..."} │
└───────────────┘
DNSハンドルはユーザー向けの識別子です。UIに表示され、ユーザーを見つける方法として宣伝される必要があります。アプリケーションはハンドルをDIDに解決し、DIDを安定した正規の識別子として使用します。その後、DIDは公開鍵とユーザーサービスを含むDIDドキュメントに安全に解決できます。
- ハンドル
- ハンドルはDNS名です。これらは
com.atproto.identity.resolveHandleXRPCメソッドを使用して解決され、DIDドキュメント内の一致するエントリによって確認される必要があります。詳細はハンドル仕様をご覧ください。 - DIDドキュメント
DIDドキュメントは、DIDレジストリによってホストされる標準化されたオブジェクトです。これらには次の情報が含まれます。
- DIDに関連付けられたハンドル
- 署名鍵
- ユーザーのPDSのURL
DIDメソッド
DID標準は、DIDを公開し、DIDドキュメントに解決する「メソッド」を、ただ一つに定めず多様に定義できるフレームワークを設けています。さまざまな既存のメソッドが公開されおり、それぞれ異なる機能や特徴を持ちます。Atprotoでの使用に際して、以下の基準を設定しました。
- 強い一貫性。特定のDIDに対して、解決クエリによって生成される有効なドキュメントは常に1つだけである必要があります。(一部のネットワークでは、これは確率的なトランザクションの最終性に左右される可能性があります。)
- 高可用性。解決クエリは確実に成功する必要があります。
- オンラインAPI。クライアントは、標準APIを介して新しいDIDドキュメントを公開できる必要があります。
- 安全。ネットワークは、オペレーター、MITM、およびその他のユーザーからの攻撃から保護する必要があります。
- 低コスト。DIDドキュメントの作成と更新は、サービスとユーザーにとって手頃な価格である必要があります。
- 鍵ローテーション。ユーザーは、IDを失うことなく鍵ペアをローテーションできる必要があります。
- 分散型ガバナンス。ネットワークは単一の利害関係者によって管理されるべきではなく、オープンネットワークまたはプロバイダーのコンソーシアムである必要があります。
プロジェクト開始時点で、DIDメソッドのいずれも当社の基準を完全には満たしていませんでした。そのため、私たちはdid-webと、私たちが作成したDID PLCという新規メソッドをサポートすることを選択しました。
ハンドル解決
Atprotoのハンドルは、DIDに解決されるドメイン名です。DIDは、ユーザーの署名公開鍵とホスティングサービスを含むDIDドキュメントに解決されます。
ハンドル解決には、DNSのTXTレコードか、HTTPSのwell-knownエンドポイントを利用します。詳細はハンドル仕様を参照してください。
例:ホスティングサービス
ホスティングサービスがPLCを使用していて、ユーザーのハンドルをサブドメインとして提供しているシナリオを考えてみましょう。
- ハンドル:
alice.pds.com - DID:
did:plc:12345 - ホスティングサービス:
https://pds.com
まず、わかっているのはalice.pds.comなので、_atproto.alice.pds.comのDNS TXTレコードを見てみます。これにより、DIDがdid:plc:12345であるとわかります。
次に、返されたDIDでPLCディレクトリに問い合わせ、ホスティングサービスのエンドポイントとユーザーの鍵マテリアルを確認します。
await didPlc.resolve('did:plc:12345') /* => {
id: 'did:plc:12345',
alsoKnownAs: `https://alice.pds.com`,
verificationMethod: [...],
service: [{serviceEndpoint: 'https://pds.com', ...}]
}*/
これで、https://pds.comと通信してAliceのデータにアクセスできるようになりました。
例:セルフホスト
セルフホストのシナリオを考えてみましょう。did:plcを使用している場合は、次のようになります。
- ハンドル:
alice.com - DID:
did:plc:12345 - ホスティングサービス:
https://alice.com
ただし、セルフホストする人がドメイン名の所有権を保持し続けられると確信している場合、did:plcではなくdid:webを使用できます。
- ハンドル:
alice.com - DID:
did:web:alice.com - ホスティングサービス:
https://alice.com
解決方法は同じく_atproto.alice.comで、DIDとしてdid:web:alice.comが得られます。
これを解決すると以下のようになります。
await didWeb.resolve('did:web:alice.com') /* => {
id: 'did:web:alice.com',
alsoKnownAs: `https://alice.com`,
verificationMethod: [...],
service: [{serviceEndpoint: 'https://alice.com', ...}]
}*/