はじめに
社内規程、契約書、技術資料、顧客情報などを生成AIから検索できるRAGは、企業の情報活用を大きく変える可能性があります。
一方で、RAGに登録した文書を全社員が同じ条件で検索できる状態にすると、経理部門だけが閲覧できる資料や、特定プロジェクトの関係者に限定された情報が、生成AIの回答を通じて別の利用者へ表示されるおそれがあります。
企業向けRAGで重要なのは、文書を検索できるようにすることだけではありません。既存のファイルサーバーやクラウドストレージで設定されていた権限を、文書の分割、ベクトル化、検索、回答生成まで一貫して維持する必要があります。
RAGで文書のアクセス権限が失われる理由
元文書のACLがベクトルデータに引き継がれない
企業の文書管理システムでは、通常、文書ごとにACL(アクセス制御リスト)が設定されています。
ACLには、閲覧できるユーザーやグループ、編集できる担当者、アクセスを拒否する対象などが記録されています。ファイルサーバー、SharePoint、Google Driveなどでは、この情報に基づいて文書の表示を制御しています。
ところが、RAGへ文書を登録する際は、文書が複数のチャンクに分割され、数値化されたベクトルとして検索用データベースに格納されます。このとき、本文だけをベクトル化し、元文書のACLを保存しなければ、検索システムは「誰が読める文書なのか」を判断できません。
その結果、文書管理システムでは閲覧できなかった資料が、RAGの検索結果には含まれてしまうことがあります。
類似度検索は機密区分を判断しない
ベクトル検索は、利用者の質問と意味的に近い文章を探す仕組みです。検索精度には優れていますが、そのチャンクが公開情報なのか、機密情報なのかを自動的に判断するものではありません。
例えば、営業担当者が「来年度の人員計画を教えてください」と質問した場合、内容が近ければ、人事部門だけが閲覧できる採用計画や人件費資料が候補として取得される可能性があります。
RAGでは、検索の精度とアクセス権限を別々に考えず、検索対象を決める条件の中に認可処理を組み込む必要があります。
認証と認可をRAGの検索処理に統合する
認証は「誰か」、認可は「何を見られるか」
安全なRAGを設計するには、認証と認可を区別することが重要です。
認証は、利用者が誰であるかを確認する処理です。企業では、Microsoft Entra IDや社内のID管理基盤などと連携し、ユーザーID、メールアドレス、所属組織、グループ情報を取得します。
認可は、確認された利用者が、どの文書やチャンクを閲覧できるかを判断する処理です。
ログインできたからといって、RAG内のすべての情報を閲覧できるわけではありません。認証済みのユーザー情報と、各チャンクに保存された権限情報を照合して初めて、検索対象を決定できます。
JWTなどの認証情報をそのまま信用しない
RAGアプリケーションでは、ユーザーIDやグループ情報をJWTなどのトークンから取得する構成が一般的です。
ただし、トークン内の文字列を読み取るだけでは不十分です。発行元、対象アプリケーション、有効期限、署名などを検証し、正規のID基盤から発行された情報であることを確認する必要があります。
検索フィルタへ渡すユーザー属性は、利用者が画面上で自由に入力した値ではなく、検証済みの認証情報から生成しなければなりません。
チャンク単位アクセス制御の基本設計
親文書のACLをすべてのチャンクへ継承する
RAGでは、一つの文書から複数のチャンクが生成されます。チャンク単位で安全な検索を行うには、元文書のACLをすべてのチャンクへ継承させます。
各チャンクには、本文やベクトルだけでなく、次のようなメタデータを保持します。
- 元文書のID
- チャンクID
- 閲覧を許可するユーザーID
- 閲覧を許可するグループID
- 明示的に拒否する対象
- 組織や部署
- 機密区分
- テナントID
- 文書の更新日時
- 権限情報の更新日時
これにより、検索時に利用者のIDや所属グループと照合し、閲覧可能なチャンクだけを検索対象にできます。
文書構造に合わせてチャンクを分割する
チャンクの分割方法も権限管理に影響します。
一定の文字数で機械的に分割する固定長方式は実装しやすい一方、章や条項の境界をまたいでしまう可能性があります。契約書や規程では、見出しや条項単位で分割した方が、出典と権限の対応を追跡しやすくなります。
ページ単位で閲覧権限が異なる文書では、ページ単位のチャンクも有効です。
特に注意したいのが、チャンクへ文書全体の要約を付与する処理です。検索精度を高める目的で機密文書全体の要約を各チャンクへ追加すると、本来は閲覧範囲が限定された情報が別のチャンクを通じて漏れる可能性があります。
要約や前後文脈を付与する場合も、元情報の機密区分とアクセス権限を引き継ぐ設計が必要です。
安全なRAGを構成するデータ処理パイプライン
文書権限を維持するには、一つの検索フィルタだけでなく、データの取り込みから回答表示までを通した設計が必要です。
データソースから文書と権限を同時に取得する
コネクタは、文書本文だけでなく、データソースに設定されているACL、所有者、共有グループ、機密ラベルなども取得します。
本文と権限情報を別々に管理すると、同期漏れが起きやすくなります。取得時点から同じ文書IDで結び付け、権限情報を追跡できるようにします。
チャンク生成時に権限情報を複製する
文書を分割する際は、生成されたすべてのチャンクへ親文書の権限をコピーします。
一部のチャンクだけACLが欠落した場合、そのチャンクを公開情報として扱ってはいけません。権限情報が取得できないデータはインデックスへ登録しないなど、「判断できない場合は拒否する」方針が安全です。
ベクトルデータベースへ権限メタデータを保存する
ベクトル、本文、文書ID、ACLを一つの検索単位として保存します。検索時は、質問との類似度だけでなく、ユーザーIDやグループIDに基づくメタデータ条件を同時に適用します。
リランク前にも未認可データを除外する
検索候補を並べ替えるリランカーへ、未認可のチャンクを渡さない設計も重要です。
最終回答に表示されなかったとしても、未認可データが中間処理、ログ、キャッシュ、外部APIへ渡れば、別の漏えい経路になる可能性があります。
回答生成前と表示前に再確認する
LLMへ渡すコンテキストは、認可済みチャンクだけで構成します。さらに、回答を利用者へ表示する直前にも、参照文書、個人情報、機密表現などを検査します。
アクセス制御と出力検査は役割が異なります。ACLフィルタを実装したからといって、個人情報のマスキングや回答の根拠確認が不要になるわけではありません。
プレフィルタとポストフィルタの違い
プレフィルタは検索前に対象を限定する
プレフィルタは、ベクトル検索を実行する前に、利用者が閲覧できるチャンクだけへ検索範囲を絞る方式です。
未認可チャンクが類似度計算、リランク、キャッシュ、ログへ渡りにくいため、企業向けRAGでは基本となる方式です。検索対象そのものが小さくなるため、条件によっては処理負荷の抑制にもつながります。
MicrosoftはAzure AI Searchでユーザーやグループ情報を使って検索結果を限定するセキュリティフィルターを案内しており、AWSもAmazon Bedrock Knowledge Basesで検索結果を返す前にメタデータ条件を適用する仕組みを提供しています。Azure AI Searchの文書レベルアクセス制御、Amazon BedrockのRetrievalFilter
ポストフィルタにはゼロ結果の問題がある
ポストフィルタは、類似度検索で候補を取得した後に、権限のないチャンクを除外する方式です。
実装しやすい場合がありますが、上位候補の大半が未認可文書だった場合、許可された有用な文書がデータベース内に存在していても、最終的な検索結果がゼロ件になる可能性があります。これが「ゼロ結果トラップ」です。
また、認可前の候補がアプリケーションのメモリや中間ログへ残らないよう注意しなければなりません。
現実的にはプレフィルタを基本とし、権限変更の反映遅延に備えて、LLMへ渡す直前にもう一度認可を確認する多層構成が有効です。
RBAC・ABAC・ReBACの使い分け
RBACは役割を基準に制御する
RBACは、管理職、人事担当者、営業担当者などの役割に基づいてアクセスを制御します。
組織構造が比較的単純な場合には運用しやすい一方、部署横断プロジェクトや一時的な共有関係が増えると、ロールの数が増えやすくなります。
ABACはユーザーと文書の属性を照合する
ABACは、所属部署、勤務地、雇用区分、機密レベルなどの属性を組み合わせて判断します。
例えば、「所属が法務部であり、機密レベル3まで閲覧可能」といった条件を表現できます。ただし、属性の更新元と責任者を明確にしなければ、古い所属情報によって誤った認可が行われる可能性があります。
ReBACは人・組織・文書の関係を評価する
ReBACは、「このユーザーはプロジェクトのメンバーである」「この文書は特定フォルダに属している」といった関係性に基づいて判断します。
複雑な共有関係を扱いやすい一方で、認可エンジンとの通信回数や検索対象数を考慮した設計が必要です。OpenFGAでは、ユーザーが閲覧できるオブジェクトを取得するListObjectsなど、権限付き検索のための方法が示されています。OpenFGAのRelationship Queries
権限変更をRAGへ同期する方法
RAGの権限管理では、初回登録だけでなく、異動、退職、共有解除、フォルダ移動などの変更を反映し続ける必要があります。
有効な同期方法として、次の組み合わせが考えられます。
- Webhookや変更イベントによる差分更新
- 権限キャッシュへの短い有効期限の設定
- 定期的な全件照合
- 同期失敗時の自動再実行
- 削除・共有解除を優先する処理
- 権限情報の更新日時を使った不整合検知
イベント通知だけに依存すると、通知の消失や処理失敗を見逃す可能性があります。リアルタイムの差分更新と、定期的な全件照合を組み合わせることが重要です。
退職者や共有解除済みの利用者によるアクセスを防ぐため、トークンや権限キャッシュの有効期限も必要以上に長くしないようにします。
RAGのアクセス制御で実施すべきテスト
本番稼働前には、検索精度だけでなく、権限境界を越えられないことを確認します。
- 権限のない文書名を指定して質問する
- 文書内の固有語や数値を使って検索する
- 別部署のユーザーで同じ質問を実行する
- グループから外した直後に再検索する
- 文書を別フォルダへ移動して権限継承を確認する
- ACLが欠落したチャンクが検索対象にならないか確認する
- リランクやプロンプト組み立てのログを調査する
- 検索結果がゼロ件になった場合の挙動を確認する
- 管理者権限を一般ユーザーへ誤って適用できないか確認する
- 回答の引用元が利用者の閲覧可能範囲にあるか確認する
監査ログには、利用者、質問、適用した権限条件、取得した文書ID、除外した件数、回答に使用したチャンクを記録します。ただし、ログ自体に機密本文を保存しすぎないことも重要です。

まとめ
企業向けRAGの情報漏えい対策は、プロンプトへの注意書きだけでは実現できません。
元文書のACLを取得し、すべてのチャンクへ継承し、検証済みのユーザー情報に基づいて検索前にフィルタリングする必要があります。さらに、権限変更の同期、生成直前の再認可、回答の検査、監査ログまでを一つの仕組みとして設計することが求められます。
RAGの価値は、多くの文書を検索できることだけではありません。「その利用者が本来閲覧できる情報だけを、必要な範囲で正確に提示できること」が、企業で継続的に利用するための前提条件です。
コメント