

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# 例 2: OPA と Rego を使用したマルチテナントアクセスコントロールとユーザー定義 RBAC
<a name="opa-rbac-examples"></a>

この例では、OPA と Rego を使用して、テナントユーザーが定義したカスタムロールを持つマルチテナントアプリケーションの API でアクセスコントロールを実装する方法を示します。また、テナントに基づいてアクセスを制限する方法も示します。このモデルは、OPA が高レベルのロールで提供される情報に基づいてきめ細かなアクセス許可の決定を行う方法を示しています。

![OPA と Rego を使用したユーザー定義 RBAC](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-api-access-authorization/images/opa-example-2.png)


テナントのロールは、OPA のアクセス決定を行うために使用される外部データ (RBAC データ) に保存されます。

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

これらのロールは、テナントユーザーが定義する場合、テナント定義のロールをアクセス許可とテナント自体にマッピングする際に信頼できるソースとして機能する外部データソースまたは ID プロバイダー (IdP) に保存する必要があります。 

この例では、OPA で 2 つのポリシーを使用して認可の決定を行い、これらのポリシーがテナント分離をどのように適用するかを調べます。これらのポリシーは、前に定義した 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. のユーザーは、 への API コール`Tenant A`を行います`/viewData/tenant_a`。

1. データマイクロサービスは呼び出しを受け取り、`allowViewData`ルールをクエリして、OPA クエリ入力の例に示されている入力を渡します。

1. OPA は、OPA ポリシーでクエリされたルールを使用して、提供された入力を評価します。また、OPA は RBAC データからのデータを使用して入力を評価します。OPA は以下を実行します。

   1. API コールの実行に使用されるメソッドが であることを確認します`GET`。

   1. リクエストされたパスが であることを確認します`viewData`。

   1. パス`tenant_id`の がユーザー`input.tenant_id`に関連付けられている と等しいことを確認します。これにより、テナントの分離が維持されます。同じロールを持つ別のテナントは、この API コールの実行を承認できません。

   1. ロールの外部データからロールのアクセス許可のリストを取得し、変数 に割り当てます`role_permissions`。このリストは、 のユーザーに関連付けられているテナント定義のロールを使用して取得されます。 `input.role.`

   1. アクセス許可が含まれている`role_permissions`かどうかを確認します `viewData.`

1. OPA は、データマイクロサービスに次の決定を返します。

```
{
    "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_role`。には アクセス`updateData`許可`view_data_role`がないため、 への呼び出し`/updateData`は許可されていません。この呼び出しは、 を持つ`tenant_b`ユーザーに対して成功しました`update_data_role`。