パラメータ化されたビューの概要

このドキュメントでは、Spanner のパラメータ化されたビューについて説明します。パラメータ化されたビューを使用すると、クエリで渡されたセッション パラメータに基づいてデータを動的にフィルタできます。これは、大規模言語モデル(LLM)を使用するエージェント アプリケーションやシステムで特に役立ちます。

パラメータ化されたビューは、コンテキスト パラメータをビュー定義に直接挿入することで、データベース ビューの機能を拡張します。パラメータ化されたビューは、次のことに役立ちます。

  • ユーザー ID やテナント ID などのクエリ時のコンテキスト パラメータをビュー定義に渡します。
  • 指定されたパラメータに一致する行のみにクエリ結果を制限します。
  • 生成された SQL クエリまたはアドホック SQL クエリで、ユーザーがアプリケーション レベルのデータフィルタをバイパスできないようにします。

詳細については、パラメータ化されたビューを作成するをご覧ください。

パラメータ化されたビューの仕組み

パラメータ化されたビューは、パラメータを使用して、ユーザー ID などのアプリケーション レベルのコンテキストをデータベースに安全に渡します。アプリケーションがクエリを実行すると、クエリ ステートメントとともにコンテキストが送信されます。Spanner は実行中にこのコンテキストにアクセスしますが、クエリやアプリケーション ユーザーはコンテキストを読み取ることも変更することもできません。

SECURE_CONTEXT() 関数は、ビュー定義内でこれらのセキュア パラメータにアクセスするための SQL インターフェースを提供します。パラメータ化されたビューには、定義者の権限ビューのセキュリティ モデルが必要です。このモデルでは、ビューが SECURE_CONTEXT() を使用して値にアクセスし、結果をフィルタします。

たとえば、クエリを実行するユーザーの ID に基づいてデータをフィルタするには、ビューの WHERE 句に次の内容を含めます。

CREATE VIEW MyUserData
SQL SECURITY DEFINER AS
(SELECT *
FROM AllUserData
WHERE UserID = CAST(SECURE_CONTEXT('user_id'), INT));

これにより、アプリケーションはユーザーのデータのみを表示できます。また、モデレーターが任意のユーザーの機密性の低いデータを表示できるようにするビューを作成することもできます。

CREATE VIEW SafeUserData
SQL SECURITY DEFINER AS
(SELECT UserID, AccountCreationTime, PublicProfileText
FROM AllUserData
WHERE SECURE_CONTEXT('role') = 'Moderator');

SECURE_CONTEXT() はビュークエリ定義のどこでも使用できますが、パフォーマンスを最適化するには、WHERE 句で使用して、テーブルまたはインデックスの先頭のキー列をフィルタリングすることをおすすめします。これにより、Spanner はフィルタ ロジックをストレージ レイヤに効率的に push できます。

デフォルトでは、データベース ロールに spanner_secure_context_reader ロールがない限り、アドホック クエリで SECURE_CONTEXT() 関数を直接クエリすると失敗します。これにより、権限のないユーザーがパラメータ値を直接検査できなくなります。

推奨されるパターンは、パラメータ化されたビューを定義者の権限ビューときめ細かいアクセス制御(FGAC)と組み合わせることです。ユーザーがビューを介してのみデータをクエリできるようにするには、次の操作を行います。

  1. FGAC を有効にして、アプリケーションのデータベース ロールを作成します。
  2. ビューに対する SELECT 権限をロールに GRANT します。
  3. public システムロールに、ベーステーブルまたはビューに対する権限が付与されていないことを確認します。

次に例を示します。

-- Create a role for the application user
CREATE ROLE pv_user;

-- Grant SELECT permission on the view to the role
GRANT SELECT ON VIEW MyUserData TO ROLE pv_user;

パラメータ化されたビューを作成した後の一般的なリクエストのプロセスは次のとおりです。

  1. アプリケーションは、クエリ リクエストにセキュア コンテキストを設定します。コンテキストには、ユーザー ID やロールなど、アプリケーション ユーザーを識別する情報が含まれます。
  2. アプリケーションが定義者の権限ビューに対してクエリを実行する。
  3. このビューでは、WHERE 句で SECURE_CONTEXT() 関数を使用して、セキュア コンテキストで指定された値に基づいて行をフィルタリングします。
  4. Spanner は、フィルタに一致する行のみを返します。これにより、クエリ結果がユーザーのセッション コンテキストに関連付けられたデータに効果的にフィルタリングされます。

たとえば、アプリケーションは、Spanner クライアント ライブラリのいずれかを使用して、安全なコンテキストで現在のユーザーの ID を渡すことができます。次の例では、C++ クライアント ライブラリを使用して user_id セキュア パラメータを設定しています。

(*request.mutable_secure_context())["user_id"] = "ca6095c4-1a68-44a8-9562-dd9e897326f0";

アプリケーションは、ビューに対して標準 SQL クエリを実行します。ビューは、WHERE 句でこの user_id を使用して、そのユーザーに属するレコードのみを返します。

--Query executed by the application
SELECT * FROM MyUserData;

パラメータ化されたビューのメリット

パラメータは、次の目標を達成するのに役立ちます。

  • マルチテナント アプリケーションでテナントデータを分離する: パラメータを使用して、クエリが特定のテナントのデータのみを返すようにします。

  • エージェント型 AI クエリを制限する: 自然言語クエリをユーザーまたはテナントのデータに制限します。

  • エフェメラル認証情報を使用してデータをフィルタする: Identity and Access Management(IAM)に存在しないユーザー ID またはテナント ID に基づいてデータアクセスを制限します。

  • フィルタリングにプライベート認証情報を使用する: エンドユーザーに返すべきではないクエリに必要な値を使用してデータをフィルタします。

セキュリティ リスク軽減

パラメータ化されたビューは、エンドユーザーがデータベースで信頼できないクエリ(自然言語クエリなど)を実行した場合のセキュリティ リスクの軽減に役立ちます。たとえば次のようなリスクがあります。

  • 悪意のあるプロンプト: 基盤となるモデルをユーザーが操作して、すべてのアプリケーション データにアクセスしようとする可能性があります。
  • 対象範囲の広い SQL クエリ: 大規模言語モデル(LLM)は、ユーザーに悪意がなくても、センシティブ データの漏洩につながる SQL クエリを生成してしまうことがあります。

パラメータ化されたビューを使用すると、ユーザーがクエリのフレーズに関係なく、個々のアプリケーション ユーザーに返される行の範囲を制限できます。

ベスト プラクティス

パラメータ化されたビューを効果的に実装するには、次の方法に沿って操作します。

  • 定義者の権限ビューと FGAC を組み合わせる: 定義者の権限ビューときめ細かいアクセス制御ロールを含む包括的なセキュリティ モデルの一部としてパラメータを使用します。ロール SELECT にはビューに対する権限のみを付与し、ロールと public システムロールには基になるベーステーブルに対する権限がないことを確認します。

  • 複雑なコンテキストには JSON を使用する: 複数のロールを持つユーザーなど、構造化されたコンテキストを渡すには、データを JSON 文字列としてシリアル化します。JSON 文字列を単一のパラメータとして渡します。Spanner の組み込み JSON または JSONB を使用して、ビュー内の値を抽出します。

  • SQL UDF でアクセスを簡素化する: 構造化された JSON コンテキスト内のフィールドに頻繁にアクセスする場合は、ユーザー定義の SQL 関数(UDF)を作成して、抽出ロジックをカプセル化します。ビューで UDF を使用すると、読みやすさとメンテナンス性が向上します。

  • Model Armor でプロンプト インジェクションから保護する: 信頼できないユーザー入力を含む LLM を使用してクエリを生成する場合は、Model Armor を使用して、プロンプト インジェクションやジェイルブレイクの試みを事前に特定してブロックします。

制限事項

パラメータ化されたビューには次の制限があります。

  • 引数の型: SECURE_CONTEXT() 関数には、文字列リテラル引数が必要です。
  • 結果の型: SECURE_CONTEXT() 関数は文字列を返します。
  • Spanner 機能の相互作用: 生成された列、デフォルトの列値式、またはユーザー定義関数(UDF)内で SECURE_CONTEXT() を使用することはできません。
  • セキュリティ バリア: Spanner のパラメータ化されたビューには、セキュリティ バリアは含まれません。すべてのフィルタはクエリ結果を返す前に適用されますが、内部クエリ処理中にアクセスされるデータが制限されない場合があります。

次のステップ