powered by TechFeed
表示モード
Deep Dive

LLMが生成するSQLは「正確」でも「安全」とは限らない — アクセス制御をプロンプトに頼ってはいけない理由

11月5日、InfoWorldが「Your LLM writes good SQL. That's not the same as safe SQL」と題した記事を公開した。LLMが生成するSQLの「正確さ」と「安全さ」は別問題であり、アクセス制御をモデルではなくコードで担保すべきだという実践的な知見を紹介している。製薬業界の実案件で発覚した「正しく動くが、見せてはいけないデータを返す」クエリの問題を起点に、設計上の落とし穴と対策を具体的に解説する内容だ。

11月5日、InfoWorldが「Your LLM writes good SQL. That's not the same as safe SQL」と題した記事を公開した。LLMが生成するSQLの「正確さ」と「安全さ」は別問題であり、アクセス制御をモデルではなくコードで担保すべきだという実践的な知見を紹介している。製薬業界の実案件で発覚した「正しく動くが、見せてはいけないデータを返す」クエリの問題を起点に、設計上の落とし穴と対策を具体的に解説する内容だ。


「正しいSQL」が「正しい答え」とは限らない

LLMによるText-to-SQL(自然言語からSQLを生成する技術)の評価は、多くの場合こうだ。質問を投げ、クエリが動いて結果が期待通りなら合格。しかしこのテストが見落とすのは「誰が聞いたか」という文脈だ。

記事の筆者は、製薬業界の営業・フィールドパフォーマンスデータを扱う分析ツールをSnowflake Cortex上で構築した経験を持つ。そのツールは確かに機能した。ユーザーが英語で質問すれば、数日かかっていた分析が数分で返ってくる。だが、あるユーザーが「自分の担当病院の四半期売上を見せて」と入力したとき、そのリージョン全病院のデータが返ってきた。SQLは文法的に正しく、クエリも動いた。問題は結果そのものだった。

これはマルチテナントのSaaSアプリ、HRシステム、財務ツールでも同様に起こりうる。


プロンプトはアクセス制御ではない

よくやりがちなのが、システムプロンプトに「自分のテリトリーのデータのみ表示すること」と書いて終わりにするアプローチだ。しかしプロンプトはあくまで「示唆」にすぎない。モデルはそれを無視したり、複雑な質問の中で忘れたり、誤読したりする。

筆者が推奨するのは、生成されたSQLをパースして実行前に書き換えるというアプローチだ。ルールをモデルが回避できないコードの層に置く。900件のテストクエリを使ったベンチマーク(元記事が参照する論文「Governed LLM-to-SQL for Pharma Commercial Data」の合成データによる検証)で確認された最も多い修正内容は以下の通りだ:

  • WHERE句への行フィルター追加: 285件
  • カラムマスキング: 240件
  • スコープ制限: 165件

「許可か拒否か」の二択では足りない

同じ900クエリのうち、40%はそのまま実行可能だった。だが残り60%には何らかの介入が必要だった:

  • 行フィルターが必要: 20%
  • カラムマスキングが必要: 15%
  • JOINの書き直しが必要: 11.7%
  • 人間のレビューに回した: 6.7%
  • 完全にブロック: 6.7%

大半のユーザーはそれでも有用な答えを得られた。ただし「より安全な形で」だ。単純なブロック・許可の二択ではなく、クエリを変形して安全な範囲で応答するという中間的な対応が、実用上は最も多く求められるケースだということが数字からも読み取れる。


実装上のチェックポイント

筆者が挙げる具体的な対策は次の通りだ:

  • モデルに渡す情報を絞る: クエリを生成する前に、質問者のロール・部署・担当テリトリー・アカウントを参照し、その人が使えるテーブルとカラムのみをモデルに提示する。機密フィールド(顧客ID、契約条件、給与など)はメタデータカタログでタグ付けし、最初から候補に出さない。
  • 実行前バリデーション: SELECT *、スコープをまたぐ取得、過大な結果セット、危険なJOINはクエリ実行前に弾く。
  • 権限の狭いDBアカウントをゲートウェイ経由で使う: プロンプトインジェクション(悪意ある入力でモデルを誘導する攻撃手法)や誤生成が起きても、DBレベルの権限が壁になる。

精度の数字が隠す「漏洩」問題

精度指標だけを見ていると見落とすのが、不正アクセスによるデータ漏洩数だ。検証では:

  • 素のText-to-SQL: 一部クエリで最大約80件の無権限行を返した
  • 静的なロールベースアクセス制御(RBAC): コンテキストを考慮できないため依然として漏洩が発生
  • ポリシー対応アプローチ: 漏洩ゼロ、かつ1クエリあたりの追加レイテンシは約6.5ミリ秒

ユーザーは気づかない。だがコンプライアンスチームが「誰が何を見たか」を問いに来たとき、ログがなければ数週間かかる調査が始まる。質問・ユーザーコンテキスト・適用ポリシー・最終SQL・結果のセットを記録しておくことが必要だ。LLMを使った分析基盤では、モデルの精度と同等かそれ以上に、監査可能性の設計が重要になる。


優先順位は「誰が使うか」を先に決めること

筆者の結論はシンプルだ。「モデルがどれだけ賢いか」を考える前に、「このユーザーは誰か」を先に決めること。アクセスルールを正しく設計してから、精度をチューニングする順番が正しい。モデルはSQL生成の精度を上げ続けるが、信頼できるシステムを作るのは、クエリの実行前後にある仕組みだ。

詳細はYour LLM writes good SQL. That's not the same as safe SQLを参照していただきたい。