Complete phase-1 of RBAC community-wide goal

After moving the nova APIs policy as per the new guidlines
where system scoped token will be only allowed to access
system level APIs and will not be allowed any operation
on project level APIs. With that we do not need below
base rules (who have hardcoded 'system_scope:all' check_str):
- system_admin_api
- system_reader_api
- system_admin_or_owner
- system_or_project_reader

At this stage (phase-1 target), we allow below roles as targeted
in phase-1 [1]
1. ADMIN(this is System Administrator with scope_type 'system'
when scope enabled otherwise legacy admin)
2. PROJECT_ADMIN
3. PROJECT_MEMBER
4. PROJECT_READER
 & below one specific to nova
5. PROJECT_READER_OR_ADMIN (to allow system admin and project reader
to list flavor extra specs)

This complete the phase-1 of RBAC community-wide goal[2] for nova.

Add release notes too.

[1] https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#how-operator
[2] https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#yoga-timeline-7th-mar-2022

Partial implement blueprint policy-defaults-refresh-2

Change-Id: I075005d13ff6bfe048bbb21d80d71bf1602e4c02
This commit is contained in:
Ghanshyam Mann 2022-02-18 02:29:17 -06:00 committed by Ghanshyam
parent 1be007243b
commit f9c1d1163d
9 changed files with 108 additions and 132 deletions

View File

@ -41,7 +41,7 @@ resources from project or system level resources. Please refer to
:keystone-doc:`this document </admin/tokens-overview.html#authorization-scopes>`
and `system scope specification <https://specs.openstack.org/openstack/keystone-specs/specs/keystone/queens/system-scope.html>`_ to understand the scope concept.
In the Nova 21.0.0 (Ussuri) release, Nova policies implemented
In the Nova 25.0.0 (Yoga) release, Nova policies implemented
the scope concept and default roles provided by keystone (admin, member,
and reader). Using common roles from keystone reduces the likelihood of
similar, but different, roles implemented across projects or deployments
@ -112,15 +112,15 @@ Policies with a ``scope_type`` of ``system and project`` means a user with a
resource. All the system and project level operation's policies have defaulted
to ``scope_type`` of ``['system', 'project']``.
For example, consider the ``POST /servers/{server_id}/action (os-migrateLive)``
For example, consider the ``GET /flavors/{flavor_id}/os-extra_specs/{flavor_extra_spec_key}``
API.
.. code::
# Live migrate a server to a new host without a reboot
# POST /servers/{server_id}/action (os-migrateLive)
# Show an extra spec for a flavor
# GET /flavors/{flavor_id}/os-extra_specs/{flavor_extra_spec_key}
# Intended scope(s): system, project
#"os_compute_api:os-migrate-server:migrate_live": "rule:system_admin_api"
#"os_compute_api:os-flavor-extra-specs:show": "rule:project_reader_or_admin"
These scope types provide a way to differentiate between system-level and
project-level access roles. You can control the information with scope of the
@ -212,11 +212,12 @@ Nova supported scope & Roles
Nova supports the below combination of scopes and roles where roles can be
overridden in the policy.yaml file but scope is not override-able.
#. SYSTEM_ADMIN: ``admin`` role on ``system`` scope
#. ADMIN: ``admin`` role on ``system`` scope. This is System Administrator to
perform the system level resource operations. Example: enable/disable compute
services.
#. SYSTEM_READER: ``reader`` role on ``system`` scope
#. PROJECT_ADMIN: ``admin`` role on ``project`` scope
#. PROJECT_ADMIN: ``admin`` role on ``project`` scope. This is used to perform
admin level operation within project. For example: Live migrate server.
.. note::
@ -231,17 +232,18 @@ overridden in the policy.yaml file but scope is not override-able.
via API. This limitation will be addressed in a future release.
#. PROJECT_MEMBER: ``member`` role on ``project`` scope
#. PROJECT_MEMBER: ``member`` role on ``project`` scope. This is used to perform
resource owner level operation within project. For example: Pause a server.
#. PROJECT_READER: ``reader`` role on ``project`` scope
#. PROJECT_MEMBER_OR_SYSTEM_ADMIN: ``admin`` role on ``system`` scope
or ``member`` role on ``project`` scope. Such policy rules are scoped
as both ``system`` as well as ``project``.
#. PROJECT_READER: ``reader`` role on ``project`` scope. This is used to perform
read-only operation within project. For example: Get server.
#. PROJECT_READER_OR_SYSTEM_READER: ``reader`` role on ``system`` scope
or ``project`` scope. Such policy rules are scoped as both ``system``
as well as ``project``.
#. PROJECT_READER_OR_ADMIN: ``admin`` role on ``system`` scope
or ``reader`` role on ``project`` scope. Such policy rules are scoped
as both ``system`` as well as ``project``. Example: to allow system
admin and project reader to list flavor extra specs.
.. note:: As of now, only ``system`` and ``project`` scopes are supported in Nova.
@ -252,8 +254,9 @@ Backward compatibility with versions prior to 21.0.0 (Ussuri) is maintained by
supporting the old defaults and disabling the ``scope_type`` feature by default.
This means the old defaults and deployments that use them will keep working
as-is. However, we encourage every deployment to switch to new policy.
``scope_type`` will be enabled by default and the old defaults will be removed
starting in the 23.0.0 (W) release.
Scope checks are disabled by default and will be enabled by default starting
Nova 26.0.0 (OpenStack Zed release) and the old defaults will be removed
starting in the Nova 27.0.0 release.
To implement the new default reader roles, some policies needed to become
granular. They have been renamed, with the old names still supported for
@ -323,9 +326,9 @@ Below table show how legacy rules are mapped to new rules:
+====================+==================================+=================+===================+
| | | *Roles* | *Scope* |
| +----------------------------------+-----------------+-------------------+
| | SYSTEM_ADMIN | admin | system |
| | ADMIN | admin | system |
| Project Admin +----------------------------------+-----------------+ |
| Role | SYSTEM_READER | reader | |
| Role | PROJECT_ADMIN | admin | project |
| | | | |
+--------------------+----------------------------------+-----------------+-------------------+
| | PROJECT_ADMIN | admin | project |
@ -334,12 +337,10 @@ Below table show how legacy rules are mapped to new rules:
| +----------------------------------+-----------------+ |
| Project admin or | PROJECT_READER | reader | |
| owner role +----------------------------------+-----------------+-------------------+
| | PROJECT_MEMBER_OR_SYSTEM_ADMIN | admin on system | system |
| | | or member on | OR |
| | PROJECT_READER_OR_ADMIN | admin on system | system |
| | | or reader on | OR |
| | | project | project |
| +----------------------------------+-----------------+ |
| | PROJECT_READER_OR_SYSTEM_READER | reader | |
+--------------------+----------------------------------+-----------------+-------------------+
We expect all deployments to migrate to new policy by 23.0.0 release so that
We expect all deployments to migrate to new policy by 27.0.0 release so that
we can remove the support of old policies.

View File

@ -279,7 +279,7 @@ class UpgradeCommands(upgradecheck.UpgradeCommands):
"2. Use a pre-existing sample config file from the Train "
"release. 3. Use an empty or non-existent file to take all "
"the defaults.")
rule = "system_admin_api"
rule = "context_is_admin"
rule_new_default = "role:admin and system_scope:all"
status = upgradecheck.Result(upgradecheck.Code.SUCCESS)
# NOTE(gmann): Initialise the policy if it not initialized.

View File

@ -36,43 +36,28 @@ DEPRECATED_ADMIN_OR_OWNER_POLICY = policy.DeprecatedRule(
deprecated_reason=DEPRECATED_REASON,
deprecated_since='21.0.0'
)
# TODO(gmann): # Special string ``system_scope:all`` is added for system
# scoped policies for backwards compatibility where ``nova.conf [oslo_policy]
# enforce_scope = False``.
# Otherwise, this might open up APIs to be more permissive unintentionally if a
# deployment isn't enforcing scope. For example, the 'list all servers'
# policy will be System Scoped Reader with ``role:reader`` and
# scope_type=['system'] Until enforce_scope=True by default, it would
# be possible for users with the ``reader`` role on a project to access the
# 'list all servers' API. Once nova defaults ``nova.conf [oslo_policy]
# enforce_scope=True``, the ``system_scope:all`` bits of these check strings
# can be removed since that will be handled automatically by scope_types in
# oslo.policy's RuleDefault objects.
SYSTEM_ADMIN = 'rule:system_admin_api'
SYSTEM_READER = 'rule:system_reader_api'
PROJECT_ADMIN = 'rule:project_admin_api'
PROJECT_MEMBER = 'rule:project_member_api'
PROJECT_READER = 'rule:project_reader_api'
PROJECT_MEMBER_OR_SYSTEM_ADMIN = 'rule:system_admin_or_owner'
PROJECT_READER_OR_SYSTEM_READER = 'rule:system_or_project_reader'
PROJECT_READER_OR_ADMIN = 'rule:project_reader_or_admin'
ADMIN = 'rule:context_is_admin'
# NOTE(gmann): Below is the mapping of new roles and scope_types
# with legacy roles::
# Legacy Rule | New Rules |Operation |scope_type|
# -------------------+----------------------------------+----------+-----------
# |-> SYSTEM_ADMIN |Global | [system]
# RULE_ADMIN_API | Write
# |-> SYSTEM_READER |Global | [system]
# | |Read |
#
# |-> PROJECT_MEMBER_OR_SYSTEM_ADMIN |Project | [system,
# RULE_ADMIN_OR_OWNER| |Write | project]
# |-> PROJECT_READER_OR_SYSTEM_READER|Project | [system,
# |Read | project]
# Legacy Rule | New Rules |Operation |scope_type|
# -------------------+---------------------+----------------+-----------
# |-> ADMIN |Global resource | [system]
# RULE_ADMIN_API | |Write & Read |
# |-> PROJECT_ADMIN |Project resource| [project]
# | |Write |
# ----------------------------------------------------------------------
# |-> PROJECT_ADMIN |Project resource| [project]
# | |Write |
# |-> PROJECT_MEMBER |Project resource| [project]
# RULE_ADMIN_OR_OWNER| |Write |
# |-> PROJECT_READER |Project resource| [project]
# | |Read |
# NOTE(johngarbutt) The base rules here affect so many APIs the list
# of related API operations has not been populated. It would be
@ -106,16 +91,6 @@ rules = [
deprecated_for_removal=True,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='21.0.0'),
policy.RuleDefault(
name="system_admin_api",
check_str='role:admin and system_scope:all',
description="Default rule for System Admin APIs.",
deprecated_rule=DEPRECATED_ADMIN_POLICY),
policy.RuleDefault(
name="system_reader_api",
check_str="role:reader and system_scope:all",
description="Default rule for System level read only APIs.",
deprecated_rule=DEPRECATED_ADMIN_POLICY),
policy.RuleDefault(
"project_admin_api",
"role:admin and project_id:%(project_id)s",
@ -131,16 +106,6 @@ rules = [
"role:reader and project_id:%(project_id)s",
"Default rule for Project level read only APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY),
policy.RuleDefault(
name="system_admin_or_owner",
check_str="rule:system_admin_api or rule:project_member_api",
description="Default rule for System admin+owner APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY),
policy.RuleDefault(
"system_or_project_reader",
"rule:system_reader_api or rule:project_reader_api",
"Default rule for System+Project read only APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY),
policy.RuleDefault(
"project_reader_or_admin",
"rule:project_reader_api or rule:context_is_admin",

View File

@ -401,7 +401,7 @@ class TestUpgradeCheckPolicy(test.NoDBTestCase):
def setUp(self):
super(TestUpgradeCheckPolicy, self).setUp()
self.cmd = status.UpgradeCommands()
self.rule_name = "system_admin_api"
self.rule_name = "context_is_admin"
def tearDown(self):
super(TestUpgradeCheckPolicy, self).tearDown()

View File

@ -53,7 +53,7 @@ class BasePolicyTest(test.TestCase):
# For Example:
# rules_without_deprecation{
# "os_compute_api:os-deferred-delete:restore":
# "rule:system_admin_or_owner"}
# "rule:project_admin_api"}
rules_without_deprecation = {}
def setUp(self):
@ -141,14 +141,6 @@ class BasePolicyTest(test.TestCase):
self.rules_without_deprecation.update({
"context_is_admin":
"role:admin",
"system_admin_or_owner":
"rule:system_admin_api or rule:project_member_api",
"system_or_project_reader":
"rule:system_reader_api or rule:project_reader_api",
"system_admin_api":
"role:admin and system_scope:all",
"system_reader_api":
"role:reader and system_scope:all",
"project_reader_or_admin":
"rule:project_reader_api or rule:context_is_admin",
"project_admin_api":

View File

@ -75,7 +75,6 @@ class ExtensionsScopeTypePolicyTest(ExtensionsPolicyTest):
class ExtensionsNoLegacyPolicyTest(ExtensionsScopeTypePolicyTest):
"""Test Extensions APIs policies with system scope enabled,
and no more deprecated rules that allow the legacy admin API to
access system_admin_or_owner APIs.
and no more deprecated rules.
"""
without_deprecated_rules = True

View File

@ -14,7 +14,6 @@ import functools
import fixtures
import mock
from oslo_log import log as logging
from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import timeutils
@ -38,7 +37,6 @@ from nova.tests.unit import fake_instance
from nova.tests.unit.policies import base
CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)
class ServersPolicyTest(base.BasePolicyTest):

View File

@ -366,6 +366,26 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-server-external-events:create",
"os_compute_api:os-volumes-attachments:swap",
"os_compute_api:servers:create:zero_disk_flavor",
"os_compute_api:os-baremetal-nodes:list",
"os_compute_api:os-baremetal-nodes:show",
"os_compute_api:servers:migrations:index",
"os_compute_api:servers:migrations:show",
"os_compute_api:os-simple-tenant-usage:list",
"os_compute_api:os-migrations:index",
"os_compute_api:os-services:list",
"os_compute_api:os-instance-actions:events:details",
"os_compute_api:os-instance-usage-audit-log:list",
"os_compute_api:os-instance-usage-audit-log:show",
"os_compute_api:os-hosts:list",
"os_compute_api:os-hosts:show",
"os_compute_api:os-hypervisors:list",
"os_compute_api:os-hypervisors:list-detail",
"os_compute_api:os-hypervisors:show",
"os_compute_api:os-hypervisors:statistics",
"os_compute_api:os-hypervisors:uptime",
"os_compute_api:os-hypervisors:search",
"os_compute_api:os-hypervisors:servers",
"os_compute_api:limits:other_project",
)
self.admin_or_owner_rules = (
@ -455,44 +475,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-volumes-attachments:create",
"os_compute_api:os-volumes-attachments:delete",
"os_compute_api:os-volumes-attachments:update",
)
self.allow_all_rules = (
"os_compute_api:os-quota-sets:defaults",
"os_compute_api:os-availability-zone:list",
"os_compute_api:limits",
"os_compute_api:extensions",
"os_compute_api:os-floating-ip-pools",
)
self.system_reader_rules = (
"os_compute_api:os-tenant-networks:list",
"os_compute_api:os-tenant-networks:show",
"os_compute_api:os-baremetal-nodes:list",
"os_compute_api:os-baremetal-nodes:show",
"os_compute_api:servers:migrations:index",
"os_compute_api:servers:migrations:show",
"os_compute_api:os-simple-tenant-usage:list",
"os_compute_api:os-migrations:index",
"os_compute_api:os-services:list",
"os_compute_api:os-instance-actions:events:details",
"os_compute_api:os-instance-usage-audit-log:list",
"os_compute_api:os-instance-usage-audit-log:show",
"os_compute_api:os-hosts:list",
"os_compute_api:os-hosts:show",
"os_compute_api:os-hypervisors:list",
"os_compute_api:os-hypervisors:list-detail",
"os_compute_api:os-hypervisors:show",
"os_compute_api:os-hypervisors:statistics",
"os_compute_api:os-hypervisors:uptime",
"os_compute_api:os-hypervisors:search",
"os_compute_api:os-hypervisors:servers",
"os_compute_api:limits:other_project",
"os_compute_api:os-networks:list",
"os_compute_api:os-networks:show",
)
self.system_reader_or_owner_rules = (
"os_compute_api:os-simple-tenant-usage:show",
"os_compute_api:os-security-groups:get",
"os_compute_api:os-security-groups:show",
@ -514,6 +496,18 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-volumes:snapshots:show",
"os_compute_api:os-volumes:snapshots:list",
"os_compute_api:os-volumes:snapshots:detail",
"os_compute_api:os-networks:list",
"os_compute_api:os-networks:show",
"os_compute_api:os-tenant-networks:list",
"os_compute_api:os-tenant-networks:show",
)
self.allow_all_rules = (
"os_compute_api:os-quota-sets:defaults",
"os_compute_api:os-availability-zone:list",
"os_compute_api:limits",
"os_compute_api:extensions",
"os_compute_api:os-floating-ip-pools",
)
self.allow_nobody_rules = (
@ -558,13 +552,10 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
# admin_only, non_admin, admin_or_user, empty_rule
special_rules = ('admin_api', 'admin_or_owner', 'context_is_admin',
'os_compute_api:os-quota-class-sets:show',
'system_admin_api', 'system_reader_api',
'project_admin_api', 'project_member_api',
'project_reader_api', 'system_admin_or_owner',
'system_or_project_reader', 'project_reader_or_admin')
'project_reader_api', 'project_reader_or_admin')
result = set(rules.keys()) - set(self.admin_only_rules +
self.admin_or_owner_rules +
self.allow_all_rules + self.system_reader_rules +
self.system_reader_or_owner_rules +
self.allow_all_rules +
self.allow_nobody_rules + special_rules)
self.assertEqual(set([]), result)

View File

@ -0,0 +1,30 @@
---
features:
- |
The Nova policies have been modified to isolate the system and project
level APIs policy. This means system users will be allowed to perform
the operation on system level resources and will not to allowed any
operation on project level resources. Project Level APIs operation will be
performed by the project scoped users.
Currently, nova supports:
* ``system admin``
* ``project admin``
* ``project member``
* ``project reader``
For the details on what changed from the existing policy, please refer the
`RBAC new guidelines`_. We have implemented only phase-1
`RBAC new guidelines`_.
Currently, scope checks and new defaults are disabled by default. You can
enable them by switching the below config option in ``nova.conf`` file::
[oslo_policy]
enforce_new_defaults=True
enforce_scope=True
Please refer `Policy New Defaults`_ for detail about policy new defaults
and migration plan.
.. _RBAC new guidelines: https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-1
.. _Policy New Defaults: https://docs.openstack.org/nova/latest/configuration/policy-concepts.html