User with creator role can delete his/her own secret and container
Modified policy and tests to verify this change. As per this change, user with 'creator' role can delete a secret or a container as long as that user has initially created that secret or container. There is still a difference between 'admin' role and 'creator' role behavior around delete operation. With this change, users with 'creator' role cannot delete any other user's secret/container in same project while user with 'admin' role can do that. Updated role docs to reflect this behavior. Change-Id: I53e5529ed34ac4acc76348ca0431cb3de7934b6d
This commit is contained in:
parent
e994d4dd91
commit
ce6336f393
@ -648,11 +648,24 @@ class WhenTestingSecretResource(BaseTestCase):
|
||||
project_id=self.external_project_id)
|
||||
|
||||
def test_should_raise_delete_secret(self):
|
||||
self._assert_fail_rbac([None, 'audit', 'observer', 'creator', 'bogus'],
|
||||
self._invoke_on_delete)
|
||||
"""A non-admin user cannot delete other user's secret.
|
||||
|
||||
User id is different from initial user who has created the secret.
|
||||
"""
|
||||
self._assert_fail_rbac([None, 'audit', 'observer', 'creator', 'bogus'],
|
||||
self._invoke_on_delete,
|
||||
user_id=self.user_id,
|
||||
project_id=self.external_project_id)
|
||||
|
||||
def test_should_pass_delete_secret_for_owner(self):
|
||||
"""Non-admin user can delete his/her own secret
|
||||
|
||||
Secret creator_id should match with token user to establish ownership.
|
||||
"""
|
||||
self._assert_pass_rbac(['creator'], self._invoke_on_delete,
|
||||
user_id=self.creator_user_id,
|
||||
project_id=self.external_project_id)
|
||||
|
||||
# @mock.patch.object(secrets.SecretController, 'get_acl_tuple',
|
||||
# return_value=(None, None))
|
||||
def _invoke_on_get(self):
|
||||
self.resource.on_get(self.req, self.resp)
|
||||
|
||||
@ -883,8 +896,24 @@ class WhenTestingContainerResource(BaseTestCase):
|
||||
project_id=self.external_project_id)
|
||||
|
||||
def test_should_raise_delete_container(self):
|
||||
"""A non-admin user cannot delete other user's container.
|
||||
|
||||
User id is different from initial user who has created the container.
|
||||
"""
|
||||
self._assert_fail_rbac([None, 'audit', 'observer', 'creator', 'bogus'],
|
||||
self._invoke_on_delete)
|
||||
self._invoke_on_delete,
|
||||
user_id=self.user_id,
|
||||
project_id=self.external_project_id)
|
||||
|
||||
def test_should_pass_delete_container_for_owner(self):
|
||||
"""Non-admin user can delete his/her own container
|
||||
|
||||
Container creator_id should match with token user to establish
|
||||
ownership.
|
||||
"""
|
||||
self._assert_pass_rbac(['creator'], self._invoke_on_delete,
|
||||
user_id=self.creator_user_id,
|
||||
project_id=self.external_project_id)
|
||||
|
||||
def _invoke_on_get(self):
|
||||
self.resource.on_get(self.req, self.resp)
|
||||
|
@ -104,6 +104,15 @@ if [[ "$ENABLED_SERVICES" =~ "barbican" ]]; then
|
||||
--user "$USER_ID" \
|
||||
--project "$PROJECT_A_ID" \
|
||||
"$ROLE_CREATOR_ID"
|
||||
# Adding second creator user in project_a
|
||||
USER_ID=$(openstack user create \
|
||||
--password "$PASSWORD" \
|
||||
--email "creator2_a@example.net" \
|
||||
"project_a_creator_2" -f value -c id)
|
||||
openstack role add \
|
||||
--user "$USER_ID" \
|
||||
--project "$PROJECT_A_ID" \
|
||||
"$ROLE_CREATOR_ID"
|
||||
#
|
||||
# Setup RBAC Observer of Project A
|
||||
#
|
||||
|
@ -278,6 +278,15 @@ function create_barbican_accounts {
|
||||
--user "$USER_ID" \
|
||||
--project "$PROJECT_A_ID" \
|
||||
"$ROLE_CREATOR_ID"
|
||||
# Adding second creator user in project_a
|
||||
USER_ID=$(openstack user create \
|
||||
--password "$PASSWORD" \
|
||||
--email "creator2_a@example.net" \
|
||||
"project_a_creator_2" -f value -c id)
|
||||
openstack role add \
|
||||
--user "$USER_ID" \
|
||||
--project "$PROJECT_A_ID" \
|
||||
"$ROLE_CREATOR_ID"
|
||||
#
|
||||
# Setup RBAC Observer of Project A
|
||||
#
|
||||
|
@ -5,8 +5,8 @@ Access Control
|
||||
Role Based Access Control (RBAC)
|
||||
--------------------------------
|
||||
|
||||
Like many other services, the Key Manager service supports the protection of
|
||||
its APIs by enforcing policy rules defined in a policy file. The Key Manager
|
||||
Like many other services, the Key Manager service supports the protection of its
|
||||
APIs by enforcing policy rules defined in a policy file. The Key Manager
|
||||
service stores a reference to a policy JSON file in its configuration file,
|
||||
:file:`/etc/barbican/barbican.conf`. Typically this file is named
|
||||
``policy.json`` and it is stored in :file:`/etc/barbican/policy.json`.
|
||||
@ -58,9 +58,11 @@ admin
|
||||
by the project for which the admin role is scoped.
|
||||
|
||||
creator
|
||||
Users with this role are allowed to create new resources but are not
|
||||
allowed to delete any existing resources. They are also allowed full
|
||||
access to existing secrets owned by the project in scope.
|
||||
Users with this role are allowed to create new resources and can only
|
||||
delete resources which are originally created (owned) by them. Users with
|
||||
this role cannot delete other user's resources managed within same project.
|
||||
They are also allowed full access to existing secrets owned by the project
|
||||
in scope.
|
||||
|
||||
observer
|
||||
Users with this role are allowed to access to existing resources but are
|
||||
@ -73,11 +75,11 @@ audit
|
||||
Access Control List API
|
||||
-----------------------
|
||||
|
||||
There are some limitations that result from scoping ownership of a secret
|
||||
at the project level. For example, there is no easy way for a user to upload
|
||||
a secret for which only they have access. There is also no easy way to grant
|
||||
a user access to only a single secret.
|
||||
There are some limitations that result from scoping ownership of a secret at the
|
||||
project level. For example, there is no easy way for a user to upload a secret
|
||||
for which only they have access. There is also no easy way to grant a user
|
||||
access to only a single secret.
|
||||
|
||||
To address this limitations the Key Manager service includes an Access
|
||||
Control List (ACL) API. For full details see the
|
||||
To address this limitations the Key Manager service includes an Access Control
|
||||
List (ACL) API. For full details see the
|
||||
`ACL API User Guide <http://developer.openstack.org/api-guide/key-manager/acls.html>`__
|
||||
|
@ -24,6 +24,8 @@ admin_a=project_a_admin
|
||||
admin_a_password=barbican
|
||||
creator_a=project_a_creator
|
||||
creator_a_password=barbican
|
||||
creator_a_2=project_a_creator_2
|
||||
creator_a_2_password=barbican
|
||||
observer_a=project_a_observer
|
||||
observer_a_password=barbican
|
||||
auditor_a=project_a_auditor
|
||||
|
@ -30,7 +30,7 @@
|
||||
"secret:decrypt": "rule:secret_decrypt_non_private_read or rule:secret_project_creator or rule:secret_project_admin or rule:secret_acl_read",
|
||||
"secret:get": "rule:secret_non_private_read or rule:secret_project_creator or rule:secret_project_admin or rule:secret_acl_read",
|
||||
"secret:put": "rule:admin_or_creator and rule:secret_project_match",
|
||||
"secret:delete": "rule:admin and rule:secret_project_match",
|
||||
"secret:delete": "rule:secret_project_admin or rule:secret_project_creator",
|
||||
"secrets:post": "rule:admin_or_creator",
|
||||
"secrets:get": "rule:all_but_audit",
|
||||
"orders:post": "rule:admin_or_creator",
|
||||
@ -45,7 +45,7 @@
|
||||
"containers:post": "rule:admin_or_creator",
|
||||
"containers:get": "rule:all_but_audit",
|
||||
"container:get": "rule:container_non_private_read or rule:container_project_creator or rule:container_project_admin or rule:container_acl_read",
|
||||
"container:delete": "rule:admin",
|
||||
"container:delete": "rule:container_project_admin or rule:container_project_creator",
|
||||
"container_secret:post": "rule:admin",
|
||||
"container_secret:delete": "rule:admin",
|
||||
"transport_key:get": "rule:all_users",
|
||||
|
@ -24,6 +24,7 @@ from functionaltests.common import config
|
||||
CONF = config.get_config()
|
||||
admin_a = CONF.rbac_users.admin_a
|
||||
creator_a = CONF.rbac_users.creator_a
|
||||
creator_a_2 = CONF.rbac_users.creator_a_2
|
||||
observer_a = CONF.rbac_users.observer_a
|
||||
auditor_a = CONF.rbac_users.auditor_a
|
||||
|
||||
@ -55,8 +56,10 @@ test_data_rbac_update_container = {
|
||||
test_data_rbac_delete_container = {
|
||||
'with_admin_a': {'user': admin_a, 'admin': admin_a,
|
||||
'expected_return': 204},
|
||||
'with_creator_a': {'user': creator_a, 'admin': admin_a,
|
||||
'expected_return': 403},
|
||||
'with_creator_a': {'user': creator_a, 'admin': creator_a,
|
||||
'expected_return': 204},
|
||||
'with_creator_a_2': {'user': creator_a_2, 'admin': creator_a,
|
||||
'expected_return': 403},
|
||||
'with_observer_a': {'user': observer_a, 'admin': admin_a,
|
||||
'expected_return': 403},
|
||||
'with_auditor_a': {'user': auditor_a, 'admin': admin_a,
|
||||
|
@ -24,6 +24,7 @@ from functionaltests.common import config
|
||||
CONF = config.get_config()
|
||||
admin_a = CONF.rbac_users.admin_a
|
||||
creator_a = CONF.rbac_users.creator_a
|
||||
creator_a_2 = CONF.rbac_users.creator_a_2
|
||||
observer_a = CONF.rbac_users.observer_a
|
||||
auditor_a = CONF.rbac_users.auditor_a
|
||||
|
||||
@ -86,8 +87,10 @@ test_data_rbac_get_list_of_secrets = {
|
||||
test_data_rbac_delete_secret = {
|
||||
'with_admin_a': {'user': admin_a, 'admin': admin_a,
|
||||
'expected_return': 204},
|
||||
'with_creator_a': {'user': creator_a, 'admin': admin_a,
|
||||
'expected_return': 403},
|
||||
'with_creator_a': {'user': creator_a, 'admin': creator_a,
|
||||
'expected_return': 204},
|
||||
'with_creator_a_2': {'user': creator_a_2, 'admin': creator_a,
|
||||
'expected_return': 403},
|
||||
'with_observer_a': {'user': observer_a, 'admin': admin_a,
|
||||
'expected_return': 403},
|
||||
'with_auditor_a': {'user': auditor_a, 'admin': admin_a,
|
||||
|
@ -65,6 +65,12 @@ class BarbicanClient(object):
|
||||
username=CONF.rbac_users.creator_a,
|
||||
password=CONF.rbac_users.creator_a_password,
|
||||
project_name=CONF.rbac_users.project_a)
|
||||
self._auth[CONF.rbac_users.creator_a_2] = auth.FunctionalTestAuth(
|
||||
endpoint=CONF.identity.uri,
|
||||
version=CONF.identity.version,
|
||||
username=CONF.rbac_users.creator_a_2,
|
||||
password=CONF.rbac_users.creator_a_2_password,
|
||||
project_name=CONF.rbac_users.project_a)
|
||||
self._auth[CONF.rbac_users.observer_a] = auth.FunctionalTestAuth(
|
||||
endpoint=CONF.identity.uri,
|
||||
version=CONF.identity.version,
|
||||
|
@ -48,6 +48,8 @@ def setup_config(config_file=''):
|
||||
cfg.StrOpt('admin_a_password', default='barbican', secret=True),
|
||||
cfg.StrOpt('creator_a', default='project_a_creator'),
|
||||
cfg.StrOpt('creator_a_password', default='barbican', secret=True),
|
||||
cfg.StrOpt('creator_a_2', default='project_a_creator_2'),
|
||||
cfg.StrOpt('creator_a_2_password', default='barbican', secret=True),
|
||||
cfg.StrOpt('observer_a', default='project_a_observer'),
|
||||
cfg.StrOpt('observer_a_password', default='barbican', secret=True),
|
||||
cfg.StrOpt('auditor_a', default='project_a_auditor'),
|
||||
|
Loading…
Reference in New Issue
Block a user