AIエージェントに必要なのはマスターキーではなく、境界線である
MCPを介してAIエージェントにアプリへのアクセス権を与えることはリスクを伴います。それは、鍵束を渡し、特定のドアだけを開けてくれることを期待しているようなものです。その信頼こそがセキュリティリスクなのです。
マルチテナントのLaravelアプリ向けにMCPツールを構築する場合、解決しなければならない問題が一つあります。それは、他人のデータにアクセスさせることなく、いかにしてエージェントにアプリを操作させるか、という点です。
各MCPツールはエンドポイントとして機能します。エージェントがツールを呼び出すと、サーバーがコードを実行します。マルチテナント構成では、すべてのツールが次の2つの問いに答えられなければなりません。
- これを行う許可はありますか?
- ここで行う許可はありますか?
これらを怠ると、セキュリティホールを生み出すことになります。
Webリクエストはマルチテナンシーを処理するためにセッションを使用しますが、MCPツールはトークンを使用します。セッションも、現在のテナントコンテキストを設定するためのミドルウェアも存在しません。もしセッション内の「現在の組織(current org)」を探すグローバルスコープに依存しているなら、何も見つからないでしょう。制限されるべきクエリが、データベースの全行を返してしまう可能性があります。
私は安全を確保するために、次の4つのルールを使用しています。
- 明示的なフィルタリング:トークン認証下では、暗黙的なスコープ(ambient scope)に決して依存しないでください。毎回、組織ごとにフィルタリングを行う単一のTraitを使用してください。
- UUIDの使用:オートインクリメントIDは決して使用しないでください。エージェントが他のレコードを推測できないよう、推測不可能な識別子を使用してください。
- 権限の再利用:エージェント用に新しい権限セットを作成しないでください。Webアプリで使用しているものと同じability文字列を使用してください。
- 副作用の明示:アノテーションを使用して、ツールを読み取り専用(read-only)または書き込み可能(write-enabled)としてラベル付けしてください。
組織の検索に単一のTraitを使用することで、監査すべき場所を1箇所に集約できます。検索結果がnullを返した場合、ツールはエージェントに「レコードが見つかりません」と伝えます。エージェントは他のテナントに関する情報を一切得ることができません。
これはAIの問題ではありません。マルチテナンシーと認可(authorization)の問題です。MCPはアプリを公開することを容易にしますが、だからこそ境界線については規律を持って取り組まなければなりません。
エージェントは、自身のテナント内において、人間ができることと全く同じことだけを行い、それ以上のことは一切行ってはなりません。
オプションの学習コミュニティ: https://t.me/GyaanSetuAi
