Merge "Complete phase-1 of RBAC community-wide goal"
This commit is contained in:
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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",
|
||||
|
@@ -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()
|
||||
|
@@ -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":
|
||||
|
@@ -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
|
||||
|
@@ -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):
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
Reference in New Issue
Block a user