記錄訪問
在物件許可權允許之後,控制使用者能看到或修改哪些記錄 —— 共享模型預設值、租戶隔離、共享規則、記錄共享。
記錄訪問控制的是:在物件許可權允許某項操作之後,使用者能看到或修改哪些行。
機制
| 機制 | 用途 |
|---|---|
| 行級安全 | 強制執行租戶或組織隔離 |
| 共享規則 | 基於宣告式條件授予訪問 |
| 記錄共享 | 向特定使用者、團隊、崗位、業務單元,或某個單元及其下級授予訪問 |
| 所有權 / 層級 | 通過負責人和業務單元樹授予訪問 |
共享模型預設值
每個物件都會宣告(或繼承)一個 sharingModel,它設定組織範圍的預設值:
private、public_read、public_read_write 或 controlled_by_parent。
從 ObjectStack 13 起,帶有負責人欄位且沒有宣告 sharingModel 的自定義物件預設
為私有 —— 記錄只對其負責人(以及管理員)可見,直到某條共享規則、記錄共享或
更寬的預設值把它們開放出來。顯式宣告模型即可恢復開放的行為:
ObjectSchema.create({
name: 'crm_lead',
sharingModel: 'public_read_write',
fields: {
company: Field.text({ label: 'Company' }),
// …
},
});13 之前的別名 read、read_write 和 full 已被移除;os compile 會通過
security-owd-unset 和 security-owd-alias lint 標出未設定或使用別名的模型。
預設的租戶隔離
安全外掛通過當前使用者的上下文強制執行租戶隔離。對於標準的平臺物件,預設規則會 保護那些不帶常規組織欄位的全域性表。
客戶在實踐中的預期是:
Users only see records that belong to their organization or records
explicitly shared with them.共享規則
用共享規則表達可重複的業務策略:
- 所有區域經理都可以讀取其所在區域的客戶;
- 支援經理可以看到已升級的案例;
- 財務可以讀取已批准的發票;
- 審計人員可以讀取標記為待審計的記錄。
一條規則是基於欄位值的 CEL condition,在編寫時編譯成行過濾條件;匹配的記錄會
為解析出的接收方(某個使用者、團隊、崗位、業務單元,或某個單元及其下級)生成
sys_record_share 授權。criteria 規則是唯一可編寫的形式。
兩個開關都失敗即關閉
兩件讀者理所當然會假定、卻直到 ObjectStack 17.0 才成立的事:
- 沒有條件的共享規則什麼都不共享。 過去,一條儲存時沒有條件謂詞的規則會被 求值為該物件的每一條記錄 —— 即空過濾條件 —— 所以經由某個未校驗的寫入路徑 產生的一個拼寫錯誤,就會悄悄地開放整張表。現在,寫入一個匹配全部的條件會被 拒絕,求值器也會把空條件視為什麼都不匹配。
enabled: false的 RLS 策略就是停用的。 過去,被關閉的策略仍會繼續貢獻 它的 OR 分支授權,所以關閉一條策略並不會收回訪問。現在,被停用的策略根本不會 被求值。
如果你在更早的版本下審計過訪問,並得出"這條規則什麼也沒授予"或"這條策略是關閉 的"的結論,值得重新執行一遍 解釋引擎 —— 實際的範圍可能比 後設資料所說的更寬。
行級安全拒絕它無法強制執行的內容
從 ObjectStack 17.5 起,RLS 策略要麼精確地收窄它所宣告的範圍,要麼拒絕:
- 沒有
check的策略用它的using門控寫入。 文件一直說check預設為using,但只有聲明瞭check的策略才會被應用到寫入上,所以使用者可能寫入一行 自己讀不回來的資料。現在,單行插入或按 id 更新的結果如果落在所有適用的寫入 策略的using之外,會返回403 PERMISSION_DENIED。如果一條策略本意就是讓 寫入可以落在其讀取範圍之外,就必須宣告一個允許這些寫入的check。 - 它無法強制執行的謂詞會拒絕。 把欄位與列表比較
(
record.status != ['closed', 'archived'])、與裸的current_user而不是current_user.id比較,或者指定了物件未宣告的欄位,都可能放進它本來要拒絕的 行和寫入。這樣的策略現在會失敗即關閉:它的讀取不返回任何行,寫入返回403。 - 寫入按儲存後的行來判定。
check和組織隔離牆看到的,是引擎在beforeInsert/beforeUpdate鉤子執行之後所儲存的行。
os validate 會在這些形態釋出之前報告它們(rls-predicate-unenforceable、
rls-predicate-unknown-field),後設資料儲存入口也會拒絕攜帶這類策略的許可權集
(422 INVALID_METADATA)。
記錄共享
用記錄共享處理例外情況:
- 把某個商機共享給一位專家;
- 在升級處理期間授予臨時訪問;
- 讓外部整合訪問某條特定記錄。
可見性故障排查
當用戶看不到某條記錄時,按以下順序檢查:
- 使用者是否已認證,且處於預期的組織中?
- 使用者是否擁有物件的
read許可權? - 物件的
sharingModel是什麼(從 ObjectStack 13 起,自定義物件預設為private)? - 行級安全是否允許這條記錄?
- 是否有本應適用的共享規則?
- 是否有直接的記錄共享?
- 記錄是否由預期業務單元子樹中的某個使用者擁有?
- 使用者訪問的專案 / 主機名是否正確?
解釋引擎一次呼叫就能回答所有這些 問題 —— 它會報告每一層的判定,以及是哪項授權(或缺少的授權)決定了結果。