[ English | 中文 (简体, 中国) | русский | português (Brasil) | नेपाली | 한국어 (대한민국) | Indonesia | français | español | esperanto | English (United Kingdom) | Deutsch ]

Horizon Policy Enforcement (RBAC: Role Based Access Control)

Pengantar

Penegakan kebijakan Horizon dibangun di atas engine oslo_policy. Dasarnya adalah openstack_auth/policy.py. Layanan di OpenStack menggunakan mesin kebijakan oslo untuk mendefinisikan aturan kebijakan untuk membatasi akses ke API berdasarkan pada pemberian peran dan kepemilikan sumber daya.

Implementasi di Horizon didasarkan pada salinan file kebijakan yang ditemukan dalam kode sumber layanan.

File aturan layanan dimuat ke mesin kebijakan untuk menentukan hak akses ke tindakan dan API layanan.

Pengaturan Horizon

Ada beberapa pengaturan yang harus ada agar mesin kebijakan Horizon berfungsi.

  • POLICY_CHECK_FUNCTION

  • POLICY_DIRS

  • POLICY_FILES_PATH

  • POLICY_FILES

  • DEFAULT_POLICY_FILES

Untuk detail lebih lanjut, lihat Referensi Pengaturan.

Bagaimana peran pengguna ditentukan

Setiap pemeriksaan kebijakan menggunakan informasi tentang pengguna yang disimpan pada permintaan untuk menentukan peran pengguna. Informasi ini diekstraksi dari bukti yang diterima dari Keystone ketika diautentikasi.

Kepemilikan entitas juga merupakan peran yang valid. Untuk memverifikasi akses ke entitas tertentu seperti proyek, target harus ditentukan. Lihat bagian rule targets nanti dalam dokumen ini.

Cara Menggunakan RBAC

Django: Table action

Cara utama untuk menambahkan pemeriksaan kontrol akses berbasis peran ke panel adalah dalam definisi table action (tindakan tabel). Saat menerapkan kelas tindakan turunan, menetapkan atribut policy_rules ke aturan kebijakan yang valid akan memaksa pemeriksaan kebijakan sebelum metode horizon.tables.Action.allowed() dipanggil tindakan. Aturan-aturan ini didefinisikan dalam file kebijakan yang ditunjukkan oleh POLICY_PATH dan POLICY_FILES. Aturan berdasarkan peran, di mana pemilik entitas juga berperan. Format untuk policy_rules adalah daftar dua item tuple. Komponen pertama dari tuple adalah ruang lingkup aturan kebijakan, ini adalah jenis layanan. Ini menginformasikan mesin kebijakan yang file kebijakan untuk referensi. Komponen kedua adalah aturan untuk menegakkan dari file kebijakan yang ditentukan oleh ruang lingkup. Contoh tuple adalah

("identity", "identity:get_user")

x tuples dapat ditambahkan untuk menegakkan aturan x.

Catatan

Jika aturan yang ditentukan tidak ditemukan dalam file kebijakan, pemeriksaan kebijakan akan mengembalikan False dan tindakan tidak akan diizinkan.

Django: fungsi pemeriksaan kebijakan

Cara sekunder untuk menambahkan cek berbasis peran adalah dengan langsung menggunakan metode:meth:~openstack_dashboard.policy.check. Metode ini mengambil daftar tindakan, format yang sama dengan atribut policy_rules yang dirinci di atas; objek permintaan saat ini; dan kamus target aksi. Ini adalah metode yang memanfaatkan kelas horizon.tables.Action. Contohnya terlihat seperti

from openstack_dashboard import policy

allowed = policy.check((("identity", "identity:get_user"),
                       ("identity", "identity:get_project"),), request)

can_see = policy.check((("identity", "identity:get_user"),), request,
                       target={"domain_id": domainId})

Catatan

Setiap kali beberapa aturan ditentukan dalam pemanggilan metode policy.check tunggal, hasilnya adalah logika and dari setiap pemeriksaan aturan. Jadi, jika ada aturan yang gagal verifikasi, hasilnya adalah False.

Angular: metode ifAllowed

Cara ketiga untuk menambahkan pemeriksaan berbasis peran adalah dalam file javascript. Gunakan metode 'ifAllowed ()' dalam file 'openstack_dashboard.static.app.core.policy.service.js'. Metode ini mengambil daftar tindakan, format yang serupa dengan atribut :attr: ~ horizon.tables.Action.policy_rules yang dirinci di atas. Contohnya terlihat seperti:

angular
.module('horizon.dashboard.identity.users')
.controller('identityUsersTableController', identityUsersTableController);

identityUsersTableController.$inject = [
  'horizon.app.core.openstack-service-api.policy',
];

function identityUsersTableController(toast, gettext, policy, keystone) {
  var rules = [['identity', 'identity:list_users']];
  policy.ifAllowed({ rules: rules }).then(policySuccess, policyFailed);
}

Angular: hz-if-policies

Cara keempat untuk menambahkan pemeriksaan berbasis peran adalah dalam file html. Gunakan directive angular 'hz-if-policy' dalam file 'openstack_dashboard/static/app/core/cloud-services/hz-if-policies.directive.js'. Asumsikan Anda memiliki kebijakan berikut yang ditentukan dalam pengontrol angular Anda

ctrl.policy = { rules: [["identity", "identity:update_user"]] }

Kemudian di HTML Anda, gunakan seperti ini:

<div hz-if-policies='ctrl.policy'>
  <span>I am visible if the policy is allowed!</span>
</div>

Rule Targets

Beberapa aturan mengizinkan akses jika pengguna memiliki entitas. Target pemeriksaan kebijakan menentukan entitas tertentu untuk memeriksa kepemilikan pengguna. Parameter target ke metode check() adalah kamus sederhana. Misalnya, target untuk memeriksa akses suatu proyek terlihat seperti:

{"project_id": "0905760626534a74979afd3f4a9d67f1"}

Jika nilainya sesuai dengan project_id tempat token pengguna dicakup, maka akses diizinkan.

Ketika menurunkan kelas :class: horizon.tables.Action untuk digunakan dalam sebuah tabel, jika pemeriksaan kebijakan diinginkan untuk target tertentu, pelaksana harus mengganti metode :meth:` horizon.tables.Action.get_policy_target`. Ini memungkinkan cara terprogram untuk menentukan target berdasarkan pada datum saat ini. Nilai yang dikembalikan harus menjadi kamus target.

Policy-in-Code and deprecated rules

As the effort of policy-in-code, most OpenStack projects define their default policies in their codes. All projects (except swift) covered by horizon supports "policy-in-code". (Note that swift is an exception as it has its own mechanism to control RBAC.)

"oslo.policy" provides a way to deprecate existing policy rules like renaming rule definitions ("check_str") and renaming rule names. They are defined as part of python codes in back-end services. horizon cannot import python codes of back-end services, so we need a way to restore policies defined by "policy-in-code" including deprecated rules.

To address the above issue, horizon adopts the following two-step approach:

  • The first step scans policy-in-code of back-end services and and dump the loaded default policies into YAML files per service including information of deprecated rules. This step is executed as part of the development process per release cycle and these YAML files are shipped per release.

    Note that oslopolicy-sample-generator does not output deprecated rules in a structured way, so we prepare a dedicated script for this purpose in the horizon repo.

  • The horizon policy implementation loads the above YAML file into a list of RuleDefault and registers the list as the default rules to the policy enforcer. The default rules and operator-defined rules are maintained separately, so operators still can edit the policy files as oslo.policy does in back-end services.

This approach has the following merits:

  • All features supported by oslo.policy can be supported in horizon as default rules in back-end services are restored as-is. Horizon can evaluate deprecated rules.

  • The default rules and operator defined rules are maintained separately. Operators can use the same way to maintain policy files of back-end services.

The related files in the horizon codebase are:

  • openstack_dashboard/conf/<service>_policy.yaml: operator-defined policies. These files are generated by oslopolicy-sample-generator.

  • openstack_dashboard/conf/default_policies/<service>.yaml YAML files contain default policies.

  • openstack_dashboard/management/commands/dump_default_policies.py: This script scans policy-in-code of a specified namespace under oslo.policy.policies entrypoints and dump them into the YAML file under openstack_dashboard/conf/default_policies.

  • openstack_auth/policy.py: _load_default_rules function loads the YAML files with default rules and call register_defautls method of the policy enforcer per service.

Pemeliharaan file kebijakan

  • YAML files for default policies

    Run the following command after installing a corresponding project. You need to run it for keystone, nova, cinder, neutron, glance.

    python3 manage.py dump_default_policies \
      --namespace $PROJECT \
      --output-file openstack_dashboard/conf/default_policies/${PROJECT}.yaml
    
  • Sample policy files

    Run the following commands after installing a corresponding project. You need to run it for keystone, nova, cinder, neutron, glance.

    oslopolicy-sample-generator --namespace $PROJECT \
      --output-file openstack_dashboard/conf/${PROJECT}_policy.yaml
    sed -i 's/^"/#"/' openstack_dashboard/conf/${PROJECT}_policy.yaml
    

    Catatan

    We now use YAML format for sample policy files now. "oslo.policy" can accept both YAML and JSON files. We now support default policies so there is no need to define all policies using JSON files. YAML files also allows us to use comments, so we can provide good sample policy files. This is the same motivation as the Wallaby community goal Migrate RBAC Policy Format from JSON to YAML.

    Catatan

    The second "sed" command is to comment out rules for rule renames. oslopolicy-sample-generator does not comment out them, but they are unnecessary in horizon usage. A single renaming rule can map to multiple rules, so it does not work as-is. In addition, they trigger deprecation warnings in horizon log if these sample files are used in horizon as-is. Thus, we comment them out by default.

After syncing policies from back-end services, you need to check what are changed. If a policy referred by horizon has been changed, you need to check and modify the horizon code base accordingly.

Peringatan

After the support of default policies, the following tool does not work. It is a future work to make it work again or evaluate the need itself.

To summarize which policies are removed or added, a convenient tool is provided:

$ cd openstack_dashboard/conf/
$ python ../../tools/policy-diff.py --help
usage: policy-diff.py [-h] --old OLD --new NEW [--mode {add,remove}]

optional arguments:
-h, --help           show this help message and exit
--old OLD            Current policy file
--new NEW            New policy file
--mode {add,remove}  Diffs to be shown

# Show removed policies
# The default is "--mode remove". You can omit --mode option.
$ python ../../tools/policy-diff.py \
    --old keystone_policy.json --new keystone_policy.json.new --mode remove
default
identity:change_password
identity:get_identity_provider