リモートデーモン(HTTP/WebSocket とリレー RPC)
Memories は、同じフレーム化された service::Request プロトコルを次の経路で提供できます。
- ローカル IPC(既定。OS ユーザー認証。長さプレフィックス付きフレーム)
- HTTP + WebSocket(任意の待ち受け。トークン認証。リレー RPC と同じバイナリ JSON フレーム)
- WSS リレー RPC(
/v1/rpc/{room}/{slot})
直接接続とリレー経由のリモート接続は、AuthFrame の後にバージョン 1 の Wire(service::Request)を載せる WebSocket バイナリフレームという同じ通信方式を共有します。保管庫の同期は引き続き /v1/channel を使用します。WebUI は状態表示専用のままです。
セキュリティ規則
- 待ち受けトークンは
--listen-token/MEMORIES_LISTEN_TOKENで指定するか、HTTP/リレーホストを有効にしたときに生成され、一度だけ表示されます。トークンを TOML に入れないでください。 - ストアがロックされるとトークンは消去されます。
- リモート呼び出し元は安定した昇格名前空間
ws:remote/relay:remote(cli:{pid}とは別)を使用します。リモートトランスポート経由のロック解除と sudo はその名前空間を昇格させるため、後続の単発接続もアイドル期間中は昇格を保持します(ローカルと同じ規則で、アイドル 5 分 / 最大 15 分)。 - デスクトップの HTTP/リレーホストは、ロック解除/sudo 後に 完全な
handle_clientの機能(保管庫、カード、記憶、ファイル、認証情報、同期、MCP 許可、バックアップ、ホスト上のプロキシバインド、リモートセッション、Run、CryptoJob など)を公開し、ローカル IPC と同じ昇格チェックを適用します。 - HTTP 待ち受けは既定でループバックです。ループバック以外には
--allow-non-loopbackが必要です。 - 平文 HTTP/WS は証明書不要です(直接 LAN 接続の既定)。
- 任意の TLS:
--tls-cert/--tls-key(PEM)で、同じ待ち受けに HTTPS/WSS を有効にします。https://の待ち受け URL にはこれらのフラグが必要です。 - 信頼範囲外のリレーは、43 文字のルーム ID とトークンを使用した
wss://である必要があります。 - 待ち受けトークンの所有者は、そのトランスポート名前空間において、ローカルの昇格済みクライアントと同じだけ信頼されます。トークンをパスワードと同様に扱い、ループバックまたは認証済みのネットワーク経路を優先してください。
残るリスク
- トークンの盗難 ⇒ ロック解除/昇格済みのデスクトップデーモンを完全にリモート制御できます。
- ループバック以外の HTTP は、フレーム化 API をネットワークに公開します。ループバック以外にバインドする場合は、
--tls-cert/--tls-key、リバースプロキシ、VPN、またはファイアウォールを使用してください。 - リレー RPC(
/v1/rpc/{room}/{slot})は認証されますが、エンドツーエンド暗号化されていません。アプリケーションレベルの JSON フレームは、共有待ち受けトークンに続いてリクエストとレスポンスを運びます。リレー運営者や TLS 終端はトークンと RPC ペイロードを読み取れます。WSS はリレーへの各接続を保護しますが、リレー自体からは保護しません。リモートデーモンへのアクセスには信頼できるリレーを使用してください。 - 保管庫のピア同期(
/v1/channel)は別の経路で、エンドツーエンド暗号化されたペイロードを運びます。このチャネルでリレー運営者に見えるのは暗号文の長さとタイミングであり、アセットの平文ではありません。 - ホスト側のプロキシリスナーは引き続きデーモンのマシンのループバックにバインドします。リモートクライアントは昇格時に開始できますが、そのホストのループバックにも到達できる場合(通常は別のトンネル経由)にしかアクセスできません。
HTTP/WebSocket のホストとクライアント
# Host (prints a token once if --listen-token is omitted)
memories daemon --listen http://127.0.0.1:7900
# or HTTPS URL when TLS is configured:
memories daemon --listen https://127.0.0.1:8443 \
--tls-cert certs/daemon-tls.crt --tls-key certs/daemon-tls.key --listen-token "$TOKEN"
# Client (another shell / machine that can reach the listener)
export MEMORIES_DAEMON=http://127.0.0.1:7900
export MEMORIES_DAEMON_TOKEN="$TOKEN"
memories status
memories unlock
memories sudo
memories vault list
直接 RPC のパスは /v1/rpc(WebSocket アップグレード)です。フラグは --daemon、--daemon-token(環境変数と同じ意味)です。
クライアントの TLS 信頼
証明書とホスト名の検証は既定で有効です。グローバルオプション --ca-file PATH は、PEM CA バンドルのすべての証明書を通常の信頼ストアに追加します。自己署名のデーモンでは、その証明書を明示的に信頼してください(DNS/IP のサブジェクト代替名は引き続き URL と一致する必要があります)。
memories --daemon https://localhost:8443 --daemon-token "$TOKEN" \
--ca-file certs/daemon-tls.crt status
# Equivalent CA setting, also usable with relay and HTTPS clients:
export MEMORIES_CA_FILE=certs/daemon-tls.crt
memories --daemon https://localhost:8443 --daemon-token "$TOKEN" status
# DANGEROUS: development only; prefer --ca-file instead.
memories --daemon https://localhost:8443 --daemon-token "$TOKEN" --insecure status
--insecure は証明書チェーンとホスト名の検証を無効にします。 TLS 暗号化は有効なままですが、攻撃者がサーバーになりすまし、デーモントークン、認証情報、リクエスト/レスポンスのデータを読み取れるようになります。本番環境や信頼できないネットワークでは使用しないでください。CLI 専用です(MEMORIES_INSECURE 環境変数はありません)。明示的に指定された CA ファイルは、--insecure を使用していても読み取り可能で、有効な PEM 証明書を含む必要があります。無効なファイルは接続前に失敗します。ファイルは起動時に一度だけ読み込まれるため、バンドルを変更したらプロセスを再起動してください。
両オプションは、現在のプロセスが行う外向き接続に適用されます。直接のデーモン HTTPS/WSS 接続、リレー RPC ホスト/クライアント、保管庫同期リレークライアント、クラウド OAuth と Drive HTTP、RAG API/モデルダウンロード HTTP、認証情報で認証される HTTPS、自動化 Webhook、データベース TLS セッション/プロキシが対象です。デーモンで実行される操作には、そのデーモンの起動時にオプションを渡してください。クライアントのフラグは RPC 経由で送信されず、デーモンの上流 TLS ポリシーを変更できません。
memories --ca-file /path/internal-ca.pem daemon
# Development only: affects every outbound TLS connection in this daemon.
memories --insecure daemon
サーバーの --tls-cert / --tls-key と共有トークン認証は変わりません。データベースの --tls-ca CA_ID は引き続き保管庫内の PEM 認証情報を解決し、その信頼はデーモンの --ca-file バンドルと組み合わされます。どちらのオプションも TLS または SSH ホストキーピンニングを無効にしません。これらのフラグは TOML 設定ではなく、保管庫のシークレットとして永続化されず、モバイル/FFI の呼び出し元、外部プログラム/ブラウザーの TLS クライアント、これらの HTTP ビルダー外の依存関係管理下のダウンロードを設定しません。
リレー RPC のホストとクライアント
# Generate a room id (43 URL-safe characters)
memories sync room
# Host joins slot a
memories daemon \
--relay-host wss://relay.example.com \
--room "$ROOM" \
--listen-token "$TOKEN"
# Client joins slot b
export MEMORIES_DAEMON_RELAY=wss://relay.example.com
export MEMORIES_DAEMON_ROOM="$ROOM"
export MEMORIES_DAEMON_TOKEN="$TOKEN"
memories status
ローカル開発では、memories-relay とともに ws://127.0.0.1:8787 を使用できます。
プライベート CA を持つリレーでは、ホストとクライアントの両方でグローバルフラグを使用できます。
memories --ca-file /path/relay-ca.pem daemon \
--relay-host wss://relay.example.com --room "$ROOM" --listen-token "$TOKEN"
memories --ca-file /path/relay-ca.pem --daemon-relay wss://relay.example.com \
--daemon-room "$ROOM" --daemon-token "$TOKEN" status
モバイル共有(フォアグラウンドホスト)
Flutter アプリは、ロック解除済みでフォアグラウンドにある間、リレー RPC にホスト(スロット a)として参加する共有セッションを開始できます。バックグラウンドへの移行やロックでセッションは終了します。モバイルは FFI 拒否リストを維持します(Run/CryptoJob/MCP 許可/リモートセッション/プロキシは不可。共有では認証情報の平文コピーとバックアップダンプも拒否します)。スマートフォンは HTTP リスナーを開きません。mobile/README.md を参照してください。
ローカル限定 / プラットフォームの例外
| 機能 | デスクトップのリモート(HTTP/WS / リレー) | モバイル FFI / 共有 |
|---|---|---|
| 保管庫 / 記憶 / カード / ファイル / 同期 / 状態 / ロック解除 / sudo | 全機能(必要な場合は昇格) | FFI が許可する範囲の全機能 |
| MCP 許可/取り消し、バックアップ、CredentialCopy | 昇格時は全機能 | 共有では拒否。FFI はローカルでコピー/バックアップを許可 |
| Run、CryptoJob、Remote、Proxy | 昇格時は全機能(ホスト上で実行) | 拒否(デスクトップランタイムなし) |
| HTTP/WS 待ち受け | 任意(--listen) |
利用不可 |
ペルソナ自動化 Webhook
HTTP 待ち受けが有効な場合、受信する自動化トリガーは次の場所で受け付けます。
POST /v1/persona/{vault}/{persona}/automation/trigger
Authorization: Bearer <persona world.automation.webhook_token>
Content-Type: application/json
{"hook":"HOOK_ID"}
デーモンはロック解除済みである必要があります(他の書き込み RPC と同様)。待ち受けトークンは HTTP の機能を有効にし、自動化の webhook_token(persona automation put
--webhook-token で設定)がフックを認可します。リレーホストは、リレー上の POST /v1/persona/{room}/{vault}/{persona}/automation/trigger で同じ呼び出しを受け取ります(本文と Webhook の Bearer は同じ)。パスの唯一の違いはルーム部分であり、リレーはローカルで処理したり外向きに送信したりする代わりに、既存の persona_automation_trigger 通信フレームを 1 個、接続済みホストに転送します。同等の CLI は次のとおりです。
memories persona automation trigger VAULT PERSONA --id HOOK_ID \
--source webhook --token "$WEBHOOK_TOKEN"