# 通常通信の観測とブラウザの送信先制限 ## 有効化 管理者用 Settings → Network → 通信の観測・制限から、既存の config.yaml へ `egress` を保存できる。未設定の既定値は観測・CSPとも無効。UIからの保存は設定変更通知で直ちにサーバーへ反映され、サーバー再起動は不要。ブラウザのCSPは次の文書レスポンスから適用されるため、既存の画面・タブは再読み込みが必要。 UIでの変更を禁止したい環境では、管理者だけが書き換えられる JSON ファイルを用意し、`AAO_EGRESS_POLICY=/etc/maestro/egress.json` を起動環境へ指定する。変更には再起動が必要。指定した場合は config.yaml より優先し、UIとAPIで通信設定の変更をロックする。外部ファイル未指定なら保存済みのUI設定を使い、明示したファイルが存在しない・不正・64 KiB 超ならサービス起動前に失敗する。ワーカーと Gateway の標準エントリーポイント、および旧 `dist/index.js` で読み込む。 ```json { "version": 1, "observeNode": true, "browser": { "mode": "report-only", "connectOrigins": [], "imageOrigins": ["https://tile.openstreetmap.org"], "frameOrigins": [] } } ``` 用途ごとの配列は最大128件、各要素はスキーム・ホスト・ポートのみ。同じサイトの通信は既定で許可される。接続先には必要に応じて `wss://...` も指定する。空配列は追加許可なし。パス、資格情報、ワイルドカード、未知の設定項目を拒否する。この外部ファイルはアプリの管理画面や設定変更APIから編集できない場所へ配置する。外部ロック中でも、無関係な設定の保存は可能。同値の通信設定を含む全体保存では、外部ファイルや保存済みのegress値を書き換えない。 ブラウザの `off` は無効、`report-only` は報告のみ、`enforce` は遮断。まず起動・待機・使用する全機能を report-only で検査し、必要な宛先をレビューしてから enforce へ切り替える。特に地図タイル、外部アバター、Markdown画像、直接モデル一覧を取得する推論サーバー、埋め込みページを確認する。既存のファイル閲覧用 `sandbox` CSP は追加ポリシーとして保持される。 ## 記録と限界 Node は `diagnostics_channel` の HTTP client、Undici、TCP socket チャンネルを観測する。HTTP は論理的な origin、TCP は接続成功時のリモートIP・ポート。WebSocket の handshake はHTTPとして数える。HTTP と TCP は同一リクエストの別層なので合算しない。Node 22 の実通信で検証している。UIから観測を無効にすると購読・定期集計を停止し、有効に戻すと新しい集計を開始する。 `[egress]` に新規の接続先、`[egress-summary]` に60秒間隔の累積件数を標準ログへ出力する。既定のログレベル info が必要。保持上限は256件で、上限以降の新規宛先の件数を `overflow` に計上する。再起動で集計は消える。本文、Cookie、Authorization、URLのパス・クエリ・フラグメントは収集しない。originのホスト名・IPも機密となり得るため、ログのアクセス権と保存期間を別途管理する。 **この観測はサーバー側の遮断でも、全通信の証明でもない。** 子プロセス、ネイティブ通信、UDP、DNS問い合わせ、接続失敗したTCPなどは網羅しない。詳細は[サーバーのネットワーク境界](./server-egress-boundary.md)を参照する。エージェントが生成したコードや子プロセスにも制限を効かせるにはOS側の境界が必要。 `[security:csp]` は最大256種類の違反の初回だけを記録する(同じ違反の再送や集計上限以降はログに追加しない)。受信は1分1000要求、本文16 KiBを上限とし、圧縮本文を拒否する。 ブラウザのCSP違反報告は未認証・未検証のクライアント入力であり、監査証跡や自動許可判断に使わない。許可した外部iframe内部の通信、利用者による別ページへの移動、ブラウザ拡張機能、既に開いている旧ポリシーのページはこのCSPだけでは管理できない。適用後は画面を再読み込みする。同一originサーバーのプロキシAPIや許可済みサービスを通じた送信も、CSPだけでは排除できない。 ## 回帰検証 ```sh npm run build:server npm run build:ui npm run security:egress npm run security:egress-settings npm run security:ui-assets -- --csp ``` Playwright Chromiumが必要。検査は一時DB・一時設定・最小限の子プロセス環境で実ワーカーを起動し、ループバック上の偽LLM・許可先・拒否先だけを使う。report-only/enforceでHTTP・画像・WebSocketを検査し、同一originのsandbox iframe内の画像遮断と不正ポリシーによる起動拒否も検証し、enforceで65秒待機して定期観測を確認する。本番の接続設定や資格情報は継承しない。さらに同じCSPを実UI部品の検査に適用し、フォント・Monaco編集保存・worker・Leaflet描画と未許可CDNの遮断を確認する。設定画面からの保存・即時反映・再起動後の保持・外部ポリシーのロックも検査する。CIでも実行する。 この検査の成功は、テストで通した起動・画面・待機経路の結果であり、全依存ライブラリの全機能の無通信を保証しない。OS境界の遮断試験は別途、実際の配備先で実施する。 ## 参照 - [Node.js diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html) - [Undici diagnostics channels](https://github.com/nodejs/undici/blob/main/docs/docs/api/DiagnosticsChannel.md) - [CSP: 複数ポリシーの適用](https://www.w3.org/TR/CSP3/#multiple-policies) HTTPヘッダーの送信直前にCSPを合成するため、既存の推移的依存 `on-headers` を直接依存として明示した。`@types/on-headers` は開発時の型定義のみ。