メインコンテンツへスキップ

デリゲート接続

デリゲート接続は、アプリケーションが一時的または低権限の「agent」DIDを使用してDID Connect操作を実行できるようにすることでセキュリティを強化する高度な機能です。これにより、エンドユーザーには主要で公式なDIDを提示し続けることができます。これは、アプリケーションのメインの秘密鍵が、日々の対話を処理するホットウォレットに決して公開されないことを意味します。

このガイドでは、デリゲート接続の概念を説明し、WalletAuthenticatorを使用してそれを実装する方法を示します。

仕組み

デリゲート接続には、3つの主要な参加者が関与します。

  • 委任者(Delegator): アプリケーションのアイデンティティを所有する主要なDIDです。これは、ユーザーが確認し信頼するDIDです。委任者のウォレットはメインの秘密鍵を保持しており、安全なコールドストレージに保管する必要があります。
  • Agent: 特定のDID Connect操作において委任者に代わって行動することが許可された、二次的で一時的なDIDです。Agentのウォレットは、アプリケーションのバックエンドによって認証リクエストに署名するために使用されます。
  • 委任証明書(Delegation Certificate): 委任者によって署名された、JWT形式の検証可能な資格情報(Verifiable Credential)です。この証明書は、Agentが委任者のために行動する権限を持っていることを暗号学的に証明します。通常、有効期限と許可されたクレームのリストが含まれます。

このプロセスにより、たとえagentの鍵が侵害されても、損害は委任証明書で定義された権限と有効期限によって限定されます。委任者の主要な鍵は安全なままです。

フロー

以下は、委任認証フローを示す図です。

Delegated Connect

  1. 委任

    委任者は、AgentにDID Connectアクションを実行する権限を付与するJWTに署名します。

  2. リクエスト

    アプリケーションのWalletAuthenticatorが認証リクエストを作成します。これはAgentによって署名されますが、iss(発行者)フィールドは委任者のDIDに設定されます。リクエストには委任証明書も含まれます。

  3. 検証

    ユーザーのウォレットがリクエストを受け取ります。まず、Agentの公開鍵を使用してメッセージの署名を検証します。次に、委任者の公開鍵を使用して含まれている委任証明書を検証します。この2段階のプロセスでagentの権限が確認されます。

  4. レスポンス

    ユーザーは、委任者のアイデンティティを明確に示すリクエストを承認し、ウォレットはレスポンスをアプリケーションに送り返します。

実装

デリゲート接続を実装するには、WalletAuthenticatorを委任者、agentウォレット、および委任証明書で設定する必要があります。

ステップ1: 委任者とAgentの定義

まず、2つの異なるウォレットが必要です。1つは委任者(メインのアイデンティティ)として、もう1つはagent(アクティブな署名者)として機能します。

Wallet Setup

javascript
const { fromRandom } = require('@ocap/wallet');

// アプリケーションの主要で信頼されたアイデンティティ
const delegator = fromRandom();

// 日常の操作を処理するagentウォレット
const agent = fromRandom();

ステップ2: 委任証明書の作成

証明書はdelegatorによって署名されたJWTであり、agentに権限を付与します。

Create Delegation JWT

javascript
const Jwt = require('@arcblock/jwt');
const { toDid } = require('@ocap/util');

const createDelegation = () => {
  const now = Math.floor(Date.now() / 1000);
  const claims = [
    'authPrincipal',
    'profile',
    'signature',
    'prepareTx',
    'agreement',
    'verifiableCredential',
    'asset',
    'keyPair',
    'encryptionKey',
  ];

  const payload = {
    agentDid: toDid(agent.address),
    permissions: [{
      role: 'DIDConnectAgent',
      claims: claims,
    }],
    exp: now + 3600, // 1時間で有効期限切れ
    iat: now,
    nbf: now,
  };

  return Jwt.signV2(delegator.address, delegator.secretKey, payload);
};

const delegationCert = createDelegation();

ステップ3: WalletAuthenticatorの設定

delegatordelegation証明書、およびwallet(これはagentです)を提供してWalletAuthenticatorをインスタンス化します。

Authenticator Configuration

javascript
const { WalletAuthenticator, WalletHandlers } = require('@arcblock/did-connect');
const MemoryAuthStorage = require('@arcblock/did-connect-storage-memory');

const authenticator = new WalletAuthenticator({
  // 'wallet'プロパティはAGENTです
  wallet: () => agent.toJSON(),

  // 委任者はメインのアプリIDです
  delegator: () => delegator.toJSON(),

  // 委任を証明するJWT
  delegation: () => delegationCert,

  appInfo: () => ({
    name: 'Delegated Connect Demo',
    description: 'Demo of delegated authentication',
    icon: 'https://arcblock.oss-cn-beijing.aliyuncs.com/images/wallet-round.png',
  }),
});

const handlers = new WalletHandlers({
  tokenStorage: new MemoryAuthStorage(),
  authenticator
});

// Expressアプリにアタッチします
handlers.attach({
  app: server, // Expressアプリのインスタンス
  action: 'delegatedLogin',
  claims: {
    profile: () => ({ fields: ['fullName'], description: '委任によるログイン' }),
  },
  onAuth: (claims) => {
    console.log('User authenticated:', claims);
  },
});

DID Connectセッションが開始されると、WalletAuthenticatorは自動的に委任フローを処理します。QRコードには、ユーザーのウォレットが委任者からagentへの信頼の連鎖を検証するために必要な情報が含まれます。ユーザーには、アプリケーションのメインアイデンティティ(委任者)からのリクエストが表示され、シームレスで安全な体験が提供されます。

コンストラクタのオプションに関する詳細については、WalletAuthenticator APIリファレンスを参照してください。