Exemple 2 : contrôle d'accès multi-locataires et RBAC défini par l'utilisateur avec OPA et Rego - AWS Conseils prescriptifs

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Exemple 2 : contrôle d'accès multi-locataires et RBAC défini par l'utilisateur avec OPA et Rego

Cet exemple utilise OPA et Rego pour montrer comment le contrôle d'accès peut être implémenté sur une API pour une application multi-locataires avec des rôles personnalisés définis par les utilisateurs locataires. Il montre également comment l'accès peut être restreint en fonction d'un locataire. Ce modèle montre comment l'OPA peut prendre des décisions d'autorisation détaillées sur la base des informations fournies dans le cadre d'un rôle de haut niveau.

RBAC défini par l'utilisateur avec OPA et Rego

Les rôles des locataires sont stockés dans des données externes (données RBAC) qui sont utilisées pour prendre des décisions d'accès pour l'OPA :

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

Ces rôles, lorsqu'ils sont définis par un utilisateur locataire, doivent être stockés dans une source de données externe ou dans un fournisseur d'identité (IdP) qui peut servir de source de vérité lors du mappage des rôles définis par le locataire aux autorisations et au locataire lui-même. 

Cet exemple utilise deux politiques de l'OPA pour prendre des décisions d'autorisation et pour examiner comment ces politiques renforcent l'isolement des locataires. Ces politiques utilisent les données RBAC définies précédemment.

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") }

Pour montrer comment cette règle fonctionnera, considérez une requête OPA contenant les entrées suivantes :

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

Une décision d'autorisation pour cet appel d'API est prise comme suit, en combinant les données RBAC, les politiques OPA et l'entrée de requête OPA :

  1. Un utilisateur de Tenant A envoie un appel d'API à/viewData/tenant_a.

  2. Le microservice Data reçoit l'appel et interroge la allowViewData règle, en transmettant l'entrée indiquée dans l'exemple de saisie de requête OPA.

  3. L'OPA utilise la règle demandée dans les politiques de l'OPA pour évaluer les données fournies. L'OPA utilise également les données du RBAC pour évaluer l'entrée. L'OPA effectue les opérations suivantes :

    1. Vérifie que la méthode utilisée pour effectuer l'appel d'API estGET.

    2. Vérifie que le chemin demandé estviewData.

    3. Vérifie que tenant_id le chemin d'accès est égal à celui input.tenant_id associé à l'utilisateur. Cela garantit le maintien de l'isolement des locataires. Un autre locataire, même avec un rôle identique, ne peut pas être autorisé à effectuer cet appel d'API.

    4. Extrait une liste d'autorisations de rôles à partir des données externes des rôles et les affecte à la variable. role_permissions Cette liste est extraite à l'aide du rôle défini par le locataire associé à l'utilisateur dans input.role.

    5. Vérifie role_permissions s'il contient l'autorisation viewData.

  4. L'OPA renvoie la décision suivante au microservice Data :

{ "allowViewData": true }

Ce processus montre comment le RBAC et la sensibilisation des locataires peuvent contribuer à prendre une décision d'autorisation auprès de l'OPA. Pour mieux illustrer ce point, considérez un appel d'API /viewData/tenant_b avec l'entrée de requête suivante :

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

Cette règle renverrait le même résultat que l'entrée de requête OPA, bien qu'elle soit destinée à un locataire différent ayant un rôle différent. Cela est dû au fait que cet appel est destiné /tenant_b et que view_data_role les données du RBAC ont toujours l'viewDataautorisation qui leur est associée. Pour appliquer le même type de contrôle d'accès pour/updateData, vous pouvez utiliser une règle OPA similaire :

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") }

Cette règle est fonctionnellement identique à la allowViewData règle, mais elle vérifie un chemin et une méthode de saisie différents. La règle garantit toujours l'isolement du locataire et vérifie que le rôle défini par le locataire accorde l'autorisation à l'appelant de l'API. Pour voir comment cela peut être appliqué, examinez l'entrée de requête suivante pour un appel d'API à /updateData/tenant_b :

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

Cette entrée de requête, lorsqu'elle est évaluée à l'aide de la allowUpdateData règle, renvoie la décision d'autorisation suivante :

{ "allowUpdateData": false }

Cet appel ne sera pas autorisé. Bien que l'appelant de l'API soit associé à la bonne API tenant_id et appelle l'API à l'aide d'une méthode approuvée, il s'input.roleagit de la méthode définie par le locataireview_data_role. Le view_data_role n'a pas l'updateDataautorisation ; par conséquent, l'appel à /updateData n'est pas autorisé. Cet appel aurait été un succès pour un tenant_b utilisateur possédant leupdate_data_role.