Implement secure RBAC for alarms and quota policies

This commit updates the default policies to include supports for
enhanced token scope checking and default roles, including a read-only
role for GET APIs.

This is part of a broader change across OpenStack projects to
consolidate common personas and provide a more secure and consistent
authorization experience for end users and operators.

Change-Id: If17dbfec10302c9c57d814cb406faee1a6efc59a
This commit is contained in:
Lance Bragstad
2020-12-01 16:03:39 +00:00
parent 5df5505c8d
commit 7779da4916

View File

@@ -13,6 +13,7 @@
# under the License. # under the License.
from oslo_log import versionutils
from oslo_policy import policy from oslo_policy import policy
RULE_CONTEXT_IS_ADMIN = 'rule:context_is_admin' RULE_CONTEXT_IS_ADMIN = 'rule:context_is_admin'
@@ -38,8 +39,68 @@ SYSTEM_OR_PROJECT_READER = (
' or (' + PROJECT_READER + ')' ' or (' + PROJECT_READER + ')'
) )
DEPRECATED_REASON = """
The alarm and quota APIs now support system-scope and default roles.
"""
deprecated_get_alarm = policy.DeprecatedRule(
name="telemetry:get_alarm",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_get_alarms = policy.DeprecatedRule(
name="telemetry:get_alarms",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_get_all_alarms = policy.DeprecatedRule(
name="telemetry:get_alarms:all_projects",
check_str=RULE_CONTEXT_IS_ADMIN
)
deprecated_query_alarm = policy.DeprecatedRule(
name="telemetry:query_alarm",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_create_alarm = policy.DeprecatedRule(
name="telemetry:create_alarm",
check_str=UNPROTECTED
)
deprecated_change_alarm = policy.DeprecatedRule(
name="telemetry:change_alarm",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_delete_alarm = policy.DeprecatedRule(
name="telemetry:delete_alarm",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_get_alarm_state = policy.DeprecatedRule(
name="telemetry:get_alarm_state",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_change_alarm_state = policy.DeprecatedRule(
name="telemetry:change_alarm_state",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_alarm_history = policy.DeprecatedRule(
name="telemetry:alarm_history",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_query_alarm_history = policy.DeprecatedRule(
name="telemetry:query_alarm_history",
check_str=RULE_ADMIN_OR_OWNER
)
deprecated_update_quotas = policy.DeprecatedRule(
name="telemetry:update_quotas",
check_str=RULE_CONTEXT_IS_ADMIN
)
deprecated_delete_quotas = policy.DeprecatedRule(
name="telemetry:delete_quotas",
check_str=RULE_CONTEXT_IS_ADMIN
)
rules = [ rules = [
# This policy can be removed once all the policies in this file are no
# longer deprecated and are using the new default policies with proper
# scope support.
policy.RuleDefault( policy.RuleDefault(
name="context_is_admin", name="context_is_admin",
check_str="role:admin" check_str="role:admin"
@@ -47,156 +108,217 @@ rules = [
policy.RuleDefault( policy.RuleDefault(
name="segregation", name="segregation",
check_str=RULE_CONTEXT_IS_ADMIN), check_str=RULE_CONTEXT_IS_ADMIN),
# This policy can be removed once all the policies in this file are no
# longer deprecated and are using the new default policies with proper
# scope support.
policy.RuleDefault( policy.RuleDefault(
name="admin_or_owner", name="admin_or_owner",
check_str=RULE_ADMIN_OR_OWNER check_str=RULE_ADMIN_OR_OWNER
), ),
# This policy can be removed once all the policies in this file are no
# longer deprecated and are using the new default policies with proper
# scope support. We shouldn't need a "default" policy if each policy has a
# reasonable default. This concept of a broad "default" existed prior to
# registering policies in code with their own default values.
policy.RuleDefault( policy.RuleDefault(
name="default", name="default",
check_str=RULE_ADMIN_OR_OWNER check_str=RULE_ADMIN_OR_OWNER
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:get_alarm", name="telemetry:get_alarm",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Get an alarm.', description='Get an alarm.',
operations=[ operations=[
{ {
'path': '/v2/alarms/{alarm_id}', 'path': '/v2/alarms/{alarm_id}',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_get_alarm,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:get_alarms", name="telemetry:get_alarms",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Get all alarms, based on the query provided.', description='Get all alarms, based on the query provided.',
operations=[ operations=[
{ {
'path': '/v2/alarms', 'path': '/v2/alarms',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_get_alarms,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:get_alarms:all_projects", name="telemetry:get_alarms:all_projects",
check_str=RULE_CONTEXT_IS_ADMIN, check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Get alarms of all projects.', description='Get alarms of all projects.',
operations=[ operations=[
{ {
'path': '/v2/alarms', 'path': '/v2/alarms',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_get_all_alarms,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:query_alarm", name="telemetry:query_alarm",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Get all alarms, based on the query provided.', description='Get all alarms, based on the query provided.',
operations=[ operations=[
{ {
'path': '/v2/query/alarms', 'path': '/v2/query/alarms',
'method': 'POST' 'method': 'POST'
} }
] ],
deprecated_rule=deprecated_query_alarm,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:create_alarm", name="telemetry:create_alarm",
check_str=UNPROTECTED, check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Create a new alarm.', description='Create a new alarm.',
operations=[ operations=[
{ {
'path': '/v2/alarms', 'path': '/v2/alarms',
'method': 'POST' 'method': 'POST'
} }
] ],
deprecated_rule=deprecated_create_alarm,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:change_alarm", name="telemetry:change_alarm",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Modify this alarm.', description='Modify this alarm.',
operations=[ operations=[
{ {
'path': '/v2/alarms/{alarm_id}', 'path': '/v2/alarms/{alarm_id}',
'method': 'PUT' 'method': 'PUT'
} }
] ],
deprecated_rule=deprecated_change_alarm,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:delete_alarm", name="telemetry:delete_alarm",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Delete this alarm.', description='Delete this alarm.',
operations=[ operations=[
{ {
'path': '/v2/alarms/{alarm_id}', 'path': '/v2/alarms/{alarm_id}',
'method': 'DELETE' 'method': 'DELETE'
} }
] ],
deprecated_rule=deprecated_delete_alarm,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:get_alarm_state", name="telemetry:get_alarm_state",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Get the state of this alarm.', description='Get the state of this alarm.',
operations=[ operations=[
{ {
'path': '/v2/alarms/{alarm_id}/state', 'path': '/v2/alarms/{alarm_id}/state',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_get_alarm_state,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:change_alarm_state", name="telemetry:change_alarm_state",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Set the state of this alarm.', description='Set the state of this alarm.',
operations=[ operations=[
{ {
'path': '/v2/alarms/{alarm_id}/state', 'path': '/v2/alarms/{alarm_id}/state',
'method': 'PUT' 'method': 'PUT'
} }
] ],
deprecated_rule=deprecated_change_alarm_state,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:alarm_history", name="telemetry:alarm_history",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Assembles the alarm history requested.', description='Assembles the alarm history requested.',
operations=[ operations=[
{ {
'path': '/v2/alarms/{alarm_id}/history', 'path': '/v2/alarms/{alarm_id}/history',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_alarm_history,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:query_alarm_history", name="telemetry:query_alarm_history",
check_str=RULE_ADMIN_OR_OWNER, check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Define query for retrieving AlarmChange data.', description='Define query for retrieving AlarmChange data.',
operations=[ operations=[
{ {
'path': '/v2/query/alarms/history', 'path': '/v2/query/alarms/history',
'method': 'POST' 'method': 'POST'
} }
] ],
deprecated_rule=deprecated_query_alarm_history,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:update_quotas", name="telemetry:update_quotas",
check_str=RULE_CONTEXT_IS_ADMIN, check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Update resources quotas for project.', description='Update resources quotas for project.',
operations=[ operations=[
{ {
'path': '/v2/quotas', 'path': '/v2/quotas',
'method': 'POST' 'method': 'POST'
} }
] ],
deprecated_rule=deprecated_update_quotas,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name="telemetry:delete_quotas", name="telemetry:delete_quotas",
check_str=RULE_CONTEXT_IS_ADMIN, check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Delete resources quotas for project.', description='Delete resources quotas for project.',
operations=[ operations=[
{ {
'path': '/v2/quotas/{project_id}', 'path': '/v2/quotas/{project_id}',
'method': 'DELETE' 'method': 'DELETE'
} }
] ],
deprecated_rule=deprecated_delete_quotas,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
) )
] ]