

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Contoh 2: Kontrol akses multi-penyewa dan RBAC yang ditentukan pengguna dengan OPA dan Rego
<a name="opa-rbac-examples"></a>

Contoh ini menggunakan OPA dan Rego untuk mendemonstrasikan bagaimana kontrol akses dapat diimplementasikan pada API untuk aplikasi multi-penyewa dengan peran khusus yang ditentukan oleh pengguna penyewa. Ini juga menunjukkan bagaimana akses dapat dibatasi berdasarkan penyewa. Model ini menunjukkan bagaimana OPA dapat membuat keputusan izin terperinci berdasarkan informasi yang diberikan dalam peran tingkat tinggi.

![RBAC yang ditentukan pengguna dengan OPA dan Rego](http://docs.aws.amazon.com/id_id/prescriptive-guidance/latest/saas-multitenant-api-access-authorization/images/opa-example-2.png)


Peran untuk penyewa disimpan dalam data eksternal (data RBAC) yang digunakan untuk membuat keputusan akses untuk OPA:

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

Peran ini, ketika didefinisikan oleh pengguna penyewa, harus disimpan dalam sumber data eksternal atau penyedia identitas (idP) yang dapat bertindak sebagai sumber kebenaran saat memetakan peran yang ditentukan penyewa ke izin dan penyewa itu sendiri. 

Contoh ini menggunakan dua kebijakan dalam OPA untuk membuat keputusan otorisasi dan untuk memeriksa bagaimana kebijakan ini menegakkan isolasi penyewa. Kebijakan ini menggunakan data RBAC yang ditentukan sebelumnya.

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

Untuk menunjukkan bagaimana aturan ini akan berfungsi, pertimbangkan kueri OPA yang memiliki masukan berikut:

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

*Keputusan otorisasi untuk panggilan API ini dibuat sebagai berikut, dengan menggabungkan *data RBAC*, *kebijakan OPA, dan input kueri OPA*:*

1. Seorang pengguna dari `Tenant A` membuat panggilan API ke`/viewData/tenant_a`.

1. Layanan mikro Data menerima panggilan dan menanyakan `allowViewData` aturan, meneruskan input yang ditunjukkan dalam contoh input kueri OPA.

1. OPA menggunakan aturan yang ditanyakan dalam kebijakan OPA untuk mengevaluasi masukan yang diberikan. OPA juga menggunakan data dari data RBAC untuk mengevaluasi input. OPA melakukan hal berikut:

   1. Memverifikasi bahwa metode yang digunakan untuk melakukan panggilan API adalah`GET`.

   1. Memverifikasi bahwa jalur yang diminta adalah`viewData`.

   1. Memeriksa bahwa `tenant_id` di jalur sama dengan yang `input.tenant_id` terkait dengan pengguna. Ini memastikan bahwa isolasi penyewa dipertahankan. Penyewa lain, bahkan dengan peran yang identik, tidak dapat diotorisasi dalam melakukan panggilan API ini.

   1. Menarik daftar izin peran dari data eksternal peran dan menetapkannya ke variabel. `role_permissions` Daftar ini diambil dengan menggunakan peran yang ditentukan penyewa yang dikaitkan dengan pengguna di `input.role.`

   1. Memeriksa `role_permissions` untuk melihat apakah itu berisi izin `viewData.`

1. OPA mengembalikan keputusan berikut ke layanan mikro Data:

```
{
    "allowViewData": true
}
```

Proses ini menunjukkan bagaimana RBAC dan kesadaran penyewa dapat berkontribusi untuk membuat keputusan otorisasi dengan OPA. Untuk mengilustrasikan poin ini lebih lanjut, pertimbangkan panggilan API `/viewData/tenant_b` dengan input kueri berikut:

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

Aturan ini akan mengembalikan output yang sama dengan input kueri OPA meskipun untuk penyewa berbeda yang memiliki peran berbeda. Ini karena panggilan ini untuk `/tenant_b` dan data `view_data_role` dalam RBAC masih memiliki `viewData` izin yang terkait dengannya. Untuk menerapkan jenis kontrol akses yang sama`/updateData`, Anda dapat menggunakan aturan OPA yang serupa:

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

Aturan ini secara fungsional sama dengan `allowViewData` aturan, tetapi memverifikasi jalur dan metode input yang berbeda. Aturan masih memastikan isolasi penyewa dan memeriksa apakah peran yang ditentukan penyewa memberikan izin pemanggil API. Untuk melihat bagaimana hal ini dapat diterapkan, periksa input kueri berikut untuk panggilan API ke`/updateData/tenant_b`:

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

Input kueri ini, ketika dievaluasi dengan `allowUpdateData` aturan, mengembalikan keputusan otorisasi berikut:

```
{
    "allowUpdateData": false
}
```

Panggilan ini tidak akan diizinkan. Meskipun pemanggil API dikaitkan dengan yang benar `tenant_id` dan memanggil API dengan menggunakan metode yang disetujui, pemanggil `input.role` adalah yang ditentukan oleh penyewa`view_data_role`. `view_data_role`Tidak memiliki `updateData` izin; oleh karena itu, panggilan ke `/updateData` tidak sah. Panggilan ini akan berhasil bagi `tenant_b` pengguna yang memiliki`update_data_role`.