Isolate project scope and system scope

This change updates the default policies implemented in Heat, to follow
the updated guideline[1] to implement SRBAC.

The main change is that system users are no longer allowed to perform
any operations about project-level resources like stacks, while project
admin(*1) is still allowed to perform operations about project-level
resources BEYOND project (like getting stacks for all projects by list
stacks API).

[1] https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#direction-change

This also adds the test cases to validate reader role which was almost
implemented in heat.

(*1)
If Keystone has an admin project defined, Heat checks an additional
requirement that request context is scoped by that admin project.

Change-Id: I943b3c1ce021cc05445b73fbc342b8386cf5bf6a
This commit is contained in:
Takashi Kajinami 2022-02-22 18:11:28 +09:00
parent 3896d8536a
commit 185f28a3b4
17 changed files with 500 additions and 236 deletions

View File

@ -31,9 +31,7 @@ def registered_policy_enforce(handler):
def handle_stack_method(controller, req, tenant_id, **kwargs):
_target = {"project_id": tenant_id}
if req.context.tenant_id != tenant_id and not (
req.context.is_admin or
req.context.system_scope == all):
if req.context.tenant_id != tenant_id and not req.context.is_admin:
raise exc.HTTPForbidden()
allowed = req.context.policy.enforce(
context=req.context,
@ -57,9 +55,7 @@ def no_policy_enforce(handler):
"""
@functools.wraps(handler)
def handle_stack_method(controller, req, tenant_id, **kwargs):
if req.context.tenant_id != tenant_id and not (
req.context.is_admin or
req.context.system_scope == all):
if req.context.tenant_id != tenant_id and not req.context.is_admin:
raise exc.HTTPForbidden()
return handler(controller, req, **kwargs)

View File

@ -85,20 +85,29 @@ class Enforcer(object):
"""
do_raise = False if not exc else True
credentials = context.to_policy_values()
if is_registered_policy:
try:
return self.enforcer.authorize(rule, target, credentials,
do_raise=do_raise,
exc=exc, action=rule)
except policy.PolicyNotRegistered:
if self.log_not_registered:
with excutils.save_and_reraise_exception():
LOG.exception(_('Policy not registered.'))
else:
raise
else:
return self.enforcer.enforce(rule, target, credentials,
do_raise, exc=exc, *args, **kwargs)
try:
if is_registered_policy:
try:
return self.enforcer.authorize(rule, target, credentials,
do_raise=do_raise,
exc=exc, action=rule)
except policy.PolicyNotRegistered:
if self.log_not_registered:
with excutils.save_and_reraise_exception():
LOG.exception(_('Policy not registered.'))
else:
raise
else:
return self.enforcer.enforce(rule, target, credentials,
do_raise, exc=exc, *args,
**kwargs)
except policy.InvalidScope:
LOG.debug('Policy check for %(action)s failed with scope check '
'%(credentials)s',
{'action': rule,
'credentials': context.to_policy_values()})
raise exc(action=rule)
def enforce(self, context, action, scope=None, target=None,
is_registered_policy=False):

View File

@ -68,7 +68,8 @@ deprecated_cancel_without_rollback = policy.DeprecatedRule(
actions_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'action',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Performs non-lifecycle operations on the stack '
'(Snapshot, Resume, Cancel update, or check stack resources). '
'This is the default for all actions but can be overridden by more '
@ -81,8 +82,8 @@ actions_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'snapshot',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Create stack snapshot',
operations=[{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions',
@ -92,8 +93,8 @@ actions_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'suspend',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Suspend a stack.',
operations=[{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions',
@ -103,8 +104,8 @@ actions_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'resume',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Resume a suspended stack.',
operations=[{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions',
@ -114,8 +115,8 @@ actions_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'check',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Check stack resources.',
operations=[{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions',
@ -125,8 +126,8 @@ actions_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'cancel_update',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Cancel stack operation and roll back.',
operations=[{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions',
@ -136,8 +137,8 @@ actions_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'cancel_without_rollback',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Cancel stack operation without rolling back.',
operations=[{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions',

View File

@ -30,22 +30,12 @@ PROJECT_STACK_USER = 'role:heat_stack_user and project_id:%(project_id)s'
# Composite check strings that are useful for policies that protect APIs that
# operate at different scopes.
SYSTEM_ADMIN_OR_PROJECT_MEMBER = (
'(' + SYSTEM_ADMIN + ')'
' or (' + PROJECT_MEMBER + ')'
)
SYSTEM_OR_PROJECT_READER = (
'(' + SYSTEM_READER + ')'
' or (' + PROJECT_READER + ')'
)
SYSTEM_ADMIN_OR_PROJECT_MEMBER_OR_STACK_USER = (
'(' + SYSTEM_ADMIN + ')'
' or (' + PROJECT_MEMBER + ')'
PROJECT_MEMBER_OR_STACK_USER = (
'(' + PROJECT_MEMBER + ')'
' or (' + PROJECT_STACK_USER + ')'
)
SYSTEM_OR_PROJECT_READER_OR_STACK_USER = (
'(' + SYSTEM_READER + ')'
' or (' + PROJECT_READER + ')'
PROJECT_READER_OR_STACK_USER = (
'(' + PROJECT_READER + ')'
' or (' + PROJECT_STACK_USER + ')'
)

View File

@ -32,8 +32,8 @@ deprecated_build_info = policy.DeprecatedRule(
build_info_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'build_info',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show build information.',
operations=[
{

View File

@ -106,80 +106,80 @@ deprecated_list_stack_resources = policy.DeprecatedRule(
cloudformation_policies = [
policy.RuleDefault(
name=POLICY_ROOT % 'ListStacks',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_list_stacks
),
policy.RuleDefault(
name=POLICY_ROOT % 'CreateStack',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
deprecated_rule=deprecated_create_stack
),
policy.RuleDefault(
name=POLICY_ROOT % 'DescribeStacks',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_describe_stacks
),
policy.RuleDefault(
name=POLICY_ROOT % 'DeleteStack',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
deprecated_rule=deprecated_delete_stack
),
policy.RuleDefault(
name=POLICY_ROOT % 'UpdateStack',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
deprecated_rule=deprecated_update_stack
),
policy.RuleDefault(
name=POLICY_ROOT % 'CancelUpdateStack',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
deprecated_rule=deprecated_cancel_update_stack
),
policy.RuleDefault(
name=POLICY_ROOT % 'DescribeStackEvents',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_describe_stack_events
),
policy.RuleDefault(
name=POLICY_ROOT % 'ValidateTemplate',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_validate_template
),
policy.RuleDefault(
name=POLICY_ROOT % 'GetTemplate',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_get_template
),
policy.RuleDefault(
name=POLICY_ROOT % 'EstimateTemplateCost',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_estimate_template_cost
),
policy.RuleDefault(
name=POLICY_ROOT % 'DescribeStackResource',
check_str=base.SYSTEM_OR_PROJECT_READER_OR_STACK_USER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER_OR_STACK_USER,
scope_types=['project'],
deprecated_rule=deprecated_describe_stack_resource
),
policy.RuleDefault(
name=POLICY_ROOT % 'DescribeStackResources',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_describe_stack_resources
),
policy.RuleDefault(
name=POLICY_ROOT % 'ListStackResources',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
deprecated_rule=deprecated_list_stack_resources
)
]

View File

@ -38,8 +38,8 @@ deprecated_show = policy.DeprecatedRule(
events_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List events.',
operations=[
{
@ -52,8 +52,8 @@ events_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show event.',
operations=[
{

View File

@ -55,8 +55,8 @@ deprecated_signal = policy.DeprecatedRule(
resource_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List resources.',
operations=[
{
@ -69,8 +69,8 @@ resource_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'metadata',
check_str=base.SYSTEM_OR_PROJECT_READER_OR_STACK_USER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER_OR_STACK_USER,
scope_types=['project'],
description='Show resource metadata.',
operations=[
{
@ -83,8 +83,8 @@ resource_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'signal',
check_str=base.SYSTEM_OR_PROJECT_READER_OR_STACK_USER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER_OR_STACK_USER,
scope_types=['project'],
description='Signal resource.',
operations=[
{
@ -97,8 +97,8 @@ resource_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'mark_unhealthy',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Mark resource as unhealthy.',
operations=[
{
@ -111,8 +111,8 @@ resource_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show resource.',
operations=[
{

View File

@ -19,70 +19,96 @@ POLICY_ROOT = 'resource_types:%s'
resource_types_policies = [
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Nova::Flavor',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Cinder::EncryptedVolumeType',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Cinder::VolumeType',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Cinder::Quota',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::Quota',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Nova::Quota',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Octavia::Quota',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Manila::ShareType',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::ProviderNet',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::QoSPolicy',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::QoSBandwidthLimitRule',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::QoSDscpMarkingRule',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::QoSMinimumBandwidthRule',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::QoSMinimumPacketRateRule',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Neutron::Segment',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Nova::HostAggregate',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Cinder::QoSSpecs',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Cinder::QoSAssociation',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Keystone::*',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
# NOTE(tkajinam): Keystone does not yet support project scope SRBAC
# but we limit the scope to project one here to make
# this consistent with the scope enforcement in stack
# resources.
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Blazar::Host',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Octavia::Flavor',
check_str=base.RULE_PROJECT_ADMIN),
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project']),
policy.RuleDefault(
name=POLICY_ROOT % 'OS::Octavia::FlavorProfile',
check_str=base.RULE_PROJECT_ADMIN)
check_str=base.RULE_PROJECT_ADMIN,
scope_types=['project'])
]

View File

@ -31,7 +31,8 @@ deprecated_index = policy.DeprecatedRule(
service_policies = [
policy.RuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.SYSTEM_READER,
check_str=base.PROJECT_ADMIN,
scope_types=['project'],
deprecated_rule=deprecated_index
)
]

View File

@ -21,12 +21,6 @@ The software configuration API now support system scope and default roles.
POLICY_ROOT = 'software_configs:%s'
deprecated_global_index = policy.DeprecatedRule(
name=POLICY_ROOT % 'global_index',
check_str=base.RULE_DENY_EVERYBODY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_index = policy.DeprecatedRule(
name=POLICY_ROOT % 'index',
check_str=base.RULE_DENY_STACK_USER,
@ -55,8 +49,7 @@ deprecated_delete = policy.DeprecatedRule(
software_configs_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'global_index',
check_str=base.SYSTEM_READER,
scope_types=['system', 'project'],
check_str=base.RULE_DENY_EVERYBODY,
description='List configs globally.',
operations=[
{
@ -64,12 +57,11 @@ software_configs_policies = [
'method': 'GET'
}
],
deprecated_rule=deprecated_global_index
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List configs.',
operations=[
{
@ -81,8 +73,8 @@ software_configs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Create config.',
operations=[
{
@ -94,8 +86,8 @@ software_configs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show config details.',
operations=[
{
@ -107,8 +99,8 @@ software_configs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Delete config.',
operations=[
{

View File

@ -56,8 +56,8 @@ deprecated_delete = policy.DeprecatedRule(
software_deployments_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List deployments.',
operations=[
{
@ -69,8 +69,8 @@ software_deployments_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Create deployment.',
operations=[
{
@ -82,8 +82,8 @@ software_deployments_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show deployment details.',
operations=[
{
@ -95,8 +95,8 @@ software_deployments_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Update deployment.',
operations=[
{
@ -108,8 +108,8 @@ software_deployments_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Delete deployment.',
operations=[
{
@ -121,8 +121,8 @@ software_deployments_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'metadata',
check_str=base.SYSTEM_OR_PROJECT_READER_OR_STACK_USER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER_OR_STACK_USER,
scope_types=['project'],
description='Show server configuration metadata.',
operations=[
{

View File

@ -57,12 +57,6 @@ deprecated_generate_template = policy.DeprecatedRule(
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_global_index = policy.DeprecatedRule(
name=POLICY_ROOT % 'global_index',
check_str=base.RULE_DENY_EVERYBODY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_index = policy.DeprecatedRule(
name=POLICY_ROOT % 'index',
check_str=base.RULE_DENY_STACK_USER,
@ -206,8 +200,8 @@ deprecated_lookup = policy.DeprecatedRule(
stacks_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'abandon',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Abandon stack.',
operations=[
{
@ -220,8 +214,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Create stack.',
operations=[
{
@ -233,8 +227,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Delete stack.',
operations=[
{
@ -246,8 +240,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'detail',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List stacks in detail.',
operations=[
{
@ -259,8 +253,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'export',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Export stack.',
operations=[
{
@ -273,8 +267,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'generate_template',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Generate stack template.',
operations=[
{
@ -287,8 +281,7 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'global_index',
check_str=base.SYSTEM_READER,
scope_types=['system', 'project'],
check_str=base.RULE_DENY_EVERYBODY,
description='List stacks globally.',
operations=[
{
@ -296,12 +289,11 @@ stacks_policies = [
'method': 'GET'
}
],
deprecated_rule=deprecated_global_index
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List stacks.',
operations=[
{
@ -313,8 +305,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'list_resource_types',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List resource types.',
operations=[
{
@ -326,8 +318,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'list_template_versions',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List template versions.',
operations=[
{
@ -339,8 +331,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'list_template_functions',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List template functions.',
operations=[
{
@ -353,8 +345,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'lookup',
check_str=base.SYSTEM_OR_PROJECT_READER_OR_STACK_USER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER_OR_STACK_USER,
scope_types=['project'],
description='Find stack.',
operations=[
{
@ -366,8 +358,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'preview',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Preview stack.',
operations=[
{
@ -379,8 +371,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'resource_schema',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show resource type schema.',
operations=[
{
@ -392,8 +384,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show stack.',
operations=[
{
@ -405,8 +397,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'template',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Get stack template.',
operations=[
{
@ -419,8 +411,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'environment',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Get stack environment.',
operations=[
{
@ -433,8 +425,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'files',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Get stack files.',
operations=[
{
@ -447,8 +439,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Update stack.',
operations=[
{
@ -460,8 +452,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update_patch',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Update stack (PATCH).',
operations=[
{
@ -474,7 +466,7 @@ stacks_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update_no_change',
check_str='rule:%s' % (POLICY_ROOT % 'update_patch'),
scope_types=['system', 'project'],
scope_types=['project'],
description='Update stack (PATCH) with no changes.',
operations=[
{
@ -485,8 +477,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'preview_update',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Preview update stack.',
operations=[
{
@ -499,8 +491,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'preview_update_patch',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Preview update stack (PATCH).',
operations=[
{
@ -513,8 +505,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'validate_template',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Validate template.',
operations=[
{
@ -526,8 +518,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'snapshot',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Snapshot Stack.',
operations=[
{
@ -540,8 +532,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show_snapshot',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show snapshot.',
operations=[
{
@ -554,8 +546,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete_snapshot',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Delete snapshot.',
operations=[
{
@ -568,8 +560,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'list_snapshots',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List snapshots.',
operations=[
{
@ -582,8 +574,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'restore_snapshot',
check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
check_str=base.PROJECT_MEMBER,
scope_types=['project'],
description='Restore snapshot.',
operations=[
{
@ -596,8 +588,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'list_outputs',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='List outputs.',
operations=[
{
@ -610,8 +602,8 @@ stacks_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show_output',
check_str=base.SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
check_str=base.PROJECT_READER,
scope_types=['project'],
description='Show outputs.',
operations=[
{

View File

@ -7,7 +7,6 @@ actions_most_restricted:
- "cancel_update"
- "cancel_without_rollback"
allowed:
- "system_admin"
- "project_member"
denied:
- "stack_user"
@ -17,7 +16,6 @@ actions_restricted:
actions:
- "check"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
@ -36,7 +34,6 @@ cloud_formation_most_restricted:
- "EstimateTemplateCost"
- "DescribeStackResources"
allowed:
- "system_admin"
- "project_member"
denied:
- "stack_user"
@ -46,15 +43,14 @@ cloud_formation_restricted:
actions:
- "DescribeStackResource"
allowed:
- "system_admin"
- "project_member"
- "stack_user"
build_info_acl:
scope: "build_info"
actions:
- "build_info"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
@ -65,7 +61,6 @@ events_acl:
- "index"
- "show"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
@ -76,9 +71,8 @@ resource_least_restricted:
- "metadata"
- "signal"
allowed:
- "system_reader"
- "system_reader"
- "stack_user"
- "project_reader"
resource_restricted:
scope: "resource"
@ -86,7 +80,6 @@ resource_restricted:
- "index"
- "show"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
@ -96,7 +89,6 @@ resource_most_restricted:
actions:
- "mark_unhealthy"
allowed:
- "system_admin"
- "project_member"
denied:
- "stack_user"
@ -106,14 +98,19 @@ service_acl:
actions:
- "index"
allowed:
- "system_reader"
- "project_admin"
denied:
- "project_member"
- "stack_user"
software_configs_least_restricted:
software_configs_restricted_index:
scope: "software_configs"
actions:
- "global_index"
allowed:
- "system_reader"
denied:
- "system_admin"
- "project_admin"
- "stack_user"
software_configs_most_restricted:
scope: "software_configs"
@ -121,7 +118,6 @@ software_configs_most_restricted:
- "create"
- "delete"
allowed:
- "system_admin"
- "project_member"
denied:
- "stack_user"
@ -130,10 +126,8 @@ software_configs_restricted:
scope: "software_configs"
actions:
- "index"
- "create"
- "show"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
@ -145,7 +139,6 @@ software_deployments_most_restricted:
- "update"
- "delete"
allowed:
- "system_admin"
- "project_member"
denied:
- "stack_user"
@ -156,17 +149,16 @@ software_deployments_restricted:
- "index"
- "show"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
software_deployments_least_restricted:
scope: "software_deployments"
actions:
- "metadata"
allowed:
- "project_reader"
- "stack_user"
stacks_most_restricted:
@ -186,7 +178,6 @@ stacks_most_restricted:
- "delete_snapshot"
- "restore_snapshot"
allowed:
- "system_admin"
- "project_member"
denied:
- "stack_user"
@ -210,7 +201,6 @@ stacks_restricted:
- "list_outputs"
- "show_output"
allowed:
- "system_reader"
- "project_reader"
denied:
- "stack_user"
@ -219,15 +209,15 @@ stacks_restricted_index:
scope: "stacks"
actions:
- "global_index"
allowed:
denied:
- "system_admin"
- "project_admin"
stacks_open:
scope: "stacks"
actions:
- "lookup"
allowed:
- "system_reader"
- "project_reader"
- "stack_user"
@ -236,6 +226,4 @@ create_stacks:
actions:
- "create"
allowed:
- "system_admin"
- "project_admin"
- "project_member"

View File

@ -0,0 +1,263 @@
actions_most_restricted:
scope: "actions"
actions:
- "snapshot"
- "suspend"
- "resume"
- "cancel_update"
- "cancel_without_rollback"
allowed:
- "project_member"
denied:
- "project_reader"
- "stack_user"
- "system_admin"
actions_restricted:
scope: "actions"
actions:
- "check"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
cloud_formation_most_restricted:
scope: "cloudformation"
actions:
- "CreateStack"
- "DeleteStack"
- "UpdateStack"
allowed:
- "project_member"
denied:
- "project_reader"
- "stack_user"
- "system_admin"
cloud_formation_restricted:
scope: "cloudformation"
actions:
- "ListStacks"
- "DescribeStacks"
- "DescribeStackEvents"
- "GetTemplate"
- "EstimateTemplateCost"
- "DescribeStackResources"
- "ValidateTemplate"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
cloud_formation_least_restricted:
scope: "cloudformation"
actions:
- "DescribeStackResource"
allowed:
- "project_reader"
- "stack_user"
denied:
- "system_admin"
build_info_acl:
scope: "build_info"
actions:
- "build_info"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
events_acl:
scope: "events"
actions:
- "index"
- "show"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
resource_least_restricted:
scope: "resource"
actions:
- "metadata"
- "signal"
allowed:
- "stack_user"
- "project_reader"
denied:
- "system_admin"
resource_restricted:
scope: "resource"
actions:
- "index"
- "show"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
resource_most_restricted:
scope: "resource"
actions:
- "mark_unhealthy"
allowed:
- "project_member"
denied:
- "project_reader"
- "stack_user"
- "system_admin"
service_acl:
scope: "service"
actions:
- "index"
allowed:
- "project_admin"
denied:
- "system_admin"
- "project_member"
- "stack_user"
software_configs_restricted_index:
scope: "software_configs"
actions:
- "global_index"
denied:
- "system_admin"
- "project_admin"
software_configs_most_restricted:
scope: "software_configs"
actions:
- "create"
- "delete"
allowed:
- "project_member"
denied:
- "stack_user"
software_configs_restricted:
scope: "software_configs"
actions:
- "index"
- "show"
allowed:
- "project_reader"
denied:
- "stack_user"
software_deployments_most_restricted:
scope: "software_deployments"
actions:
- "create"
- "update"
- "delete"
allowed:
- "project_member"
denied:
- "stack_user"
software_deployments_restricted:
scope: "software_deployments"
actions:
- "index"
- "show"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
software_deployments_least_restricted:
scope: "software_deployments"
actions:
- "metadata"
allowed:
- "project_reader"
- "stack_user"
denied:
- "system_admin"
stacks_most_restricted:
scope: "stacks"
actions:
- "abandon"
- "create"
- "delete"
- "export"
- "generate_template"
- "update"
- "update_patch"
- "preview_update"
- "preview_update_patch"
- "validate_template"
- "snapshot"
- "delete_snapshot"
- "restore_snapshot"
allowed:
- "project_member"
denied:
- "project_reader"
- "stack_user"
- "system_admin"
stacks_restricted:
scope: "stacks"
actions:
- "detail"
- "index"
- "list_resource_types"
- "list_template_versions"
- "list_template_functions"
- "preview"
- "resource_schema"
- "show"
- "template"
- "environment"
- "files"
- "show_snapshot"
- "list_snapshots"
- "list_outputs"
- "show_output"
allowed:
- "project_reader"
denied:
- "stack_user"
- "system_admin"
stacks_restricted_index:
scope: "stacks"
actions:
- "global_index"
denied:
- "system_admin"
- "project_admin"
stacks_open:
scope: "stacks"
actions:
- "lookup"
allowed:
- "project_reader"
- "stack_user"
denied:
- "system_admin"
create_stacks:
scope: "stacks"
actions:
- "create"
allowed:
- "project_member"
denied:
- "project_reader"
- "system_admin"

View File

@ -78,7 +78,7 @@ class TestPolicyEnforcer(common.HeatTestCase):
def test_deprecated_policies(self, **kwargs):
self._test_legacy_rbac_policies(**kwargs)
@ddt.file_data('policy/test_acl_personas.yaml')
@ddt.file_data('policy/test_new_acl_personas.yaml')
@ddt.unpack
def test_secure_rbac_policies(self, **kwargs):
self.fixture.config(group='oslo_policy', enforce_scope=True)

View File

@ -0,0 +1,6 @@
---
features:
- |
Heat policies have been modified to isolate the system and project level
APIs policy. Because of this change, system users will not be allowed to
perform any operations on project level resources.