

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
<a name="opa-rbac-examples"></a>

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](http://docs.aws.amazon.com/fr_fr/prescriptive-guidance/latest/saas-multitenant-api-access-authorization/images/opa-example-2.png)


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`.

1. 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.

1. 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 est`GET`.

   1. Vérifie que le chemin demandé est`viewData`.

   1. 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.

   1. 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.`

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

1. 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'`viewData`autorisation 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.role`agit de la méthode définie par le locataire`view_data_role`. Le `view_data_role` n'a pas l'`updateData`autorisation ; par conséquent, l'appel à `/updateData` n'est pas autorisé. Cet appel aurait été un succès pour un `tenant_b` utilisateur possédant le`update_data_role`.