Add secure RBAC role as new default

This add new RBAC defaults in the cloukitty API policy. There is no
change in the admin policy except they are scoped to the 'project'.
Adding project reader role in the read APIs which continue to be allow
by the member and admin role.

Change-Id: Ia693a50210a850626adcd9daab1736335ae2b015
This commit is contained in:
Ghanshyam Mann
2025-01-28 13:00:40 -08:00
committed by Pierre Riteau
parent 591106aea1
commit 0f0754dab8
12 changed files with 127 additions and 38 deletions

View File

@@ -19,6 +19,24 @@ RULE_ADMIN_OR_OWNER = 'rule:admin_or_owner'
ROLE_ADMIN = 'role:admin'
UNPROTECTED = ''
DEPRECATED_REASON = """
CloudKitty API policies are introducing new default roles with scope_type
capabilities. Old policies are deprecated and silently going to be ignored
in future release.
"""
DEPRECATED_ADMIN_OR_OWNER_POLICY = policy.DeprecatedRule(
name=RULE_ADMIN_OR_OWNER,
check_str='is_admin:True or '
'(role:admin and is_admin_project:True) or '
'project_id:%(project_id)s',
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'
)
PROJECT_MEMBER_OR_ADMIN = 'rule:project_member_or_admin'
PROJECT_READER_OR_ADMIN = 'rule:project_reader_or_admin'
rules = [
policy.RuleDefault(
name='context_is_admin',
@@ -27,10 +45,33 @@ rules = [
name='admin_or_owner',
check_str='is_admin:True or '
'(role:admin and is_admin_project:True) or '
'project_id:%(project_id)s'),
'project_id:%(project_id)s',
deprecated_for_removal=True,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.RuleDefault(
name='default',
check_str=UNPROTECTED)
check_str=UNPROTECTED),
policy.RuleDefault(
"project_member_api",
"role:member and project_id:%(project_id)s",
"Default rule for Project level non admin APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY),
policy.RuleDefault(
"project_reader_api",
"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(
"project_member_or_admin",
"rule:project_member_api or rule:context_is_admin",
"Default rule for Project Member or admin APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY),
policy.RuleDefault(
"project_reader_or_admin",
"rule:project_reader_api or rule:context_is_admin",
"Default rule for Project reader or admin APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY)
]

View File

@@ -23,13 +23,15 @@ collector_policies = [
check_str=base.ROLE_ADMIN,
description='Return the list of every services mapped to a collector.',
operations=[{'path': '/v1/collector/mappings',
'method': 'LIST'}]),
'method': 'LIST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='collector:get_mapping',
check_str=base.ROLE_ADMIN,
description='Return a service to collector mapping.',
operations=[{'path': '/v1/collector/mappings/{service_id}',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='collector:manage_mapping',
check_str=base.ROLE_ADMIN,
@@ -37,19 +39,22 @@ collector_policies = [
operations=[{'path': '/v1/collector/mappings',
'method': 'POST'},
{'path': '/v1/collector/mappings/{service_id}',
'method': 'DELETE'}]),
'method': 'DELETE'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='collector:get_state',
check_str=base.ROLE_ADMIN,
description='Query the enable state of a collector.',
operations=[{'path': '/v1/collector/states/{collector_id}',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='collector:update_state',
check_str=base.ROLE_ADMIN,
description='Set the enable state of a collector.',
operations=[{'path': '/v1/collector/states/{collector_id}',
'method': 'PUT'}])
'method': 'PUT'}],
scope_types=['project'])
]

View File

@@ -23,31 +23,36 @@ info_policies = [
check_str=base.UNPROTECTED,
description='List available services information in Cloudkitty.',
operations=[{'path': '/v1/info/services',
'method': 'LIST'}]),
'method': 'LIST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='info:get_service_info',
check_str=base.UNPROTECTED,
description='Get specified service information.',
operations=[{'path': '/v1/info/services/{metric_id}',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='info:list_metrics_info',
check_str=base.UNPROTECTED,
description='List available metrics information in Cloudkitty.',
operations=[{'path': '/v1/info/metrics',
'method': 'LIST'}]),
'method': 'LIST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='info:get_metric_info',
check_str=base.UNPROTECTED,
description='Get specified metric information.',
operations=[{'path': '/v1/info/metrics/{metric_id}',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='info:get_config',
check_str=base.UNPROTECTED,
description='Get current configuration in Cloudkitty.',
operations=[{'path': '/v1/info/config',
'method': 'GET'}])
'method': 'GET'}],
scope_types=['project'])
]

View File

@@ -23,32 +23,37 @@ rating_policies = [
check_str=base.ROLE_ADMIN,
description='Return the list of loaded modules in Cloudkitty.',
operations=[{'path': '/v1/rating/modules',
'method': 'LIST'}]),
'method': 'LIST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='rating:get_module',
check_str=base.ROLE_ADMIN,
description='Get specified module.',
operations=[{'path': '/v1/rating/modules/{module_id}',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='rating:update_module',
check_str=base.ROLE_ADMIN,
description='Change the state and priority of a module.',
operations=[{'path': '/v1/rating/modules/{module_id}',
'method': 'PUT'}]),
'method': 'PUT'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='rating:quote',
check_str=base.UNPROTECTED,
description='Get an instant quote based on multiple resource '
'descriptions.',
operations=[{'path': '/v1/rating/quote',
'method': 'POST'}]),
'method': 'POST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='rating:module_config',
check_str=base.ROLE_ADMIN,
description='Trigger a rating module list reload.',
operations=[{'path': '/v1/rating/reload_modules',
'method': 'GET'}])
'method': 'GET'}],
scope_types=['project'])
]

View File

@@ -23,19 +23,22 @@ report_policies = [
check_str=base.ROLE_ADMIN,
description='Return the list of rated tenants.',
operations=[{'path': '/v1/report/tenants',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='report:get_summary',
check_str=base.RULE_ADMIN_OR_OWNER,
check_str=base.PROJECT_READER_OR_ADMIN,
description='Return the summary to pay for a given period.',
operations=[{'path': '/v1/report/summary',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='report:get_total',
check_str=base.RULE_ADMIN_OR_OWNER,
check_str=base.PROJECT_READER_OR_ADMIN,
description='Return the amount to pay for a given period.',
operations=[{'path': '/v1/report/total',
'method': 'GET'}])
'method': 'GET'}],
scope_types=['project'])
]

View File

@@ -20,11 +20,12 @@ from cloudkitty.common.policies import base
storage_policies = [
policy.DocumentedRuleDefault(
name='storage:list_data_frames',
check_str=base.RULE_ADMIN_OR_OWNER,
check_str=base.PROJECT_READER_OR_ADMIN,
description='Return a list of rated resources for a time period '
'and a tenant.',
operations=[{'path': '/v1/storage/dataframes',
'method': 'GET'}])
'method': 'GET'}],
scope_types=['project'])
]

View File

@@ -23,13 +23,15 @@ dataframes_policies = [
check_str=base.ROLE_ADMIN,
description='Add one or several DataFrames',
operations=[{'path': '/v2/dataframes',
'method': 'POST'}]),
'method': 'POST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='dataframes:get',
check_str=base.RULE_ADMIN_OR_OWNER,
check_str=base.PROJECT_READER_OR_ADMIN,
description='Get DataFrames',
operations=[{'path': '/v2/dataframes',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
]

View File

@@ -23,19 +23,22 @@ rating_policies = [
check_str=base.ROLE_ADMIN,
description='Returns the list of loaded modules in Cloudkitty.',
operations=[{'path': '/v2/rating/modules',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='v2_rating:get_module',
check_str=base.ROLE_ADMIN,
description='Get specified module.',
operations=[{'path': '/v2/rating/modules/{module_id}',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='v2_rating:update_module',
check_str=base.ROLE_ADMIN,
description='Change the state and priority of a module.',
operations=[{'path': '/v2/rating/modules/{module_id}',
'method': 'PUT'}])
'method': 'PUT'}],
scope_types=['project'])
]

View File

@@ -23,25 +23,29 @@ scope_policies = [
check_str=base.ROLE_ADMIN,
description='Get the state of one or several scopes',
operations=[{'path': '/v2/scope',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='scope:reset_state',
check_str=base.ROLE_ADMIN,
description='Reset the state of one or several scopes',
operations=[{'path': '/v2/scope',
'method': 'PUT'}]),
'method': 'PUT'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='scope:patch_state',
check_str=base.ROLE_ADMIN,
description='Enables operators to patch a storage scope',
operations=[{'path': '/v2/scope',
'method': 'PATCH'}]),
'method': 'PATCH'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='scope:post_state',
check_str=base.ROLE_ADMIN,
description='Enables operators to create a storage scope',
operations=[{'path': '/v2/scope',
'method': 'POST'}]),
'method': 'POST'}],
scope_types=['project']),
]

View File

@@ -19,10 +19,11 @@ from cloudkitty.common.policies import base
example_policies = [
policy.DocumentedRuleDefault(
name='summary:get_summary',
check_str=base.RULE_ADMIN_OR_OWNER,
check_str=base.PROJECT_READER_OR_ADMIN,
description='Get a rating summary',
operations=[{'path': '/v2/summary',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
]

View File

@@ -22,13 +22,15 @@ schedule_policies = [
check_str=base.ROLE_ADMIN,
description='Schedule a scope for reprocessing',
operations=[{'path': '/v2/task/reprocesses',
'method': 'POST'}]),
'method': 'POST'}],
scope_types=['project']),
policy.DocumentedRuleDefault(
name='schedule:get_task_reprocesses',
check_str=base.ROLE_ADMIN,
description='Get reprocessing schedule tasks for scopes.',
operations=[{'path': '/v2/task/reprocesses',
'method': 'GET'}]),
'method': 'GET'}],
scope_types=['project']),
]

View File

@@ -0,0 +1,17 @@
---
features:
- |
The CloudKitty policies implemented the scope concept and new default roles
(``admin``, ``member``, and ``reader``) provided by keystone.
upgrade:
- |
All the policies implement the ``scope_type`` and new defaults.
* **Scope**
Each policy is protected with ``project`` ``scope_type``.
* **New Defaults (Admin, Member and Reader)**
Policies are default to Admin, Member and Reader roles. Old roles are
also supported. There is no change in the legacy admin access.