參數化檢視區塊總覽

本文說明 Spanner 中的參數化檢視表。參數化檢視表可讓您根據查詢傳遞的工作階段參數,動態篩選資料,特別適用於使用大型語言模型 (LLM) 的代理應用程式和系統。

參數化檢視表可直接將情境參數插入檢視表定義,藉此擴充資料庫檢視表的功能。參數化檢視表可協助您執行下列操作:

  • 將查詢時間情境參數 (例如使用者或租戶身分) 傳遞至檢視表定義。
  • 限制查詢結果,只顯示符合指定參數的資料列。
  • 防止使用者在生成或臨時 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 有效率地將篩選器邏輯推送至儲存層。

根據預設,除非資料庫角色具有 spanner_secure_context_reader 角色,否則直接在臨時查詢中查詢 SECURE_CONTEXT() 函式會失敗。這可防止無權限的使用者直接檢查參數值。

建議的做法是將參數化檢視表與定義者權限檢視表和精細存取控管 (FGAC) 結合。如要確保使用者只能透過檢視表查詢資料,請按照下列步驟操作:

  1. 啟用 FGAC,並為應用程式建立資料庫角色。
  2. GRANT檢視表的 SELECT 權限給角色。
  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 限制資料存取權。

  • 使用私人憑證進行篩選:使用查詢所需的值篩選資料,但不應將這些值傳回給使用者。

降低安全風險

當使用者在資料庫執行不受信任的查詢 (例如自然語言查詢) 時,參數化檢視表有助於降低安全風險。這些風險包括:

  • 惡意提示:使用者可能會嘗試操控基礎模型,存取所有應用程式資料。
  • 大範圍 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 中的參數化檢視不含安全屏障。雖然所有篩選器都會在傳回查詢結果前套用,但可能不會限制內部查詢處理期間存取的資料。

後續步驟