identity:list_services doesn't obey policy.yaml when scope enforcement is enabled

Bug #2017056 reported by Dmitry Veber
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Magnum
New
Undecided
Unassigned
OpenStack Identity (keystone)
New
Undecided
Douglas Mendizábal

Bug Description

Using Openstack Xena with the following setting enabled in keystone:
[oslo_policy]
enforce_scope = true

I have two openstack cli sessions:
- system_admin: admin user scoped to system:all
- project_admin: admin user scoped to admin project

At first, I don't have list_services defined in policy.yaml, so it defaults to this:
- "identity:list_services": "role:reader and system_scope:all"

As expected, system_admin can execute "openstack service list", and project_admin gets a Forbidden

I then change the policy.yaml definition to this, with the intent to remove the requirement for system:all ... which should allow the project_admin to run the command:
- "identity:list_services": "role:reader"

I run "openstack service list" again from both of the above cli sessions, and the result is the same as before. system_admin gets the list, and project_admin gets forbidden

I took a step further, and tried to remove permission requirements entirely ...
- "identity:list_services": ""

I run the command again, and the result is the same ... project_admin continues to get forbidden, which is odd because the policy no longer specifies any role requirements at all

At first I thought that perhaps policy.yaml changes are not registering in keystone for some reason. I ruled this out by temporarily breaking the permissions for another command that project_admin can use, and that worked.

This behavior looks like a bug at first glance, but I see no references to any rbac fixes in the release notes for any of the versions after Xena, so i have no confidence that an upgrade will affect this issue. In any case, i don't have a quick way to test this right now

Impact:
Why am I trying to change the permission of this command at all? The answer is Magnum. When I try to delete a cluster (that was created prior to enabling the rbac enforcement), magnum fails because it is unable to run the list_services command due to the permission error
- Unfortunately, magnum MUST be run in the project scope as clusters are tied to projects, and the catalog lacks orchestration endpoints when you are system_scoped

This puts me in a catch-22. I can't run magnum commands in system scope because orchestration endpoints are absent in the catalog, and I can't run magnum commands in project scope because of this rbac issue.

I was hoping to work around it by changing the permissions of the service command

I have attached many configs to this ticket, which should give you a sense of my openstack deployment. Any values/files missing should be assumed to be set to whatever the default is

Revision history for this message
Dmitry Veber (night-raven1337) wrote :
David Wilde (dave-wilde)
Changed in keystone:
assignee: nobody → Douglas Mendizábal (dougmendizabal)
Revision history for this message
Andrew Bogott (andrewbogott) wrote :

I think this is a real bug.

I may be misreading the code, but it looks to me like the policy code checks the new rule from policy.yaml for auth but also does a separate scope check -- the scope check seems to only use the original rule from code rather than the rule from policy.yaml. So you can only override policies in policy.yaml as long as you don't modify the scope requirements.

This breaks quite a lot of things!

Revision history for this message
Andrew Bogott (andrewbogott) wrote :

I think the problematic code is in oslo_policy.policy.Enforcer.enforce():

                registered_rule = self.registered_rules.get(rule)
                if registered_rule and registered_rule.scope_types:
                    scope_valid = self._enforce_scope(creds, registered_rule,
                                                      do_raise=do_raise)
                    if not scope_valid:
                        return False

Regardless of what I override, registered_rule is:

    "identity:list_services": "role:reader and system_scope:all"

Of course elsewhere in the code it's testing the rule from yaml, it's only in that one place where it refers back to 'registered_rule' which apparently is not replaced from yaml.

So either that check is wrong, or something is wrong with how rules are registered in the first place.

summary: - identity:list_services doesn't obey policy.yaml when enforcement is
- enabled
+ identity:list_services doesn't obey policy.yaml when scope enforcement
+ is enabled
Revision history for this message
Ghanshyam Mann (ghanshyammann) wrote :

Actually, this is by design and the scope was never intended to be overridable. scope are hard-coded in code and we should not make them customizable via config. The main idea behind the scope of API policy is to provide the secure RBAC so that different scope users are not allowed to perform other user operations.

If any policy require to be allowed to access by system as well as project scope then it should be changed in code. We have many policy like that where we do allow project as well system scope user to allow access as per their check string.

Coming back to this issue, Keystone has implemented the system scope and made the keystone policy specific to system scope. Like this identity:list_services. But we faced many issues on system scope on service side, this doc[1] can give you more details about the issues we faced and then decided to drop the system scope from all services except ironic. And for ironic use case, keystone kept the system scope support.

To continue supporting the project scope users to access Keystone APIs, we have to change the Keystone policies to allow both system (for ironic deployment use case) and project (for rest of OpenStack deployment) scope. I am working on the changes and should push up for review soon which will solve this bug too.

[1] https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#the-issues-we-are-facing-with-scope-concept

Revision history for this message
Andrew Bogott (andrewbogott) wrote :

OK, I have a few questions!

#1 Just to confirm: the concept of system scope is being phased out for everything but ironic? So for example even though project-scoped tokens can't list services right now, they'll be able to again in a future release?

#2 This sample file[1] shows scope requirements being set in policy.yaml in very many places. What am I to make of that w/r/t you asserting here that scope can never be changed in that file?

#3 What is the currently recommended transition path to new policy models? I've now spent many many hours getting ready to switch 'enforce_scope' and 'enforce_new_defaults' to True but now I'm getting the impression that I should definitely NOT do that since everything will just change again in a future release... can you advise about how I should go forward? Will enforce_scope=False remain supported until this is sorted out? (The deprecation warnings imply otherwise!)

[1] https://docs.openstack.org/keystone/latest/configuration/samples/policy-yaml.html

Revision history for this message
Dmitry Veber (night-raven1337) wrote :

Can the team answer Andrews questions? It's been a while

Revision history for this message
Marcin Wilk (wilkmarcin) wrote (last edit ):

Following scenario works on my Yoga deployment:

Using following policy overrides in /etc/keystone/policy.json):

    "identity:list_services": "rule:admin_required",

where the 'admin_required' rule is as follows:

    "admin_required": "role:Admin",

When a user is assigned Admin role to a project scope, he is able to list services:
openstack role assignment list --user test1 --user-domain default --names
+--------+---------------+-------+------------------+--------+--------+-----------+
| Role | User | Group | Project | Domain | System | Inherited |
+--------+---------------+-------+------------------+--------+--------+-----------+
| member | test1@Default | | project1@Default | | | False |
| Admin | test1@Default | | project1@Default | | | False |
+--------+---------------+-------+------------------+--------+--------+-----------+

# as test1 user
env | grep OS_
OS_AUTH_URL=https://AA.BB.CC.DD:5000/v3
OS_PROJECT_NAME=project1
OS_PROJECT_DOMAIN_NAME=default
OS_USER_DOMAIN_NAME=default
OS_USERNAME=test1
OS_PASSWORD=*****************
OS_REGION_NAME=RegionOne
OS_IDENTITY_API_VERSION=3
OS_AUTH_VERSION=3
OS_AUTH_TYPE=password

# the test1 user is able to see only his project (as expected)
openstack project list
+----------------------------------+----------+
| ID | Name |
+----------------------------------+----------+
| 16825f957a194f8ab49427e1e4f5dfd1 | project1 |
+----------------------------------+----------+

# and test1 is able to list the services:
openstack service list
+----------------------------------+-----------+-----------+
| ID | Name | Type |
+----------------------------------+-----------+-----------+
| 0398a11c75484ab790a5a77397300c75 | neutron | network |
| 2c40704758284ff9ab0ff302cd2dc03c | cinderv3 | volumev3 |
| 70b58cc846a0400781f9232c1d1128c2 | keystone | identity |
| ad173bc15dc34f8f8eaeac98866d0bc6 | nova | compute |
| d0b3f192f0334ba69b46c5842636803a | glance | image |
| f0515ca5fc1f4b1999dee2f8e6ed1b2b | placement | placement |
+----------------------------------+-----------+-----------+

I see the same behaviour on my Ussuri deployment as well.
It's not the solution that suits all use cases but at least it is something available now.
Hope that helps in any way.
Kind regards,
Marcin

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.