範例 2:具有 OPA 和 Rego 的多租戶存取控制和使用者定義的 RBAC - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

範例 2:具有 OPA 和 Rego 的多租戶存取控制和使用者定義的 RBAC

此範例使用 OPA 和 Rego 來示範如何在 API 上實作存取控制,適用於具有租用戶使用者定義的自訂角色的多租用戶應用程式。它也示範如何根據租用戶限制存取。此模型顯示 OPA 如何根據高階角色提供的資訊,做出精細的許可決策。

具有 OPA 和 Rego 的使用者定義 RBAC

租用戶的角色存放在外部資料 (RBAC 資料) 中,用於為 OPA 做出存取決策:

{ "roles": { "tenant_a": { "all_access_role": ["viewData", "updateData"] }, "tenant_b": { "update_data_role": ["updateData"], "view_data_role": ["viewData"] } } }

當租用戶使用者定義時,這些角色應存放在外部資料來源或身分提供者 (IdP) 中,當將租用戶定義的角色映射到許可和租用戶本身時,該提供者可以做為事實來源。 

此範例使用 OPA 中的兩個政策進行授權決策,並檢查這些政策如何強制執行租用戶隔離。這些政策會使用先前定義的 RBAC 資料。

default allowViewData = false allowViewData = true { input.method == "GET" input.path = ["viewData", tenant_id] input.tenant_id == tenant_id role_permissions := data.roles[input.tenant_id][input.role][_] contains(role_permissions, "viewData") }

若要顯示此規則的運作方式,請考慮具有下列輸入的 OPA 查詢:

{ "tenant_id": "tenant_a", "role": "all_access_role", "path": ["viewData", "tenant_a"], "method": "GET" }

此 API 呼叫的授權決策會結合 RBAC 資料OPA 政策和 OPA 查詢輸入,如下所示:

  1. 的使用者對 Tenant A發出 API 呼叫/viewData/tenant_a

  2. 資料微服務會接收呼叫並查詢allowViewData規則,並傳遞 OPA 查詢輸入範例中顯示的輸入。

  3. OPA 使用 OPA 政策中的查詢規則來評估提供的輸入。OPA 也會使用來自 RBAC 資料的資料來評估輸入。OPA 會執行下列動作:

    1. 驗證用於進行 API 呼叫的 方法為 GET

    2. 驗證請求的路徑是否為 viewData

    3. 檢查路徑tenant_id中的 是否等於與使用者input.tenant_id相關聯的 。這可確保保持租戶隔離。另一個租用戶,即使具有相同的角色,也無法獲得進行此 API 呼叫的授權。

    4. 從角色的外部資料提取角色許可清單,並將其指派給變數 role_permissions。此清單是透過使用與 中的使用者相關聯的租戶定義角色來擷取 input.role.

    5. 檢查role_permissions是否包含 許可 viewData.

  4. OPA 會將下列決策傳回給 Data microservice:

{ "allowViewData": true }

此程序顯示 RBAC 和租戶意識如何有助於使用 OPA 做出授權決策。若要進一步說明這一點,請考慮/viewData/tenant_b使用下列查詢輸入對 進行 API 呼叫:

{ "tenant_id": "tenant_b", "role": "view_data_role", "path": ["viewData", "tenant_b"], "method": "GET" }

此規則會傳回與 OPA 查詢輸入相同的輸出,但適用於具有不同角色的不同租用戶。這是因為此呼叫適用於 ,/tenant_b且 RBAC 資料view_data_role中的 仍有與其相關聯的viewData許可。若要對 強制執行相同類型的存取控制/updateData,您可以使用類似的 OPA 規則:

default allowUpdateData = false allowUpdateData = true { input.method == "POST" input.path = ["updateData", tenant_id] input.tenant_id == tenant_id role_permissions := data.roles[input.tenant_id][input.role][_] contains(role_permissions, "updateData") }

此規則的功能與allowViewData規則相同,但會驗證不同的路徑和輸入方法。此規則仍然可確保租戶隔離,並檢查租戶定義的角色是否授予 API 發起人許可。若要查看如何強制執行,請針對對 的 API 呼叫檢查下列查詢輸入/updateData/tenant_b

{ "tenant_id": "tenant_b", "role": "view_data_role", "path": ["updateData", "tenant_b"], "method": "POST" }

當使用 allowUpdateData規則評估時,此查詢輸入會傳回下列授權決策:

{ "allowUpdateData": false }

此呼叫將不會獲得授權。雖然 API 呼叫者與正確的 相關聯,tenant_id並且使用核准的方法呼叫 API,但 input.role是租戶定義的 view_data_roleview_data_role 沒有 updateData 許可;因此,對 的呼叫/updateData未經授權。對於擁有 tenant_b的使用者,此呼叫會成功update_data_role