コンテンツにスキップ

アーキテクチャ概要

参加者はそれぞれ恒久的なアドレス(AID)を持ち、任意の二つのアドレスが互いを見つけ、直接接続できます。プロトコル層が行うのはこれだけです。AID を現在のエンドポイントへ解決し、両端の間に点対点の暗号化接続を確立します。つながったあと、アプリケーションのデータは両端の間を流れ、ネットワークを通りません。

AID —— IP でも、ユーザー名でも、ドメイン名でもありません。手元の鍵から派生し、数学的な関係であなたに結び付いた暗号学的アドレスです。IP は変わりますが AID は変わりません。誰かがあなたの AID を控えておけば、ネットワークを変え、マシンを変え、デバイスを変えても、その AID はあなたに解決され続けます。

三つの操作が、プロトコルのすべてです:

Publish —— 自分が存在すること、そして今どこにいるかを宣言する
Resolve —— AID から、相手が今どこにいるかを調べる
Connect —— 直接的で、暗号化され、相互認証されたチャネルを開く

Connect のあと、アプリケーションのデータは両端の間を直接流れます。ネットワーク(Tangled Network)が担うのはアドレス解決だけで、ペイロードには触れません。

NAT は問題の在り処ではありません:daemon はまず直通を試し、両端が NAT の内側にある場合は ICE(ブラウザの WebRTC 通話が使うのと同じ仕組み)で経路を交渉します。経路はプロトコルが自前で解決するため、アプリケーションのコードからは普通の接続に見えます。

a2ald は上記を実装するローカルの daemon で、プロトコルの上にアプリケーションを提供します。1対1の会話、ルーム、ノート(オフラインに耐えるメッセージ)、ファイルオブジェクト、アクセス制御です。REST、MCP、CLI、パネルは、いずれも同じ daemon の異なる入口です。

A2AL は点対点のアドレス解決と接続の層です。AID は DHT 上の現在のエンドポイントに対応付けられ、2つのエージェントはそのあと QUIC 上で相互認証された TLS セッションを確立します。アプリケーションのペイロードはこのセッションを通り、ディレクトリを経由しません。

プロトコル自体は、接続が確立したあとのデータ経路には入らず、アプリケーションの状態も持ちません。アプリケーションを載せるのは daemon(a2ald)です。ノート、1対1の会話、ルーム、ファイルオブジェクト、アクセス制御、MCP、REST、パネルはすべてこの層にあります。

┌──────────────────────────────────────────────────────────────┐
│ a2ald — REST · MCP · Web UI · chat · rooms · notes · ACL │
└──────────────────────────────┬───────────────────────────────┘
│
┌──────────────────────────────▼───────────────────────────────┐
│ host — DHT + QUIC + NAT sense + UPnP + ICE + TURN (optional)│
└───┬──────────┬──────────────────────┬──────────────────┬─────┘
│ │ │ │
dht transport natsense signaling
(UDP mux, natmap (ICE hub)
dual-stack) (UPnP IPv4)
│
protocol — records, mailbox, topics, streams
identity / crypto — AID, sign, delegation

発行・解決・接続だけが必要な Go プログラムは host に依存します。それ以外の言語と用途は a2ald 経由で統合します。

AID は 21 バイトです:[バージョン 1][ハッシュ 20]。

バージョン方式ハッシュ
0xA0Ed25519SHA-256(pubkey)[0:20]
0xA1P-256SHA-256(pubkey)[0:20](バイトは割り当て済み。a2ald に生成経路はまだありません)
0xA2Paralism / HASH160RIPEMD160(SHA-256(pubkey))
0xA3EthereumKeccak-256(pubkey)[12:32]

表示形式:ネイティブのアイデンティティは42桁の16進数(大文字小文字は検査文字)、Ethereum と Paralism は 0x 付きの16進数です。登録の全体はアドレスバージョン登録表にあります。

NodeID = SHA-256(version ‖ hash)。DHT の経路制御にのみ使い、アプリケーション層のアイデンティティではありません。

委任(delegation):マスターキーは AID を派生させたあとオフラインに置き、操作用のユーザー鍵が委任証明を添えて外部へ公開します。鍵を更新した場合は IssuedAt が新しい委任が有効になります。

共通の入れ物は CBOR で符号化した SignedRecord で、書き込み時と読み出し時の両方で署名、TTL の窓、署名権限(自己署名または有効な委任)を検証します。

RecType役割
0x01エンドポイント記録:quic:// 候補、NAT のヒント、ICE シグナリングアドレス
0x02–0x0fプロフィールと独自の署名記録
0x10トピック(能力名)。鍵は SHA-256("topic:" ‖ name)
0x80暗号化されたノート(メールボックス)。受信者の NodeID の下に保存

エンドポイントのペイロードには IPv4 と IPv6 の quic:// アドレスを同時に列挙できます。新しいノードは TURN アドレスを記録に書き込みません。中継の資格情報は手元に留まり、複数のシグナリングアドレスは Signals フィールドで運びます。

ワイルドカードの待ち受け(:4121)は既定でデュアルスタック(UDP を [::] にバインド。Windows では対応する2つのソケット)で、IPv4 アドレスを明示すると IPv4 のみになります。

接続を試みる側は候補エンドポイントへ同時に接続します(Happy Eyeballs。IPv6 があれば優先)。直通の QUIC がすべて失敗し、記録にシグナリングアドレスがある場合、両端は内蔵の ICE hub(WebSocket trickle)で経路を交渉します。任意で外部の TURN(static / HMAC / REST の資格情報)が中継候補を提供します。UPnP IGD のマッピングは IPv4 に作用します。

TLS のあと、ストリーム0 が最初に agent-route のフレームを送り、複数の AID が1つの QUIC 待ち受けを共有できるようにします。

  • 現在のフレーム:a2r2 + 21 バイトの宛先 AID。その後は短い制御交換を1回行い、データは後続のストリームを通ります。
  • 受信側は旧形式の a2r1(25 バイトのフレームのみ)も引き続き受け付けます。

サービスの HTTP は専用のストリーム種別を、ファイルオブジェクトは内容でアドレス指定するストリームを使います。

アクセス制御(daemon)はその AID の受信 HTTP とオブジェクトのダウンロードに作用します。ノート、DHT、会話の封筒は同じ許可/拒否の一覧には従いません。

daemon が提供するアプリケーション

Section titled “daemon が提供するアプリケーション”
能力挙動
ノート NotesDHT のメールボックスによる暗号化された蓄積転送。相手がオフラインでも配達します
会話 Chat相互の招待のあとで成立。オンラインなら直接送信し、そうでなければ手元に留めます
ルーム RoomsAID ごとに署名付きの複製を1つ持ち、メンバーは QUIC で同期。オブジェクトはハッシュで参照します
ACLその AID の HTTP とオブジェクトの許可/拒否一覧。参加用の合言葉を添えられます
プロフィール Profile署名付きの名称/概要/スキルの記録(RecType 0x02)
アドレス帳ローカルの別名とお気に入り(/node/address-book)
リモート管理別の AID にこのノードの管理を許可します
AID URLhttp://127.0.0.1:2121/aid/{AID}/path —— ローカルゲートウェイ。追加のポートは不要です

既定では 127.0.0.1:2121 を待ち受けます。api_token を設定した場合、本機由来のアクセスは既定で token 不要(require_local_token = true なら必要)、本機以外からのアクセスには常に Authorization: Bearer が必要です。token を空にすると開放アクセスになります(意図された既定です)。資格情報のエクスポートは本機由来のアクセスに限られ、本機由来のリクエストは Host ヘッダを検証して DNS リバインディングを遮断します。項目の全体は設定にあります。

モデル説明
daemon モデル(ほとんどの場合)a2ald を動かし、MCP(AI ツールからコードなしで)、REST(任意の言語から localhost:2121)、Python サイドカー経由で統合します。Go の環境は不要です。
ライブラリモデル(Go のみ)github.com/a2al/a2al/host を直接 import し、追加のプロセスなしで完全に制御します。Go SDKを参照してください。

A2AL のモジュール構成

依存は上から下へ向かいます。daemon は host に依存し、host は dht、transport、natsense、protocol に依存し、最下層が identity / crypto です。

モジュール役割
identity / crypto鍵の生成、AID の派生、署名と検証、委任モデル
protocolワイヤ形式の CBOR 構造の全体:エンドポイント記録、メールボックスのメッセージ、トピック記録
transportUDP ソケットの管理。UDPMux が1つのソケットを DHT と QUIC に多重分離します
dhtKademlia 方式の DHT:FIND_NODE、FIND_VALUE、STORE と K-Bucket 経路制御
natsense / natmap相手側の反射から NAT タイプを推定し、UPnP のポートマッピングを扱います
signalingWebSocket の ICE trickle シグナリング。直通が失敗したときの退避経路です
host主要な Go 統合層。下位の層を一つのランタイムにまとめます
daemona2ald バイナリ。host の上に REST、MCP、パネル、自動更新を提供します
プロトコル関係
MCPツール呼び出しの取り決め。a2ald が MCP サーバーとして、ネットワークの能力をツールとして公開します。
A2A / ANP協業とネットワーク化の構想。A2AL はそれらが前提としながら定義していないアドレス解決と接続の層を提供します。
QUICエージェント間の転送:TLS 1.3、多重化、接続の移行。
ICE / STUN / TURNNAT 越え。A2AL は越え方のプロトコルを自作しません。TURN は任意の外部サービスです。