

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

# 設計授權模型的最佳實務
<a name="design-authz-strategy"></a>

當您準備在軟體應用程式中使用 Amazon Verified Permissions 服務時，第一步是立即跳到撰寫政策陳述式可能很困難。這類似於在完全決定應用程式應執行的操作之前，先撰寫 SQL 陳述式或 API 規格，開始開發應用程式的其他部分。反之，您應該從使用者體驗開始。然後，從該體驗向後工作，以達成實作方法。

當您執行這項工作時，您會發現自己會提出問題，例如：
+ 我的資源是什麼？ 如何組織它們？ 例如，檔案是否位於資料夾中？
+ 資源的組織是否在許可模型中扮演某種角色？
+ 主體可以對每個資源執行哪些動作？
+ 委託人如何取得這些許可？ 
+ 您希望最終使用者從預先定義的許可中進行選擇，例如「Admin」、「Operator」或「ReadOnly」，還是他們應該建立臨機操作政策陳述式？ 還是兩者同時？
+ 角色是全域或範圍？ 例如，單一租用戶中的「運算子」是否受限，或者「運算子」是否表示整個應用程式的運算子？
+ 轉譯使用者體驗需要哪些類型的查詢？ 例如，是否需要列出委託人可以存取的所有資源，以轉譯該使用者的首頁？ 
+ 使用者可以不小心將自己鎖定在自己的資源之外嗎？ 是否需要避免？

此練習的最終結果稱為**授權模型**；它定義了委託人、資源、動作，以及它們如何相互關聯。產生此模型不需要 Cedar 或 Verified Permissions 服務的獨特知識。相反地，它首先是使用者體驗設計練習，就像任何其他練習一樣，並且可以呈現在成品中，例如界面模型、邏輯圖，以及許可如何影響使用者可以在產品中做什麼的整體描述。Cedar 的設計具有足夠的靈活性，可滿足模型中的客戶，而不是強制模型不自然地彎曲以符合 Cedar 的實作。因此，清楚了解所需的使用者體驗是實現最佳模型的最佳方式。

為了協助回答問題並獲得最佳模型，請執行下列動作：
+ 在 [Cedar 政策語言參考指南中檢閱 Cedar 設計模式](https://docs.cedarpolicy.com/overview/patterns.html)。
+ 請考慮 Cedar 政策語言參考指南中的[最佳實務](https://docs.cedarpolicy.com/bestpractices/bp-naming-conventions.html)。
+ 請考慮此頁面中包含的最佳實務。

**Topics**
+ [沒有正式的「正確」模型](#design-no-canonical-correct-model)
+ [傳回 403 禁止錯誤，而不是 404 找不到錯誤](#resource-existence-errors)
+ [專注於 API 操作以外的資源](#design-focus-on-data-beyond-apis)
+ [多租戶考量事項](#design-multi-tenancy-considerations)

## 沒有正式的「正確」模型
<a name="design-no-canonical-correct-model"></a>

當您設計授權模型時，沒有單一且唯一正確的答案。不同的應用程式可以有效地針對類似的概念使用不同的授權模型，這沒問題。例如，請考慮電腦檔案系統的表示法。當您在類似 Unix 的作業系統中建立檔案時，它不會自動繼承父資料夾的許可。相反地，在許多其他作業系統和大多數線上檔案共用服務中，檔案確實繼承了其父資料夾的許可。根據應用程式最佳化的情況，這兩個選項都是有效的。

授權解決方案的正確性並非絕對，但應該根據它如何提供客戶所需的體驗，以及它是否以預期的方式保護其資源。如果您的授權模型交付此項目，則表示成功。

因此，以所需的使用者體驗開始設計是建立有效授權模型最有幫助的先決條件。

## 傳回 403 禁止錯誤，而不是 404 找不到錯誤
<a name="resource-existence-errors"></a>

最好將 *403 禁止*的錯誤傳回給包含 實體的請求，特別是 資源，該請求未對應至任何政策，而不是 *404 找不到*錯誤。這可提供最高層級的安全性，因為您不會公開實體是否存在，只是請求不符合政策存放區中任何政策的政策條件。

## 專注於 API 操作以外的資源
<a name="design-focus-on-data-beyond-apis"></a>

在大多數應用程式中，許可是根據支援的資源建立模型。例如，檔案共用應用程式可能將許可表示為可在檔案或資料夾上執行的動作。這是一個很好、簡單的模型，可抽象化基礎實作和後端 API 操作。

相反地，其他類型的應用程式，特別是 Web 服務，經常設計 API 操作本身的許可。例如，如果 Web 服務提供名為 的 API`createThing()`，授權模型可能會定義對應的許可，或在名為 的 Cedar `action`中定義 `createThing`。這可在許多情況下運作，並讓您輕鬆了解許可。若要叫用 `createThing`操作，您需要 `createThing`動作許可。看起來很簡單，對嗎？

您會發現 Verified Permissions 主控台中的[入門](getting-started-first-policy-store.md)程序包含直接從 API 建置資源和動作的選項。這是有用的基準：您的政策存放區與其授權的 API 之間的直接映射。

不過，當您進一步開發模型時，這種以 API 為中心的方法可能不適合具有非常精細的授權模型的應用程式，因為 APIs 只是您客戶真正嘗試保護的代理：基礎資料和資源。如果多個 APIs控制對相同資源的存取，管理員可能很難推斷這些資源的路徑，並相應地管理存取。

例如，請考慮包含組織成員的使用者目錄。使用者可以組織成群組，而其中一個安全目標是禁止未經授權方探索群組成員資格。管理此使用者目錄的服務提供兩種 API 操作：
+ `listMembersOfGroup`
+ `listGroupMembershipsForUser`

客戶可以使用其中一個操作來探索群組成員資格。因此，許可管理員必須記住協調對*這兩個*操作的存取。如果您稍後選擇新增 API 操作來處理其他使用案例，這會更複雜，如下所示。
+ `isUserInGroups` *（新的 API，可快速測試使用者是否屬於一或多個群組）*

從安全角度來看，此 API 開啟第三個路徑來探索群組成員資格，中斷管理員精心打造的許可。

我們建議您專注於基礎資料和資源及其關聯操作。將此方法套用到群組成員資格範例將導致抽象許可，例如 `viewGroupMembership`，這三個 API 操作都必須參考。


| API 名稱 | 許可 | 
| --- | --- | 
| listMembersOfGroup | 需要 群組的viewGroupMembership許可 | 
| listGroupMembershipsForUser | 需要 使用者的viewGroupMembership許可 | 
| isUserInGroups | 需要 使用者的viewGroupMembership許可 | 

透過定義此許可，管理員可以成功控制目前和永久探索群組成員資格的存取權。做為權衡，每個 API 操作現在都必須記錄可能需要的數個許可，而且管理員在製作許可時必須參考此文件。為了滿足您的安全需求，這可以是有效的權衡。

## 多租戶考量事項
<a name="design-multi-tenancy-considerations"></a>

您可能想要開發供多個客戶使用的應用程式 - 取用您應用程式的企業或*租戶* - 並將其與 Amazon Verified Permissions 整合。在您開發授權模型之前，請開發多租戶策略。您可以在*一個共用政策存放區中管理客戶的政策*，或為每個*租用戶政策存放區指派一個政策*。如需詳細資訊，請參閱 *AWS 方案指引*中的 [Amazon Verified Permissions 多租戶設計考量](https://docs.aws.amazon.com/prescriptive-guidance/latest/saas-multitenant-api-access-authorization/avp-design-considerations.html)事項。

1. 

**一個共用政策存放區**  
 所有租戶共用單一政策存放區。應用程式會將所有授權請求傳送至共用政策存放區。

1. 

**每個租戶政策存放區**  
 每個租戶都有一個專用政策存放區。應用程式會根據提出請求的租用戶，查詢不同的政策存放區以取得授權決策。

這兩種策略都會對您的 AWS 帳單產生很大的影響。那麼，您應該如何設計您的方法？ 以下是可能導致 Verified Permissions 多租用授權策略的常見條件。

**租用戶政策隔離**  
將每個租用戶的政策與其他租用戶隔離對於保護租用戶資料至關重要。當每個租用戶都有自己的政策存放區時，每個租用戶都有自己的隔離政策集。

**授權流程**  
您可以使用每個租用戶的政策存放區，識別在請求中使用政策存放區 ID 提出授權請求的租用戶。使用共用政策存放區時，所有請求都會使用相同的政策存放區 ID。

**範本和結構描述管理**  
當您的應用程式有多個政策存放區時，您的[政策範本](policy-templates.md)和[政策存放區結構描述](schema.md)會在每個政策存放區中新增設計和維護開銷層級。

**全球政策管理**  
您可能想要將一些*全域*政策套用至每個租用戶。全域政策管理的額外負荷層級因共用和每個租用戶的政策存放區模型而異。

**租戶離職**  
有些租戶會為您的結構描述和特定於其案例的政策提供元素。當您的組織不再處於作用中狀態，而且您想要移除其資料時，工作量會隨著與其他租戶的隔離程度而有所不同。

**服務資源配額**  
Verified Permissions 具有可能影響多租用戶決策的資源和請求率配額。如需配額的詳細資訊，請參閱 [資源的配額](quotas.md#quotas-resources)。

### 比較共用政策存放區和每個租用戶政策存放區
<a name="design-multi-tenancy-considerations-chart"></a>

每個考量都需要在共用和每個租用戶政策存放區模型中自己的時間和資源承諾程度。


| 
| 
| 考量事項  | 共用政策存放區中的工作量層級 | 每個租用戶政策存放區的工作量層級 | 
| --- |--- |--- |
| 租用戶政策隔離 | 中。Must include tenant identifiers in policies and authorization requests. | 低。 Isolation is default behavior. Tenant-specific policies are inaccessible to other tenants. | 
| 授權流程 | 低。 All queries target one policy store. | 中。 Must maintain mappings between each tenant and their policy store ID. | 
| 範本和結構描述管理 | 低。 Must make one schema work for all tenants. | 高。 Schemas and templates might be less complex individually, but changes require more coordination and complexity. | 
| 全球政策管理 | 低。 All policies are global and can be centrally updated. | 高。 You must add global policies to each policy store in onboarding. Replicate global policy updates between many policy stores. | 
| 租戶離職 | 高。 Must identify and delete only tenant-specific policies. | 低。 Delete the policy store. | 
| 服務資源配額 | 高。 Tenants share resource quotas that affect policy stores like schema size, policy size per resource, and identity sources per policy store.  | 低。 Each tenant has dedicated resource quotas. | 

### 如何選擇
<a name="design-multi-tenancy-considerations-how-to-choose"></a>

每個多租戶應用程式都不同。在做出架構決策之前，請仔細比較這兩種方法及其考量。

如果您的應用程式不需要租用戶特定的政策，並使用單一[身分來源](identity-sources.md#identity-sources.title)，則所有租用戶的一個共用政策存放區可能是最有效的解決方案。這會導致更簡單的授權流程和全域政策管理。使用一個共用政策存放區讓租用戶離職需要的精力較少，因為應用程式不需要刪除租用戶特定的政策。

 

但是，如果您的應用程式需要許多租戶特定的政策，或使用多個[身分來源](identity-sources.md#identity-sources.title)，則每個租戶政策存放區可能最有效。您可以使用將每個租用戶許可授予每個政策存放區的 IAM 政策來控制對租用戶政策的存取。離職租戶涉及刪除其政策存放區；在shared-policy-store區環境中，您必須尋找並刪除租戶特定的政策。