Merge "Add support for scoped tokens and default roles"
This commit is contained in:
commit
41ff3ee3f1
@ -2,6 +2,19 @@
|
|||||||
Octavia Policies
|
Octavia Policies
|
||||||
================
|
================
|
||||||
|
|
||||||
|
.. _Keystone Default Roles: https://docs.openstack.org/keystone/latest/admin/service-api-protection.html
|
||||||
|
|
||||||
|
Octavia Advanced Role Based Access Control (RBAC)
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
Octavia adopted the "Advanced Role Based Access Control (RBAC)" default
|
||||||
|
policies in the Pike release of OpenStack. This provides a fine-grained default
|
||||||
|
access control policy for the Octavia service.
|
||||||
|
|
||||||
|
The Octavia Advanced RBAC goes beyond the OpenStack legacy RBAC policies of
|
||||||
|
allowing "owners and admins" full access to all services. It also provides a
|
||||||
|
more fine-grained RBAC policy than the newer `Keystone Default Roles`_ .
|
||||||
|
|
||||||
The default policy is to not allow access unless the auth_strategy is 'noauth'.
|
The default policy is to not allow access unless the auth_strategy is 'noauth'.
|
||||||
|
|
||||||
Users must be a member of one of the following roles to have access to
|
Users must be a member of one of the following roles to have access to
|
||||||
@ -23,11 +36,11 @@ the load-balancer API:
|
|||||||
User is considered an admin for quota APIs only.
|
User is considered an admin for quota APIs only.
|
||||||
|
|
||||||
role:load-balancer_admin
|
role:load-balancer_admin
|
||||||
User is considered an admin for all load-balnacer APIs including
|
User is considered an admin for all load-balancer APIs including
|
||||||
resources owned by others.
|
resources owned by others.
|
||||||
|
|
||||||
role:admin
|
role:admin and system_scope:all
|
||||||
User is admin to all APIs.
|
User is admin to all service APIs, including Octavia.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -36,13 +49,136 @@ the load-balancer API:
|
|||||||
It is equivalent to 'rule:context_is_admin or {auth_strategy == noauth}'
|
It is equivalent to 'rule:context_is_admin or {auth_strategy == noauth}'
|
||||||
if that would be valid syntax.
|
if that would be valid syntax.
|
||||||
|
|
||||||
Legacy Admin or Owner Policy
|
These roles are in addition to the `Keystone Default Roles`_:
|
||||||
----------------------------
|
|
||||||
|
* role:reader
|
||||||
|
* role:member
|
||||||
|
|
||||||
|
In addition, the Octavia API supports Keystone scoped tokens. When enabled
|
||||||
|
in Oslo Policy, users will need to present a token scoped to either the
|
||||||
|
"system" or a specific "project". See the section `Upgrade Considerations`_
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
See the section `Managing Octavia User Roles`_ for examples and advice on how
|
||||||
|
to apply these RBAC policies in production.
|
||||||
|
|
||||||
|
Legacy Admin or Owner Policy Override File
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
An alternate policy file has been provided in octavia/etc/policy called
|
An alternate policy file has been provided in octavia/etc/policy called
|
||||||
admin_or_owner-policy.yaml that removes the load-balancer RBAC role
|
admin_or_owner-policy.yaml that removes the load-balancer RBAC role
|
||||||
requirement. Please see the README.rst in that directory for more information.
|
requirement. Please see the README.rst in that directory for more information.
|
||||||
|
|
||||||
|
This will drop the role requirements to allow access to all with the "admin"
|
||||||
|
role or if the user is a member of the project that created the resource. All
|
||||||
|
users have access to the Octavia API to create and manage load balancers
|
||||||
|
under their project.
|
||||||
|
|
||||||
|
OpenStack Default Roles Policy Override File
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
An alternate policy file has been provided in octavia/etc/policy called
|
||||||
|
keystone_default_roles-policy.yaml that removes the load-balancer RBAC role
|
||||||
|
requirement. Please see the README.rst in that directory for more information.
|
||||||
|
|
||||||
|
This policy will honor the following `Keystone Default Roles`_ in the Octavia
|
||||||
|
API:
|
||||||
|
|
||||||
|
* System scoped - Admin
|
||||||
|
* System scoped - Reader
|
||||||
|
* Project scoped - Reader
|
||||||
|
* Project scoped - Member
|
||||||
|
|
||||||
|
Managing Octavia User Roles
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
User and group roles are managed through the Keystone (identity) project.
|
||||||
|
|
||||||
|
A role can be added to a user with the following command::
|
||||||
|
|
||||||
|
openstack role add --project <project name or id> --user <user name or id> <role>
|
||||||
|
|
||||||
|
An example where user "jane", in the "engineering" project, gets a new role
|
||||||
|
"load-balancer_member"::
|
||||||
|
|
||||||
|
openstack role add --project engineering --user jane load-balancer_member
|
||||||
|
|
||||||
|
Keystone Group Roles
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Roles can also be assigned to `Keystone groups
|
||||||
|
<https://docs.openstack.org/keystone/latest/admin/identity-concepts.html>`_.
|
||||||
|
This can simplify the management of user roles greatly.
|
||||||
|
|
||||||
|
For example, your cloud may have a "users" group defined in Keystone. This
|
||||||
|
group is set up to have all of the regular users of your cloud as a member.
|
||||||
|
If you want all of your users to have access to the load balancing service
|
||||||
|
Octavia, you could add the "load-balancer_member" role to the "users" group::
|
||||||
|
|
||||||
|
openstack role add --domain default --group users load-balancer_member
|
||||||
|
|
||||||
|
Upgrade Considerations
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Starting with the Wallaby release of Octavia, Keystone token scopes and
|
||||||
|
default roles can be enforced. By default, in the Wallaby release, `Oslo Policy
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest>`_
|
||||||
|
will not be enforcing these new roles and scopes. However, at some point in the
|
||||||
|
future they may become the default. You may want to enable them now to be ready
|
||||||
|
for the later transition. This section will describe those settings.
|
||||||
|
|
||||||
|
The Oslo Policy project defines two configuration settings, among others, that
|
||||||
|
can be set in the Octavia configuration file to influence how policies are
|
||||||
|
handled in the Octavia API. Those two settings are `enforce_scope
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_scope>`_ and `enforce_new_defaults
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_new_defaults>`_.
|
||||||
|
|
||||||
|
[oslo_policy] enforce_scope
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Keystone has introduced the concept of `token scopes
|
||||||
|
<https://docs.openstack.org/keystone/latest/admin/tokens-overview.html#authorization-scopes>`_.
|
||||||
|
Currently, Oslo Policy defaults to not enforce the scope validation of a
|
||||||
|
token for backward compatibility reasons.
|
||||||
|
|
||||||
|
The Octavia API supports enforcing the Keystone token scopes as of the Wallaby
|
||||||
|
release. If you are ready to start enforcing the Keystone token scope in the
|
||||||
|
Octavia API you can add the following setting to your Octavia API configuration
|
||||||
|
file::
|
||||||
|
|
||||||
|
[oslo_policy]
|
||||||
|
enforce_scope = True
|
||||||
|
|
||||||
|
Currently the primary effect of this setting is to allow a system scoped
|
||||||
|
admin token when performing administrative API calls to the Octavia API.
|
||||||
|
It will also allow system scoped reader tokens to have the equivalent of the
|
||||||
|
load-balancer_global_observer role.
|
||||||
|
|
||||||
|
The Octavia API already enforces the project scoping in Keystone tokens.
|
||||||
|
|
||||||
|
[oslo_policy] enforce_new_defaults
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The Octavia Wallaby release added support for `Keystone Default Roles`_ in
|
||||||
|
the default policies. The previous Octavia Advanced RBAC policies have now
|
||||||
|
been deprecated in favor of the new policies requiring one of the new
|
||||||
|
`Keystone Default Roles`_.
|
||||||
|
Currently, Oslo Policy defaults to using the deprecated policies that do not
|
||||||
|
require the new `Keystone Default Roles`_ for backward compatibility.
|
||||||
|
|
||||||
|
The Octavia API supports requiring these new `Keystone Default Roles`_ as of
|
||||||
|
the Wallaby release. If you are ready to start requiring these roles you can
|
||||||
|
enable the new policies by adding the following setting to your Octavia API
|
||||||
|
configuration file::
|
||||||
|
|
||||||
|
[oslo_policy]
|
||||||
|
enforce_new_defaults = True
|
||||||
|
|
||||||
|
When the new default policies are enabled in the Octavia API, users with the
|
||||||
|
load-balancer:observer role will also require the Keystone default role of
|
||||||
|
"role:reader". Users with the load-balancer:member role will also require
|
||||||
|
the Keystone default role of "role:member".
|
||||||
|
|
||||||
Sample File Generation
|
Sample File Generation
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
@ -76,7 +212,109 @@ in effective policy::
|
|||||||
oslopolicy-list-redundant
|
oslopolicy-list-redundant
|
||||||
--config-file etc/policy/octavia-policy-generator.conf
|
--config-file etc/policy/octavia-policy-generator.conf
|
||||||
|
|
||||||
Default Octavia Policies
|
Default Octavia Policies - API Effective Rules
|
||||||
------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
|
This section will list the RBAC rules the Octavia API will use followed by a
|
||||||
|
list of the roles that will be allowed access.
|
||||||
|
|
||||||
|
Without `enforce_scope
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_scope>`_ and `enforce_new_defaults
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_new_defaults>`_:
|
||||||
|
|
||||||
|
* load-balancer:read
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* load-balancer_member and <project member>
|
||||||
|
* load-balancer_observer and <project member>
|
||||||
|
* role:admin
|
||||||
|
|
||||||
|
* load-balancer:read-global
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* role:admin
|
||||||
|
|
||||||
|
* load-balancer:write
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_member and <project member>
|
||||||
|
* role:admin
|
||||||
|
|
||||||
|
* load-balancer:read-quota
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* load-balancer_member and <project member>
|
||||||
|
* load-balancer_observer and <project member>
|
||||||
|
* load-balancer_quota_admin
|
||||||
|
* role:admin
|
||||||
|
|
||||||
|
* load-balancer:read-quota-global
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* load-balancer_quota_admin
|
||||||
|
* role:admin
|
||||||
|
|
||||||
|
* load-balancer:write-quota
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_quota_admin
|
||||||
|
* role:admin
|
||||||
|
|
||||||
|
With `enforce_scope
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_scope>`_ and `enforce_new_defaults
|
||||||
|
<https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_new_defaults>`_:
|
||||||
|
|
||||||
|
* load-balancer:read
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* load-balancer_member and <project member> and role:member
|
||||||
|
* load-balancer_observer and <project member> and role:reader
|
||||||
|
* role:admin and system_scope:all
|
||||||
|
* role:reader and system_scope:all
|
||||||
|
|
||||||
|
* load-balancer:read-global
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* role:admin and system_scope:all
|
||||||
|
* role:reader and system_scope:all
|
||||||
|
|
||||||
|
* load-balancer:write
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_member and <project member> and role:member
|
||||||
|
* role:admin and system_scope:all
|
||||||
|
|
||||||
|
* load-balancer:read-quota
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* load-balancer_member and <project member> and role:member
|
||||||
|
* load-balancer_observer and <project member> and role:reader
|
||||||
|
* load-balancer_quota_admin
|
||||||
|
* role:admin and system_scope:all
|
||||||
|
* role:reader and system_scope:all
|
||||||
|
|
||||||
|
* load-balancer:read-quota-global
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_global_observer
|
||||||
|
* load-balancer_quota_admin
|
||||||
|
* role:admin and system_scope:all
|
||||||
|
* role:reader and system_scope:all
|
||||||
|
|
||||||
|
* load-balancer:write-quota
|
||||||
|
|
||||||
|
* load-balancer_admin
|
||||||
|
* load-balancer_quota_admin
|
||||||
|
* role:admin and system_scope:all
|
||||||
|
|
||||||
|
Default Octavia Policies - Generated From The Octavia Code
|
||||||
|
----------------------------------------------------------
|
||||||
|
|
||||||
.. literalinclude:: _static/octavia.policy.yaml.sample
|
.. literalinclude:: _static/octavia.policy.yaml.sample
|
||||||
|
@ -5,6 +5,8 @@ Octavia Sample Policy Files
|
|||||||
The sample policy.yaml files described here can be copied into
|
The sample policy.yaml files described here can be copied into
|
||||||
/etc/octavia/policy.yaml to override the default RBAC policy for Octavia.
|
/etc/octavia/policy.yaml to override the default RBAC policy for Octavia.
|
||||||
|
|
||||||
|
See the `Octavia Policy Guide <https://docs.openstack.org/octavia/latest/configuration/policy.html>`_ for more information about these policy override files.
|
||||||
|
|
||||||
admin_or_owner-policy.yaml
|
admin_or_owner-policy.yaml
|
||||||
--------------------------
|
--------------------------
|
||||||
This policy file disables the requirement for load-balancer service users to
|
This policy file disables the requirement for load-balancer service users to
|
||||||
@ -12,3 +14,15 @@ have one of the load-balancer:* roles. It provides a similar policy to
|
|||||||
legacy OpenStack policies where any user or admin has access to load-balancer
|
legacy OpenStack policies where any user or admin has access to load-balancer
|
||||||
resources that they own. Users with the admin role has access to all
|
resources that they own. Users with the admin role has access to all
|
||||||
load-balancer resources, whether they own them or not.
|
load-balancer resources, whether they own them or not.
|
||||||
|
|
||||||
|
keystone_default_roles-policy.yaml
|
||||||
|
----------------------------------
|
||||||
|
This policy file disables the requirement for load-balancer service users to
|
||||||
|
have one of the load-balancer:* roles.
|
||||||
|
|
||||||
|
This policy will honor the following Keystone default roles in the Octavia API:
|
||||||
|
|
||||||
|
* System scoped - Admin
|
||||||
|
* System scoped - Reader
|
||||||
|
* Project scoped - Reader
|
||||||
|
* Project scoped - Member
|
||||||
|
37
etc/policy/keystone_default_roles-policy.yaml
Normal file
37
etc/policy/keystone_default_roles-policy.yaml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# This policy YAML file will revert the Octavia API to follow the keystone
|
||||||
|
# "default role" RBAC policies.
|
||||||
|
#
|
||||||
|
# The [oslo_policy] enforce_scope and enforce_new_defaults must be True.
|
||||||
|
#
|
||||||
|
# Users will not be required to be a member of the load-balancer_* roles
|
||||||
|
# to take action on Octavia resources.
|
||||||
|
# Keystone token scoping and "default roles"/personas will still be enforced.
|
||||||
|
|
||||||
|
# Role Rules
|
||||||
|
"system_admin": "role:admin and system_scope:all"
|
||||||
|
"system_reader": "role:reader and system_scope:all"
|
||||||
|
"project_reader": "role:reader and project_id:%(project_id)s"
|
||||||
|
"project_member": "role:member and project_id:%(project_id)s"
|
||||||
|
|
||||||
|
"context_is_admin": "role:admin and system_scope:all"
|
||||||
|
|
||||||
|
# API Rules
|
||||||
|
"load-balancer:admin": "is_admin:True or
|
||||||
|
rule:system_admin or
|
||||||
|
role:load-balancer_admin"
|
||||||
|
|
||||||
|
"load-balancer:read": "is_admin:True or
|
||||||
|
rule:system_reader or
|
||||||
|
rule:project_reader"
|
||||||
|
|
||||||
|
"load-balancer:read-global": "is_admin:True or rule:system_reader"
|
||||||
|
|
||||||
|
"load-balancer:write": "is_admin:True or rule:project_member"
|
||||||
|
|
||||||
|
"load-balancer:read-quota": "is_admin:True or
|
||||||
|
rule:system_reader or
|
||||||
|
rule:project_reader"
|
||||||
|
|
||||||
|
"load-balancer:read-quota-global": "is_admin:True or rule:system_reader"
|
||||||
|
|
||||||
|
"load-balancer:write-quota": "is_admin:True"
|
@ -79,14 +79,14 @@ os-service-types==1.2.0
|
|||||||
osc-lib==1.10.0
|
osc-lib==1.10.0
|
||||||
oslo.cache==1.29.0
|
oslo.cache==1.29.0
|
||||||
oslo.concurrency==3.26.0
|
oslo.concurrency==3.26.0
|
||||||
oslo.config==5.2.0
|
oslo.config==6.8.0
|
||||||
oslo.context==2.22.0
|
oslo.context==2.22.0
|
||||||
oslo.db==8.4.0
|
oslo.db==8.4.0
|
||||||
oslo.i18n==3.20.0
|
oslo.i18n==3.20.0
|
||||||
oslo.log==4.3.0
|
oslo.log==4.3.0
|
||||||
oslo.messaging==12.4.0
|
oslo.messaging==12.4.0
|
||||||
oslo.middleware==4.0.1
|
oslo.middleware==4.0.1
|
||||||
oslo.policy==2.1.0
|
oslo.policy==3.6.2
|
||||||
oslo.reports==1.18.0
|
oslo.reports==1.18.0
|
||||||
oslo.serialization==2.28.1
|
oslo.serialization==2.28.1
|
||||||
oslo.service==1.30.0
|
oslo.service==1.30.0
|
||||||
@ -130,14 +130,14 @@ python-neutronclient==6.7.0
|
|||||||
python-novaclient==9.1.0
|
python-novaclient==9.1.0
|
||||||
python-subunit==1.0.0
|
python-subunit==1.0.0
|
||||||
pytz==2018.3
|
pytz==2018.3
|
||||||
PyYAML==3.12
|
PyYAML==5.1
|
||||||
redis==2.10.0
|
redis==2.10.0
|
||||||
repoze.lru==0.7
|
repoze.lru==0.7
|
||||||
requests==2.14.2
|
requests==2.18.4
|
||||||
requests-mock==1.2.0
|
requests-mock==1.2.0
|
||||||
requestsexceptions==1.4.0
|
requestsexceptions==1.4.0
|
||||||
restructuredtext-lint==1.1.3
|
restructuredtext-lint==1.1.3
|
||||||
rfc3986==0.3.1
|
rfc3986==1.2.0
|
||||||
Routes==2.4.1
|
Routes==2.4.1
|
||||||
setproctitle==1.1.10
|
setproctitle==1.1.10
|
||||||
simplegeneric==0.8.1
|
simplegeneric==0.8.1
|
||||||
|
@ -731,6 +731,7 @@ DEFAULT_PAGE_SIZE = 1000
|
|||||||
|
|
||||||
# RBAC
|
# RBAC
|
||||||
LOADBALANCER_API = 'os_load-balancer_api'
|
LOADBALANCER_API = 'os_load-balancer_api'
|
||||||
|
|
||||||
RULE_API_ADMIN = 'rule:load-balancer:admin'
|
RULE_API_ADMIN = 'rule:load-balancer:admin'
|
||||||
RULE_API_READ = 'rule:load-balancer:read'
|
RULE_API_READ = 'rule:load-balancer:read'
|
||||||
RULE_API_READ_GLOBAL = 'rule:load-balancer:read-global'
|
RULE_API_READ_GLOBAL = 'rule:load-balancer:read-global'
|
||||||
@ -738,6 +739,7 @@ RULE_API_WRITE = 'rule:load-balancer:write'
|
|||||||
RULE_API_READ_QUOTA = 'rule:load-balancer:read-quota'
|
RULE_API_READ_QUOTA = 'rule:load-balancer:read-quota'
|
||||||
RULE_API_READ_QUOTA_GLOBAL = 'rule:load-balancer:read-quota-global'
|
RULE_API_READ_QUOTA_GLOBAL = 'rule:load-balancer:read-quota-global'
|
||||||
RULE_API_WRITE_QUOTA = 'rule:load-balancer:write-quota'
|
RULE_API_WRITE_QUOTA = 'rule:load-balancer:write-quota'
|
||||||
|
|
||||||
RBAC_LOADBALANCER = '{}:loadbalancer:'.format(LOADBALANCER_API)
|
RBAC_LOADBALANCER = '{}:loadbalancer:'.format(LOADBALANCER_API)
|
||||||
RBAC_LISTENER = '{}:listener:'.format(LOADBALANCER_API)
|
RBAC_LISTENER = '{}:listener:'.format(LOADBALANCER_API)
|
||||||
RBAC_POOL = '{}:pool:'.format(LOADBALANCER_API)
|
RBAC_POOL = '{}:pool:'.format(LOADBALANCER_API)
|
||||||
@ -756,6 +758,7 @@ RBAC_FLAVOR_PROFILE = '{}:flavor-profile:'.format(LOADBALANCER_API)
|
|||||||
RBAC_AVAILABILITY_ZONE = '{}:availability-zone:'.format(LOADBALANCER_API)
|
RBAC_AVAILABILITY_ZONE = '{}:availability-zone:'.format(LOADBALANCER_API)
|
||||||
RBAC_AVAILABILITY_ZONE_PROFILE = '{}:availability-zone-profile:'.format(
|
RBAC_AVAILABILITY_ZONE_PROFILE = '{}:availability-zone-profile:'.format(
|
||||||
LOADBALANCER_API)
|
LOADBALANCER_API)
|
||||||
|
|
||||||
RBAC_POST = 'post'
|
RBAC_POST = 'post'
|
||||||
RBAC_PUT = 'put'
|
RBAC_PUT = 'put'
|
||||||
RBAC_PUT_CONFIG = 'put_config'
|
RBAC_PUT_CONFIG = 'put_config'
|
||||||
@ -768,6 +771,16 @@ RBAC_GET_DEFAULTS = 'get_defaults'
|
|||||||
RBAC_GET_STATS = 'get_stats'
|
RBAC_GET_STATS = 'get_stats'
|
||||||
RBAC_GET_STATUS = 'get_status'
|
RBAC_GET_STATUS = 'get_status'
|
||||||
|
|
||||||
|
RBAC_SCOPE_PROJECT = 'project'
|
||||||
|
RBAC_SCOPE_SYSTEM = 'system'
|
||||||
|
|
||||||
|
RBAC_ROLES_DEPRECATED_REASON = (
|
||||||
|
'The Octavia API now requires the OpenStack default roles and scoped '
|
||||||
|
'tokens. '
|
||||||
|
'See https://docs.openstack.org/octavia/latest/configuration/policy.html '
|
||||||
|
'and https://docs.openstack.org/keystone/latest/contributor/'
|
||||||
|
'services.html#reusable-default-roles for more information.')
|
||||||
|
|
||||||
# PROVIDERS
|
# PROVIDERS
|
||||||
OCTAVIA = 'octavia'
|
OCTAVIA = 'octavia'
|
||||||
AMPHORAV2 = 'amphorav2'
|
AMPHORAV2 = 'amphorav2'
|
||||||
|
@ -125,7 +125,16 @@ class Policy(oslo_policy.Enforcer):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
credentials = context.to_dict()
|
credentials = context.to_dict()
|
||||||
return self.enforce('context_is_admin', credentials, credentials)
|
result = False
|
||||||
|
try:
|
||||||
|
result = self.enforce('context_is_admin', credentials, credentials)
|
||||||
|
except oslo_policy.InvalidScope as e:
|
||||||
|
# This will happen if the token being used is not system scoped
|
||||||
|
# which is required for the admin roles when scope checking is
|
||||||
|
# enabled.
|
||||||
|
LOG.warning(str(e))
|
||||||
|
return False
|
||||||
|
return result
|
||||||
|
|
||||||
def get_rules(self):
|
def get_rules(self):
|
||||||
return self.rules
|
return self.rules
|
||||||
|
@ -10,9 +10,61 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from oslo_log import versionutils
|
||||||
from oslo_policy import policy
|
from oslo_policy import policy
|
||||||
|
|
||||||
|
from octavia.common import constants
|
||||||
|
|
||||||
|
deprecated_context_is_admin = policy.DeprecatedRule(
|
||||||
|
name='context_is_admin',
|
||||||
|
check_str='role:admin or '
|
||||||
|
'role:load-balancer_admin'
|
||||||
|
)
|
||||||
|
deprecated_observer_and_owner = policy.DeprecatedRule(
|
||||||
|
name='load-balancer:observer_and_owner',
|
||||||
|
check_str='role:load-balancer_observer and '
|
||||||
|
'rule:load-balancer:owner'
|
||||||
|
)
|
||||||
|
deprecated_member_and_owner = policy.DeprecatedRule(
|
||||||
|
name='load-balancer:member_and_owner',
|
||||||
|
check_str='role:load-balancer_member and '
|
||||||
|
'rule:load-balancer:owner'
|
||||||
|
)
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
|
|
||||||
|
# OpenStack wide scoped rules
|
||||||
|
|
||||||
|
# System scoped Administrator
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='system-admin',
|
||||||
|
check_str='role:admin and '
|
||||||
|
'system_scope:all',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
|
# System scoped Reader
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='system-reader',
|
||||||
|
check_str='role:reader and '
|
||||||
|
'system_scope:all',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
|
# Project scoped Member
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='project-member',
|
||||||
|
check_str='role:member and '
|
||||||
|
'project_id:%(project_id)s',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT]),
|
||||||
|
|
||||||
|
# Project scoped Reader
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='project-reader',
|
||||||
|
check_str='role:reader and '
|
||||||
|
'project_id:%(project_id)s',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT]),
|
||||||
|
|
||||||
|
# Octavia specific Advanced RBAC rules
|
||||||
|
|
||||||
# The default is to not allow access unless the auth_strategy is 'noauth'.
|
# The default is to not allow access unless the auth_strategy is 'noauth'.
|
||||||
# Users must be a member of one of the following roles to have access to
|
# Users must be a member of one of the following roles to have access to
|
||||||
# the load-balancer API:
|
# the load-balancer API:
|
||||||
@ -25,66 +77,107 @@ rules = [
|
|||||||
# role:load-balancer_member
|
# role:load-balancer_member
|
||||||
# User has access to load-balancer read and write APIs
|
# User has access to load-balancer read and write APIs
|
||||||
# role:load-balancer_admin
|
# role:load-balancer_admin
|
||||||
# User is considered an admin for all load-balnacer APIs including
|
# User is considered an admin for all load-balancer APIs including
|
||||||
# resources owned by others.
|
# resources owned by others.
|
||||||
# role:admin
|
# role:admin and system_scope:all
|
||||||
# User is admin to all APIs
|
# User is admin to all service APIs, including Octavia.
|
||||||
|
|
||||||
policy.RuleDefault('context_is_admin',
|
policy.RuleDefault(
|
||||||
'role:admin or role:load-balancer_admin'),
|
name='context_is_admin',
|
||||||
|
check_str='role:load-balancer_admin or '
|
||||||
|
'rule:system-admin',
|
||||||
|
deprecated_rule=deprecated_context_is_admin,
|
||||||
|
deprecated_reason=constants.RBAC_ROLES_DEPRECATED_REASON,
|
||||||
|
deprecated_since=versionutils.deprecated.WALLABY,
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
# Note: 'is_admin:True' is a policy rule that takes into account the
|
# Note: 'is_admin:True' is a policy rule that takes into account the
|
||||||
# auth_strategy == noauth configuration setting.
|
# auth_strategy == noauth configuration setting.
|
||||||
# It is equivalent to 'rule:context_is_admin or {auth_strategy == noauth}'
|
# It is equivalent to 'rule:context_is_admin or {auth_strategy == noauth}'
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:owner', 'project_id:%(project_id)s'),
|
policy.RuleDefault(
|
||||||
|
name='load-balancer:owner',
|
||||||
|
check_str='project_id:%(project_id)s',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT]),
|
||||||
|
|
||||||
# API access roles
|
# API access roles
|
||||||
policy.RuleDefault('load-balancer:admin', 'is_admin:True or '
|
policy.RuleDefault(
|
||||||
'role:admin or '
|
name='load-balancer:observer_and_owner',
|
||||||
'role:load-balancer_admin'),
|
check_str='role:load-balancer_observer and '
|
||||||
|
'rule:project-reader',
|
||||||
|
deprecated_rule=deprecated_observer_and_owner,
|
||||||
|
deprecated_reason=constants.RBAC_ROLES_DEPRECATED_REASON,
|
||||||
|
deprecated_since=versionutils.deprecated.WALLABY,
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT]),
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:observer_and_owner',
|
policy.RuleDefault(
|
||||||
'role:load-balancer_observer and '
|
name='load-balancer:global_observer',
|
||||||
'rule:load-balancer:owner'),
|
check_str='role:load-balancer_global_observer or '
|
||||||
|
'rule:system-reader',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:global_observer',
|
policy.RuleDefault(
|
||||||
'role:load-balancer_global_observer'),
|
name='load-balancer:member_and_owner',
|
||||||
|
check_str='role:load-balancer_member and '
|
||||||
policy.RuleDefault('load-balancer:member_and_owner',
|
'rule:project-member',
|
||||||
'role:load-balancer_member and '
|
deprecated_rule=deprecated_member_and_owner,
|
||||||
'rule:load-balancer:owner'),
|
deprecated_reason=constants.RBAC_ROLES_DEPRECATED_REASON,
|
||||||
|
deprecated_since=versionutils.deprecated.WALLABY,
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT]),
|
||||||
|
|
||||||
# API access methods
|
# API access methods
|
||||||
policy.RuleDefault('load-balancer:read',
|
|
||||||
'rule:load-balancer:observer_and_owner or '
|
|
||||||
'rule:load-balancer:global_observer or '
|
|
||||||
'rule:load-balancer:member_and_owner or '
|
|
||||||
'rule:load-balancer:admin'),
|
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:read-global',
|
policy.RuleDefault(
|
||||||
'rule:load-balancer:global_observer or '
|
name='load-balancer:admin',
|
||||||
'rule:load-balancer:admin'),
|
check_str='is_admin:True or '
|
||||||
|
'role:load-balancer_admin or '
|
||||||
|
'rule:system-admin',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:write',
|
policy.RuleDefault(
|
||||||
'rule:load-balancer:member_and_owner or '
|
name='load-balancer:read',
|
||||||
'rule:load-balancer:admin'),
|
check_str='rule:load-balancer:observer_and_owner or '
|
||||||
|
'rule:load-balancer:global_observer or '
|
||||||
|
'rule:load-balancer:member_and_owner or '
|
||||||
|
'rule:load-balancer:admin',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT,
|
||||||
|
constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:read-quota',
|
policy.RuleDefault(
|
||||||
'rule:load-balancer:observer_and_owner or '
|
name='load-balancer:read-global',
|
||||||
'rule:load-balancer:global_observer or '
|
check_str='rule:load-balancer:global_observer or '
|
||||||
'rule:load-balancer:member_and_owner or '
|
'rule:load-balancer:admin',
|
||||||
'role:load-balancer_quota_admin or '
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
'rule:load-balancer:admin'),
|
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:read-quota-global',
|
policy.RuleDefault(
|
||||||
'rule:load-balancer:global_observer or '
|
name='load-balancer:write',
|
||||||
'role:load-balancer_quota_admin or '
|
check_str='rule:load-balancer:member_and_owner or '
|
||||||
'rule:load-balancer:admin'),
|
'rule:load-balancer:admin',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT,
|
||||||
|
constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
policy.RuleDefault('load-balancer:write-quota',
|
policy.RuleDefault(
|
||||||
'role:load-balancer_quota_admin or '
|
name='load-balancer:read-quota',
|
||||||
'rule:load-balancer:admin'),
|
check_str='rule:load-balancer:observer_and_owner or '
|
||||||
|
'rule:load-balancer:global_observer or '
|
||||||
|
'rule:load-balancer:member_and_owner or '
|
||||||
|
'role:load-balancer_quota_admin or '
|
||||||
|
'rule:load-balancer:admin',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_PROJECT,
|
||||||
|
constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='load-balancer:read-quota-global',
|
||||||
|
check_str='rule:load-balancer:global_observer or '
|
||||||
|
'role:load-balancer_quota_admin or '
|
||||||
|
'rule:load-balancer:admin',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
|
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='load-balancer:write-quota',
|
||||||
|
check_str='role:load-balancer_quota_admin or '
|
||||||
|
'rule:load-balancer:admin',
|
||||||
|
scope_types=[constants.RBAC_SCOPE_SYSTEM]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,11 +162,23 @@ class PolicyTestCase(base.TestCase):
|
|||||||
def test_check_is_admin_fail(self):
|
def test_check_is_admin_fail(self):
|
||||||
self.assertFalse(policy.get_enforcer().check_is_admin(self.context))
|
self.assertFalse(policy.get_enforcer().check_is_admin(self.context))
|
||||||
|
|
||||||
|
# TODO(johnsom) When oslo.policy changes "enforce_new_defaults" to True
|
||||||
|
# this test will fail as "system_scope:all" will be required.
|
||||||
|
# This test and the conditional in common/policy.py can then
|
||||||
|
# be removed in favor of test_check_is_admin_new_defaults().
|
||||||
def test_check_is_admin(self):
|
def test_check_is_admin(self):
|
||||||
self.context = context.Context('admin', 'fake', roles=['AdMiN'])
|
self.context = context.Context('admin', 'fake', roles=['AdMiN'])
|
||||||
|
|
||||||
self.assertTrue(policy.get_enforcer().check_is_admin(self.context))
|
self.assertTrue(policy.get_enforcer().check_is_admin(self.context))
|
||||||
|
|
||||||
|
def test_check_is_admin_new_defaults(self):
|
||||||
|
conf = oslo_fixture.Config(config.cfg.CONF)
|
||||||
|
conf.config(group="oslo_policy", enforce_new_defaults=True)
|
||||||
|
self.context = context.Context('admin', 'fake', roles=['AdMiN'],
|
||||||
|
system_scope='all')
|
||||||
|
|
||||||
|
self.assertTrue(policy.get_enforcer().check_is_admin(self.context))
|
||||||
|
|
||||||
def test_get_enforcer(self):
|
def test_get_enforcer(self):
|
||||||
self.assertTrue(isinstance(policy.get_no_context_enforcer(),
|
self.assertTrue(isinstance(policy.get_no_context_enforcer(),
|
||||||
oslo_policy.Enforcer))
|
oslo_policy.Enforcer))
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support for keystone default roles and system token scopes.
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Legacy Octavia Advanced RBAC policies will continue to function as before
|
||||||
|
as long as the [oslo_policy] enforce_scope = False and
|
||||||
|
enforce_new_defaults = False settings are present (this is the current
|
||||||
|
oslo.policy default). However, we highly recommend you update your
|
||||||
|
user roles to follow the new keystone default roles and start using scoped
|
||||||
|
tokens as appropriate.
|
||||||
|
See the `Octavia Policies
|
||||||
|
<https://docs.openstack.org/octavia/latest/configuration/policy.html>`_
|
||||||
|
administration guide for more information.
|
||||||
|
deprecations:
|
||||||
|
- |
|
||||||
|
Legacy Octavia Advanced RBAC policies without the keystone default roles
|
||||||
|
and/or token scoping are deprecated as of the Wallaby release.
|
||||||
|
The oslo.policy project may change the default settings requiring the
|
||||||
|
keystone default roles and scoped tokens in a future release. Please see
|
||||||
|
the upgrade section in these release notes and the `Octavia Policies
|
||||||
|
<https://docs.openstack.org/octavia/latest/configuration/policy.html>`_
|
||||||
|
administration guide for more information.
|
@ -8,21 +8,21 @@ pbr>=3.1.1 # Apache-2.0
|
|||||||
SQLAlchemy>=1.2.19 # MIT
|
SQLAlchemy>=1.2.19 # MIT
|
||||||
SQLAlchemy-Utils>=0.30.11
|
SQLAlchemy-Utils>=0.30.11
|
||||||
futurist>=1.2.0 # Apache-2.0
|
futurist>=1.2.0 # Apache-2.0
|
||||||
requests>=2.14.2 # Apache-2.0
|
requests>=2.18.4 # Apache-2.0
|
||||||
rfc3986>=0.3.1 # Apache-2.0
|
rfc3986>=1.2.0 # Apache-2.0
|
||||||
keystoneauth1>=3.4.0 # Apache-2.0
|
keystoneauth1>=3.4.0 # Apache-2.0
|
||||||
keystonemiddleware>=4.17.0 # Apache-2.0
|
keystonemiddleware>=4.17.0 # Apache-2.0
|
||||||
python-neutronclient>=6.7.0 # Apache-2.0
|
python-neutronclient>=6.7.0 # Apache-2.0
|
||||||
WebOb>=1.8.2 # MIT
|
WebOb>=1.8.2 # MIT
|
||||||
stevedore>=1.20.0 # Apache-2.0
|
stevedore>=1.20.0 # Apache-2.0
|
||||||
oslo.config>=5.2.0 # Apache-2.0
|
oslo.config>=6.8.0 # Apache-2.0
|
||||||
oslo.context>=2.22.0 # Apache-2.0
|
oslo.context>=2.22.0 # Apache-2.0
|
||||||
oslo.db[mysql]>=8.4.0 # Apache-2.0
|
oslo.db[mysql]>=8.4.0 # Apache-2.0
|
||||||
oslo.i18n>=3.20.0 # Apache-2.0
|
oslo.i18n>=3.20.0 # Apache-2.0
|
||||||
oslo.log>=4.3.0 # Apache-2.0
|
oslo.log>=4.3.0 # Apache-2.0
|
||||||
oslo.messaging>=12.4.0 # Apache-2.0
|
oslo.messaging>=12.4.0 # Apache-2.0
|
||||||
oslo.middleware>=4.0.1 # Apache-2.0
|
oslo.middleware>=4.0.1 # Apache-2.0
|
||||||
oslo.policy>=2.1.0 # Apache-2.0
|
oslo.policy>=3.6.2 # Apache-2.0
|
||||||
oslo.reports>=1.18.0 # Apache-2.0
|
oslo.reports>=1.18.0 # Apache-2.0
|
||||||
oslo.serialization>=2.28.1 # Apache-2.0
|
oslo.serialization>=2.28.1 # Apache-2.0
|
||||||
oslo.upgradecheck>=0.1.0 # Apache-2.0
|
oslo.upgradecheck>=0.1.0 # Apache-2.0
|
||||||
|
Loading…
Reference in New Issue
Block a user