summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glance/policies/base.py13
-rw-r--r--glance/policies/discovery.py2
-rw-r--r--glance/policies/image.py50
-rw-r--r--glance/policies/metadef.py52
-rw-r--r--glance/policies/tasks.py10
-rw-r--r--releasenotes/notes/rbac-updates-ba0fcb886fe4085c.yaml26
6 files changed, 84 insertions, 69 deletions
diff --git a/glance/policies/base.py b/glance/policies/base.py
index ef908eae2..77d023414 100644
--- a/glance/policies/base.py
+++ b/glance/policies/base.py
@@ -54,16 +54,9 @@ PROJECT_READER_OR_PUBLIC_NAMESPACE = (
#
# These check strings do not support tenancy with the `admin` role. This means
# anyone with the `admin` role on any project can execute a policy, which is
-# typical in OpenStack services. Eventually, these check strings will be
-# superseded by check strings that implement scope checking and system-scope
-# for applicable APIs (e.g., making an image public). But, we have a lot of
-# cleanup to do in different parts of glance to sweep all the authorization
-# code into a single layer before we can safely consume system-scope and
-# implement scope checking. This refactoring also needs significant API testing
-# to ensure we don't leave doors open to unintended users, or expose
-# authoritative regressions. In the mean time, we can use the following check
-# strings to offer formal support for project membership and a read-only
-# variant consistent with other OpenStack services.
+# typical in OpenStack services. But following check strings offer formal
+# support for project membership and a read-only variant consistent with
+# other OpenStack services.
ADMIN_OR_PROJECT_MEMBER = f'role:admin or ({PROJECT_MEMBER})'
ADMIN_OR_PROJECT_READER = f'role:admin or ({PROJECT_READER})'
ADMIN_OR_PROJECT_READER_GET_IMAGE = (
diff --git a/glance/policies/discovery.py b/glance/policies/discovery.py
index 3273a48ec..50a421330 100644
--- a/glance/policies/discovery.py
+++ b/glance/policies/discovery.py
@@ -19,7 +19,7 @@ discovery_policies = [
policy.DocumentedRuleDefault(
name="stores_info_detail",
check_str='role:admin',
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Expose store specific information',
operations=[
{'path': '/v2/info/stores/detail',
diff --git a/glance/policies/image.py b/glance/policies/image.py
index 4bddd62d3..c4400ec0b 100644
--- a/glance/policies/image.py
+++ b/glance/policies/image.py
@@ -24,7 +24,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="add_image",
check_str=base.ADMIN_OR_PROJECT_MEMBER_CREATE_IMAGE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Create new image',
operations=[
{'path': '/v2/images',
@@ -38,7 +38,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="delete_image",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Deletes the image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -52,7 +52,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="get_image",
check_str=base.ADMIN_OR_PROJECT_READER_GET_IMAGE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Get specified image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -66,7 +66,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="get_images",
check_str=base.ADMIN_OR_PROJECT_READER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Get all available images',
operations=[
{'path': '/v2/images',
@@ -80,7 +80,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="modify_image",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Updates given image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -94,7 +94,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="publicize_image",
check_str='role:admin',
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Publicize given image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -104,7 +104,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="communitize_image",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Communitize given image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -119,7 +119,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="download_image",
check_str=base.ADMIN_OR_PROJECT_MEMBER_DOWNLOAD_IMAGE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Downloads given image',
operations=[
{'path': '/v2/images/{image_id}/file',
@@ -133,7 +133,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="upload_image",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Uploads data to specified image',
operations=[
{'path': '/v2/images/{image_id}/file',
@@ -148,7 +148,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="delete_image_location",
check_str="role:admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Deletes the location of given image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -162,7 +162,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="get_image_location",
check_str=base.ADMIN_OR_PROJECT_READER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Reads the location of the image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -176,7 +176,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="set_image_location",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Sets location URI to given image',
operations=[
{'path': '/v2/images/{image_id}',
@@ -191,7 +191,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="add_member",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Create image member',
operations=[
{'path': '/v2/images/{image_id}/members',
@@ -205,7 +205,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="delete_member",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Delete image member',
operations=[
{'path': '/v2/images/{image_id}/members/{member_id}',
@@ -219,7 +219,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="get_member",
check_str=base.ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Show image member details',
operations=[
{'path': '/v2/images/{image_id}/members/{member_id}',
@@ -233,7 +233,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="get_members",
check_str=base.ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='List image members',
operations=[
{'path': '/v2/images/{image_id}/members',
@@ -247,7 +247,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="modify_member",
check_str=base.ADMIN_OR_SHARED_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Update image member',
operations=[
{'path': '/v2/images/{image_id}/members/{member_id}',
@@ -262,17 +262,14 @@ image_policies = [
policy.RuleDefault(
name="manage_image_cache",
check_str='role:admin',
- # NOTE(lbragstad): Remove 'project' from the list below when glance
- # fully supports system-scope and this policy is updated to reflect
- # that in the check string.
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Manage image cache'
),
policy.DocumentedRuleDefault(
name="deactivate",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Deactivate image',
operations=[
{'path': '/v2/images/{image_id}/actions/deactivate',
@@ -286,7 +283,7 @@ image_policies = [
policy.DocumentedRuleDefault(
name="reactivate",
check_str=base.ADMIN_OR_PROJECT_MEMBER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Reactivate image',
operations=[
{'path': '/v2/images/{image_id}/actions/reactivate',
@@ -301,11 +298,10 @@ image_policies = [
policy.DocumentedRuleDefault(
name="copy_image",
check_str='role:admin',
- # Eventually, we need to make sure we update the check string here to
- # be scope-aware, but for now this is restricted to system-admins and
- # project-admins. That might change in the future if we decide to push
+ # For now this is restricted to project-admins.
+ # That might change in the future if we decide to push
# this functionality down to project-members.
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Copy existing image to other stores',
operations=[
{'path': '/v2/images/{image_id}/import',
diff --git a/glance/policies/metadef.py b/glance/policies/metadef.py
index 862e12e23..d1feaaed8 100644
--- a/glance/policies/metadef.py
+++ b/glance/policies/metadef.py
@@ -27,7 +27,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_namespace",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Get a specific namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}',
@@ -42,7 +42,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_namespaces",
check_str=base.ADMIN_OR_PROJECT_READER,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="List namespace.",
operations=[
{'path': '/v2/metadefs/namespaces',
@@ -57,7 +57,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="modify_metadef_namespace",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Modify an existing namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}',
@@ -67,7 +67,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="add_metadef_namespace",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Create a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces',
@@ -77,7 +77,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="delete_metadef_namespace",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Delete a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}',
@@ -88,7 +88,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_object",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Get a specific object from a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/objects'
@@ -104,7 +104,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_objects",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Get objects from a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/objects',
@@ -119,7 +119,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="modify_metadef_object",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Update an object within a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/objects'
@@ -130,7 +130,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="add_metadef_object",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Create an object within a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/objects',
@@ -140,7 +140,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="delete_metadef_object",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Delete an object within a namespace.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/objects'
@@ -152,7 +152,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="list_metadef_resource_types",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="List meta definition resource types.",
operations=[
{'path': '/v2/metadefs/resource_types',
@@ -168,7 +168,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_resource_type",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Get meta definition resource types associations.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/resource_types',
@@ -184,7 +184,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="add_metadef_resource_type_association",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Create meta definition resource types association.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/resource_types',
@@ -194,7 +194,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="remove_metadef_resource_type_association",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Delete meta definition resource types association.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/resource_types'
@@ -206,7 +206,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_property",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Get a specific meta definition property.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/properties'
@@ -223,7 +223,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_properties",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="List meta definition properties.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/properties',
@@ -239,7 +239,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="modify_metadef_property",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Update meta definition property.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/properties'
@@ -250,7 +250,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="add_metadef_property",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Create meta definition property.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/properties',
@@ -260,7 +260,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="remove_metadef_property",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Delete meta definition property.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/properties'
@@ -272,7 +272,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_tag",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Get tag definition.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags'
@@ -288,7 +288,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="get_metadef_tags",
check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE,
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="List tag definitions.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags',
@@ -303,7 +303,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="modify_metadef_tag",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Update tag definition.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags'
@@ -314,7 +314,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="add_metadef_tag",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Add tag definition.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags'
@@ -325,7 +325,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="add_metadef_tags",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Create tag definitions.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags',
@@ -335,7 +335,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="delete_metadef_tag",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Delete tag definition.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags'
@@ -346,7 +346,7 @@ metadef_policies = [
policy.DocumentedRuleDefault(
name="delete_metadef_tags",
check_str="rule:metadef_admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="Delete tag definitions.",
operations=[
{'path': '/v2/metadefs/namespaces/{namespace_name}/tags',
diff --git a/glance/policies/tasks.py b/glance/policies/tasks.py
index d4771b862..42d25a5f6 100644
--- a/glance/policies/tasks.py
+++ b/glance/policies/tasks.py
@@ -47,7 +47,7 @@ task_policies = [
# All policies except tasks_api_access are internal policies that are
# only called by glance as a result of some other operation.
check_str='rule:default',
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='Get an image task.\n' + TASK_DESCRIPTION,
operations=[
{'path': '/v2/tasks/{task_id}',
@@ -61,7 +61,7 @@ task_policies = [
policy.DocumentedRuleDefault(
name="get_tasks",
check_str='rule:default',
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='List tasks for all images.\n' + TASK_DESCRIPTION,
operations=[
{'path': '/v2/tasks',
@@ -75,7 +75,7 @@ task_policies = [
policy.DocumentedRuleDefault(
name="add_task",
check_str='rule:default',
- scope_types=['system', 'project'],
+ scope_types=['project'],
description='List tasks for all images.\n' + TASK_DESCRIPTION,
operations=[
{'path': '/v2/tasks',
@@ -89,7 +89,7 @@ task_policies = [
policy.DocumentedRuleDefault(
name="modify_task",
check_str='rule:default',
- scope_types=['system', 'project'],
+ scope_types=['project'],
description="This policy is not used.",
operations=[
{'path': '/v2/tasks/{task_id}',
@@ -102,7 +102,7 @@ task_policies = [
policy.DocumentedRuleDefault(
name="tasks_api_access",
check_str="role:admin",
- scope_types=['system', 'project'],
+ scope_types=['project'],
description=TASK_ACCESS_DESCRIPTION,
operations=[
{'path': '/v2/tasks/{task_id}',
diff --git a/releasenotes/notes/rbac-updates-ba0fcb886fe4085c.yaml b/releasenotes/notes/rbac-updates-ba0fcb886fe4085c.yaml
new file mode 100644
index 000000000..bcb3eb08f
--- /dev/null
+++ b/releasenotes/notes/rbac-updates-ba0fcb886fe4085c.yaml
@@ -0,0 +1,26 @@
+---
+features:
+ - |
+ The Glance policies have been modified to drop the system scope. Every
+ API policy is scoped to project. This means that system scoped users
+ will get 403 permission denied error.
+
+ Also, the project reader role is ready to use. Users with reader role
+ can only perform the read-only operations within their project. This
+ role can be used for the audit purposes.
+
+ For the details on what changed from the existing policy, please refer
+ to the `RBAC new guidelines`_. We have implemented only phase-1 of the
+ `RBAC new guidelines`_.
+ Currently, scope checks and new defaults are disabled by default. You can
+ enable them by switching the below config option in ``glance.conf`` file::
+
+ [oslo_policy]
+ enforce_new_defaults=True
+ enforce_scope=True
+
+ We recommend to enable the both scope as well new defaults together
+ otherwise you may experience some late failures with unclear error
+ messages.
+
+ .. _`RBAC new guidelines`: https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-1