Memories / ドキュメント

このページの内容

リモートデーモン(HTTP/WebSocket とリレー RPC)

Memories は、同じフレーム化された service::Request プロトコルを次の経路で提供できます。

  1. ローカル IPC(既定。OS ユーザー認証。長さプレフィックス付きフレーム)
  2. HTTP + WebSocket(任意の待ち受け。トークン認証。リレー RPC と同じバイナリ JSON フレーム)
  3. 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"