脅威モデル
HacoL では、チャットの本文と添付を、運用者のサーバーの Postgres と Synapse の media に保管します。AI はローカル MCP からそれを読みます。AI は、管理画面で許可した部屋にだけ、停止スイッチがオフのときに限り送信できます。
データの置き場所#
| データ | 置き場所 | 見られる人 |
|---|---|---|
| メッセージの本文とメタデータ | Context DB(運用者の Postgres) | 管理画面、API キーを持つ人 |
| 添付(画像、PDF など) | Synapse の media_store(運用者のディスク) | 同上(メディア API と MCP) |
| LINE と WhatsApp の本体 | 端末と各社のクラウド(これまでどおり) | ブリッジは連携デバイスとして同期します |
- ブリッジで取り込んだ分は、端末をなくしてもサーバー側で検索し、取り出せます。
- LINE や WhatsApp 側の全履歴が自動で入るとは限りません。LINE はつなぐ前の履歴を部屋ごとに直近の500件まで取り込みます。WhatsApp は最初の取り込みが控えめで、新しいメッセージは通常どおり同期します。
- 送信者が取り消したメッセージは、行を残したまま中身を消します。
redactedとredacted_atを記録し、本文、添付の情報、元のイベントの中身を消します。API は取り消したメッセージの本文と添付を返しません。 - 管理用の部屋(ブリッジの bot との DM)は、ログインの案内が流れる部屋です。Context はこの部屋を分類のために記録しますが、本文は保存しません。読み取り系の API はこの部屋に 404 を返します。2026-09-30 より前に作った環境には、管理用の部屋の本文が残っていることがあります。
- LINE のメールアドレスとパスワードは、固定した LINE のブリッジが自分の DB(
line_bridge)に保存します。管理画面から送った Matrix のイベントは redact しますが、Synapse は元のイベントを自分の DB に持ち続けます。
暗号化について#
- LINE の Letter Sealing(エンドツーエンドの暗号化)は、ブリッジが動くホストで復号されます。
- Matrix の部屋の暗号化は使っていません。
- 会話の全文を、自分の DB に平文で保存します。
注意ホストと DB、バックアップを持つ人は、会話の全文を読めます。ホストの管理とバックアップの扱いは運用者が決めます。
信頼の境界#
context-app の前提の設定
READ_SCOPE=all_bridged_line_rooms
SEND_SCOPE=explicit_allowlist
DEFAULT_SEND=deny
AI_NEVER_RECEIVES_MATRIX_OWNER_TOKEN=true- AI クライアントが受け取るのは Read API key か Agent API key だけです。
- Matrix の owner トークンは context-app だけが使います。API の応答にも MCP の応答にも含めません。メディアの取得では context-app が owner トークンで Synapse に問い合わせ、トークンは返しません。
- 管理画面のパスワードは AI に渡しません。
- LINE、WhatsApp の資格情報は、人が管理画面に直接入力します。モデルには渡しません。
- 読み取りのツールの結果には、保存したメッセージが指示ではなくデータであることを示す注意の文を付けます。メッセージの本文は外から来たデータとして扱います。
- MCP はローカル stdio で動かします。標準の構成では Remote MCP を公開しません。公開の URL や署名なしのメディア URL も発行しません。
鍵と秘密の置き場所#
値はここに書きません。置き場所と種類だけを示します。
| 秘密の種類 | 置き場所 | AI に渡すか |
|---|---|---|
| Matrix の owner アクセストークン | context-app だけが読む env ファイル | 渡さない |
Read API key(CONTEXT_READ_API_KEY) | ホストの .env。MCP 側は read プロファイル用の env | 渡す |
Agent API key(CONTEXT_AGENT_API_KEY) | ホストの .env。MCP 側は agent プロファイル用の env | 渡す |
管理画面のパスワード(ADMIN_PASSWORD)とセッションの秘密(SESSION_SECRET) | ホストの .env | 渡さない |
| DB のユーザーとパスワード | ホストの .env(Synapse 側は data/synapse/homeserver.yaml) | 渡さない |
| ブリッジの登録トークン | data/line-bridge/ と data/whatsapp-bridge/ の設定と登録のファイル、data/synapse/appservices/ | 渡さない |
Synapse の署名鍵と homeserver.yaml | data/synapse/ | 渡さない |
| LINE と WhatsApp のセッション | ブリッジの DB と data/line-bridge/、data/whatsapp-bridge/ | 渡さない |
| バックアップの暗号化のパスフレーズ | 環境変数 BACKUP_SECRETS_PASSPHRASE | 渡さない |
| Cloudflare Tunnel の認証情報(経路B) | cloudflared の認証情報のファイル(mode 600) | 渡さない |
やってはいけないブリッジの設定と登録のファイル、セッションのデータ、署名鍵、homeserver.yaml をリポジトリにコミットしないでください。
オプションなしの backup.sh は、ブリッジのセッションと秘密のファイルを含めません。Context の DB のダンプには、メッセージの本文が入ります。
送信の制御#
許可リスト
- 運用者が管理画面の「送信の許可」で、部屋ごとに
allow_sendをオンにします。新しい部屋は常にallow_send=falseで登録されます。 - 全部屋を一括でオンにする API はありません。MCP には
allow_sendを変えるツールがありません。 - 部屋に参加しても、送信は許可されません。読むための参加と、送信の許可は別の操作です。
- 許可しない部屋への送信には
403 NOT_ALLOWLISTEDを返し、Matrix を呼びません。エラーには、ほかの部屋の許可リストを含めません。
停止スイッチ
- 運用者が管理画面の「バックアップと更新」で「送信を止める」を押すと、すべての送信に
423 SEND_DISABLEDを返します。 .envの初期値はSEND_ENABLED=false(送信しない)です。- 緊急のときは
docker compose stop context-appで Context を止めます。 - LINE のセッションを止めるときは
docker compose stop line-bridgeを実行し、LINE アプリでセッションを取り消します。
認証の区分
| 認証 | できること |
|---|---|
| Read API key | 部屋、メッセージ、検索、メディアの取得 |
| Agent API key | read の操作と送信 |
| 管理画面のセッション(HttpOnly の cookie) | 許可リスト、停止スイッチ、監査ログ、テスト送信 |
- 管理画面のパスワードは1つで、ユーザー名はありません。セッションの期限は12時間です。
- cookie は HttpOnly、Secure、SameSite=Strict です。cookie で変更の操作をするときは、CSRF のトークンが要ります。
- 管理画面のログインは、同じ接続元から15分間に5回失敗すると
429 RATE_LIMITEDを返します。接続元の単位で数えるので、同じ NAT の出口を共有する人は同じ数にまとめられ、1人が複数の接続元を使うと別々に数えられます。 - 経路B では、管理画面のログインは同じホストの
https://127.0.0.1:18443から行います。平文の HTTP ではログインできません。 /healthと/readyは認証なしで応答します。
運用者の確認項目#
- 管理画面で、送信が必要な部屋だけ
allow_sendをオンにした(MCP からは変えられません) - 停止スイッチの場所と使い方を確認した
- AI クライアントには、平時は read プロファイルだけを設定した
.env、API キー、バックアップをチャットに貼っていない
脅威と対策#
| 脅威 | 起こりうること | いまの対策 | 運用で足すこと |
|---|---|---|---|
| AI の誤送信 | AI が無関係な相手に投稿する | 既定で拒否、部屋ごとの allow_send、停止スイッチ | 許可する部屋を最小にする |
| メッセージに埋め込まれた指示 | 受け取った本文が AI への指示のように読まれる | 読み取りの結果に、データであることを示す注意の文を付ける。送信は許可した部屋だけ | 平時は read プロファイルだけを使う |
| API キーの漏えい | 第三者が履歴を読む、許可した部屋に送信する | キーをチャットに出さない。read と agent のプロファイルを分ける | キーを入れ替える。端末とバックアップの扱いを決める |
| ホストへの侵入 | DB、media、トークンをすべて取られる | ホストの堅牢化は運用者が行う(SSH 鍵、更新、ファイアウォール) | 定期的に診断とバックアップを行い、不要なポートを閉じる |
| 管理画面のパスワードの総当たり | 送信の許可を勝手に変えられる | 接続元の単位のログインの試行制限 | 長いパスワードを使う |
| 連携デバイスの乗っ取り | LINE や WhatsApp に別の端末がつながる | 連携デバイスの管理は各アプリ側で行う | 不審な端末を切断する |
| 招待の取り違え | 送ってはいけない部屋に参加し、許可する | 参加と送信の許可を分ける。人名から room_id を推測しない | 最終メッセージの順で部屋を確かめてから許可する |
しないこと製品の方針として、全部屋への自動送信の許可はしません。標準の構成では Remote MCP を公開しません。
公開する面#
- 経路A(VPS で 80 と 443 を開ける)では、開けるのは TCP 22、80、443 だけです。5432、8008、29318、29322、3000、18080 は公開しません。
- 経路B(Cloudflare Tunnel)では、Caddy は 127.0.0.1 だけで待ち受け、外からは Tunnel を通してだけ届きます。
- Ubuntu の UFW は INPUT を制御します。Docker がコンテナのポートを公開すると、パケットは DOCKER や DOCKER-USER のチェーンを通り、UFW の一覧に出ないまま外から届くことがあります。Compose に
ports:を追加する前にレビューします。 - Caddy で
/_synapse/admin/*を外から 404 にし、Synapse の登録を無効にし、federation の whitelist を空にすることを推奨します。 - Context と Synapse の内部の通信は Compose の中の
http://synapse:8008で行い、外からの HTTP と HTTPS は Caddy だけが受けます。
クラウド版の公開の条件(準備中)#
クラウド版を準備中です。公開の前に、次の3つの条件を満たします。どれも作業中で、まだ満たしていません。
| 条件 | 内容 | 状態 |
|---|---|---|
| SSH のない固定のイメージ | VM には SSH で入れないようにし、決まったイメージだけを起動します。運用者が VM の中に入って操作する経路をなくします。 | 作業中 |
| イメージのハッシュの公開と検証 | 起動するイメージのハッシュを公開し、アテステーションで、そのイメージが動いていることを確かめられるようにします。 | 作業中 |
| 変えられない Secure Key Release のポリシー | 鍵を渡す条件(Secure Key Release のポリシー)を、あとから変えられない形で決めます。条件を満たした VM にだけ鍵を渡します。 | 作業中 |
この節について条件を満たすまで、クラウド版は公開しません。満たしたときに、検証の手順とあわせてこのページを更新します。
非公式のブリッジの限界#
非公式のブリッジですLINE と WhatsApp のブリッジは非公式です。LINE 公式の Messaging API ではなく、LINE ヤフー社との提携もありません。upstream の変更で止まることがあり、アカウントがログアウトされたり、利用を制限されたり、停止されたりするおそれがあります。動き続けることやログインの継続は約束しません。
matrix_acceptedは Matrix が送信を受け付けたことを示します。LINE に届いたことは示しません。matrix_acceptedなのに LINE に表示されないときは、ブリッジのセッションとログを確認します。- 固定している LINE のブリッジは、メディアのキャプションを受け付けません。長いキャプションを付けた画像は
matrix_acceptedのあとに捨てられることがあります。 - PC 版の LINE は必要ありません。スマートフォンの LINE のアプリとは同時に使えます。LINE の Chrome 拡張とは同時に使わないでください。Chrome 拡張でログインすると、ブリッジのセッションが無効になります。そのときは管理画面の「LINEの接続」でログインをやり直します。ログインを繰り返し試しません。
- LINE と WhatsApp は、2台で同時にログインすると片方の接続が切れやすくなります。
- LINE のブリッジには、メールアドレスとパスワードでのログインが必要です。
- WhatsApp の全履歴を完全には取り込みません。最初の取り込みは控えめで、新しいメッセージが中心です。
運用者が負うこと#
- ホスト、TLS、バックアップ、ブリッジの再ログインは運用者が管理します。
- 平時は read プロファイルだけを使うことを推奨します。
最終更新 2026年10月20日