Skip to content

CIP-11: Realtime API

本仕様は、Concrnt サーバーのエンドポイントを拡張し、サーバーで発生したリソースの変更イベントを リアルタイムにクライアントへ通知する手段を提供する。

このドキュメントは Realtime API の仕様を定義する。 Concrnt プロジェクトにより公開されるバージョン付き仕様であり、実装者およびプロトコル設計者を対象とする。

本 CIP はオプショナルな拡張であり、CIP-0, CIP-1 を前提とする。イベントの redaction には CIP-12 を必要とする。

本仕様はドラフトであり、後方互換性のない変更が行われる可能性がある。

このドキュメントにおける以下の語は、必ず大文字で記述される場合、 BCP 14 [RFC2119] [RFC8174] にしたがって解釈される。

MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, OPTIONAL

本 CIP を実装するサーバーは、WebSocket [RFC6455] へアップグレード可能な HTTP GET エンドポイントを 提供し、CIP-0 のサービスディスカバリにおいて net.concrnt.core.realtime エンドポイント名で 広告しなければならない (MUST)。

{
"version": "2.0",
"csid": "ccs1<bech32-encoded-address>",
"endpoints": {
"net.concrnt.core.resolve": "/resource/{uri}",
"net.concrnt.core.realtime": "/realtime"
}
}

クライアントは、Realtime エンドポイントに対して WebSocket ハンドシェイクを行い、 接続確立後に以下の JSON メッセージを送信して、リソースの変更イベントの購読を開始する。

{
"type": "subscribe",
"prefixes": [
"<CCURI>",
"<CCURI>"
]
}
  • type メッセージ種別。購読の開始は "subscribe" を指定する。 サーバーは "listen" を "subscribe" の別名として受理してもよい (MAY。旧仕様との互換のため)。 このほか、"h" はハートビートを表すメッセージ種別であり、サーバーは何も行わず受理する。

  • prefixes 購読するリソースの CCURI の配列。

購読のマッチングは、イベントの source (§3.2) の CCURI 文字列に対する単純な前方一致とする (MUST)。 指定した CCURI そのものに加え、それを接頭辞とするリソースで発生したイベントも通知される (CIP-5 §3.1 の prefix と同じ規則であり、item の購読には兄弟キー item2 もマッチする点に注意)。 prefix 中の * ? [ 等の文字をワイルドカードとして解釈してはならない (MUST NOT)。

各 prefix は owner 部を持つ有効な CCURI でなければならない (MUST)。owner 部を持たない prefix (空文字列や cckv:// 等) は、サーバー全体のイベントの購読を許すため、無視しなければならない (MUST)。 サーバーは、1 接続あたりの prefix 数に上限を設けるべきである (SHOULD)。

複数回 subscribe メッセージが送信された場合、サーバーは最新の購読リストのみを保持する (購読リストの全置換)。明示的な unsubscribe メッセージは存在せず、購読の解除は縮小した購読リストに よる subscribe の再送によって行う。

サーバーは、未知の type を持つメッセージを受信した場合、接続を切断せず無視するべきである (SHOULD)。 サーバーは接続の生存確認に WebSocket の Ping フレーム (RFC6455) を用いるべきであり (SHOULD)、 アプリケーションレベルの "h" メッセージの受信を接続維持の条件としてはならない (MUST NOT)。

3.1.1 外部リソースの購読 (中継)

Section titled “3.1.1 外部リソースの購読 (中継)”

prefixes に指定するリソースは、そのサーバーが管理しているものでなくてもよい。 外部リソースが要求された場合、サーバーはそのリソースの権威サーバーの Realtime エンドポイントへ 代理で購読を行い、イベントを中継してもよい (MAY)。 中継を行わないサーバーは、管理外の prefix に対するイベントを配信しない (購読メッセージ自体はエラーとしない)。クライアントは、確実に受信するためには 対象リソースの権威サーバーへ直接接続することができる。

中継を行う場合、以下に従う。

  • 上流接続の宛先が、プライベート・ループバック・リンクローカルアドレスへ解決される場合、 接続してはならない (MUST NOT)。
  • 1 接続あたり、およびサーバー全体で確立する上流接続数に上限を設けなければならない (MUST)。
  • 中継されたイベントを、それを受信した上流接続へ再送してはならない (MUST NOT)。 中継のホップ数に上限を設けるべきである (SHOULD)。

サーバー間中継の詳細プロトコル (上流の多重化、購読の張り替え、再接続方式等) は本仕様では 規定せず、将来の CIP に委ねる。

サーバーは、購読されたリソースに変更が発生した場合、以下の JSON メッセージをクライアントに送信する。

{
"type": "created",
"source": "<CCURI>",
"uri": "<CCURI>",
"association": "<CCURI>",
"documents": {
"<CCURI>": { ... }
},
"timestamp": "2025-11-23T12:34:56Z"
}
  • type (required) 変更イベントの種類を示す文字列。とりうる値は以下の通り。

    • "created": 新しい Document が作成されたことを示す。既存キーの上書き (CIP-3 §3.4) の場合も "created" を発行する (Document の作成を示すのであり、キーの新規性を示すものではない)。
    • "deleted": Document が削除されたことを示す。
    • "associated": Document に Association (CIP-9) が作成されたことを示す。
    • "unassociated": Document から Association が削除されたことを示す。

    クライアントは、未知の type を持つメッセージを、接続を切断せず無視しなければならない (MUST)。

  • source (required) イベントが発行されたチャンネル (変更が発生したリソース側) の CCURI を設定しなければならない (MUST)。 購読プレフィックスの値そのものを設定してはならない (MUST NOT)。 クライアントは、自身の購読プレフィックスと source の前方一致により、由来する購読を判別する。

  • uri (required) 変更対象となったリソースの CCURI。 "created" / "deleted" では作成・削除された Document の URI、 "associated" / "unassociated" では関連付けの対象となった Document の URI が入る。

  • association (OPTIONAL) "associated" / "unassociated" イベントにおいて、作成・削除された Association Document の ccfs URI を設定するべきである (SHOULD)。

  • documents (OPTIONAL) イベントに関連する Concrnt Signed Document (CIP-1) を、そのリソースの CCURI をキーとした マップで格納する。

    • "created": 作成された Document (キーは uri と同じ) を含む。
    • "associated": 作成された Association Document (キーは association と同じ) を含む。
    • "deleted" / "unassociated": 通常このフィールドは省略される。

    保護された Document の編集 (redaction): サーバーは、イベントの送出時に、対象 Document の 読み取りアクション (record:read / association:read, CIP-12) をゲスト (匿名) リクエスタで 評価し、匿名での読み取りが許可されない Document については documents フィールドから その内容を省略しなければならない (MUST)。この場合もイベント自体 (type / source / uri / timestamp 等) は配送される。 同梱される Signed Document がネストされた references (CIP-1) を持つ場合 (例: 配布 Reference Document に内包された元 Document)、その各エントリにも同じ 匿名 read 評価を適用し、許可されないエントリは省略しなければならない (MUST)。 さらに深い階層のネストは一律に省略してよい (MAY)。参考実装は省略する。 クライアントは、内容が省略されたイベントを受信した場合、必要に応じて自身の認証情報を 用いた通常の Resolve / Query (CIP-0, CIP-5) で Document を取得する。

  • timestamp (required) イベントの発生時刻。"created" イベントでは Document の createdAt の値が入る。 それ以外のイベントでは、サーバーがイベントを発行した時刻が入る。

  • Realtime API の配信内容は匿名で閲覧可能な情報に限定される。購読自体には認証を要求しない 代わりに、匿名リクエスタで読み取りが許可されない Document の内容は §3.2 の redaction 規則により イベントから省略されなければならない (MUST)。これにより、購読者ごとの認可評価や サーバー間中継時のアイデンティティの伝搬を必要とせず、保護された Document の内容が 未認可の購読者 (および中継先) へ漏えいすることを防ぐ。
  • イベントのメタデータ (uri 等のキー情報・イベントの発生事実) は保護の対象外である。 購読は前方一致 (§3.1) であるため、キー名そのものが機微である場合は保護されない。 リソースの存在自体を秘匿する必要がある用途では、Realtime API によるイベント配信を 行うべきではない (SHOULD NOT)。
  • イベントは配信元サーバーが構成する助言的な通知であり、それ自体は暗号学的な証明を伴わない。 クライアントは、イベントのみを根拠にリソースの状態を確定せず、必要に応じて対象を resolve で 確認すること。特に deleted / unassociated イベントは、伝搬削除の受信処理 (CIP-4 §6.1) の 性質上、実際には削除されていない対象について発行されうる。
  • 中継 (§3.1.1) は匿名クライアントの指定に基づく外向き接続であり、SSRF・増幅・ループの 温床となる。中継を行うサーバーは §3.1.1 の防御を省略してはならない。
  • RFC 2119 – Key words for use in RFCs to Indicate Requirement Levels
  • RFC 8174 – Clarifications to RFC 2119
  • RFC 6455 – The WebSocket Protocol
  • CIP-12 – Policy (record:read / association:read)

この文書は concrnt/CIPs-translated の ja/11-realtime.md から生成されています。原文(英語)は concrnt/CIPs を参照してください。