【要約】LangChain の @tool デコレータ、権限チェック引数を無言で消していた話 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
LangGraphでReAct Agentを構築する開発者が、権限情報の注入を試みた際に、重大なバグに直面した。
- ・
@toolが生成するinvoke()は、内部でPydeticのバリデーションを行う。 - ・LLMによる改ざんを防ぐため、権限情報をスキーマ外に定義していた。
- ・Pydanticがスキーマ外の引数を自動除去したため、権限チェックが機能しなくなった。
// Approach
開発者は、Pydanticのバリデーションを回避し、権限情報を確実に渡す手法を採用した。
- ・
StructuredToolが持つ元の関数(.func)を直接呼び出す方式に変更した。 - ・
inspect.signatureを用い、関数が受け付ける引数のみを抽出する処理を追加した。 - ・これにより、LLMの引数とサーバーの権限情報を、型エラーなく統合した。
// Result
修正により、権限チェックが正しく機能し、テストでのセキュリティ要件充足を確認した。
- ・
test_member_cannot_access_unauthorized_projectがパスした。 - ・
matched.invoke()からmatched.func()への変更で、認可の確実性が向上した。 - ・サーバー側のコンテキストに基づいた、厳格なアクセス制御を実現した。
Senior Engineer Insight
> LangChainの抽象化は便利だが、内部のPydantic挙動がセキュリティに直結する。特に「スキーマ外の引数を黙って捨てる」挙動は、認可ロジックにおいて致命的だ。本件のように、LLMに触らせたくない制御用引数を注入する場合、
.invoke()を盲信せず、低レイヤーの.funcへのアクセスを検討すべきである。設計段階で、LLMの制御範囲とサーバーの制御範囲を明確に分離する規律が求められる。