RAG 的權限模型:多租戶與文件級授權
企業場景中,檢索錯一份文件就是資安事故。這是可稽核的權限設計。
面向企業的 RAG,權限不是功能而是底線。設計上要能通過一個簡單的測試:任何使用者,用任何提問方式,都不可能看到無權存取的內容。
要達到這個標準,權限必須實作在檢索層,且與應用層的授權來源一致。靠提示告訴模型「不要回答其他部門的問題」是完全無效的。
三種常見模型
- 租戶隔離:不同客戶的資料完全分開,最好用實體隔離(不同索引或不同集合)。
- 角色式(RBAC):文件標記可存取的角色,使用者持有角色清單。
- 屬性式(ABAC):依部門、職級、專案等屬性動態判斷,彈性最高但也最複雜。
索引時寫入 ACL
{
"text": "...",
"meta": {
"tenant_id": "acme",
"acl_roles": ["hr", "manager"],
"acl_users": [], // 個別授權,通常為空
"classification": "internal" // public | internal | confidential
}
}查詢時強制過濾
def build_filter(user):
return {
'tenant_id': user.tenant_id, # 租戶:絕對條件
'$or': [
{'acl_roles': {'$in': user.roles}},
{'acl_users': {'$in': [user.id]}},
{'classification': 'public'},
],
}
# 檢索函式不接受「不帶 filter」的呼叫
def search(q, user, **kw):
return index.query(q, filter=build_filter(user), **kw)把過濾封裝在檢索函式內部,讓它不可能被忘記。程式碼審查時,任何直接呼叫底層索引的地方都應該被擋下。
快取的隔離
快取是權限外洩的常見破口。快取鍵必須包含租戶與使用者的權限指紋,否則 A 的答案會被回給 B。
perm_fp = hashlib.sha256(
json.dumps({'t': user.tenant_id, 'r': sorted(user.roles)},
sort_keys=True).encode()).hexdigest()[:12]
cache_key = f'{perm_fp}:{query_hash}'可稽核性
- 記錄每次檢索的使用者、套用的 filter、回傳的 doc_id 清單。
- 記錄權限變更事件,與檢索日誌可對照。
- 定期跑自動化的權限測試:用各種角色的測試帳號查詢敏感文件,斷言結果為空。
權限變更的即時性
使用者離職或轉調後,權限必須立即生效。若你的系統把角色快取在 session 裡,就會有一段空窗期。敏感場景應該每次檢索都向授權來源確認,或把快取存活時間壓到極短。
引用與來源連結也要做權限檢查。答案本身過濾了,但引用中露出了文件標題與路徑,一樣是洩漏。
訂閱後繼續閱讀全文
本篇為訂閱者專屬內容。訂閱後可取得下列權限:
- 解鎖全部內容權限
- 閱讀不限篇數
- 全站移除廣告
月卡
NT$240
開通 30 天
一次付清,開通 30 天
季卡
NT$620
開通 90 天
一次付清,開通 90 天,每天約 NT$7
年卡
NT$2,160
開通 365 天
一次付清,開通 365 天,每天約 NT$6
一次性付款,付款成功後立即開通,到期自動結束,不會再次扣款,也不需要取消訂閱。
立即訂閱
金額均為新臺幣(TWD),即實際扣款金額,不另收手續費
支援信用卡 · Apple Pay · Google Pay · WebATM · ATM 轉帳
購買須知與退款政策