Implement system scoped RBAC for utility APIs

This commit updates the policies for baremetal utility policies to understand
scope checking and account for a read-only role. This is part of a broader
series of changes across OpenStack to provide a consistent RBAC experience and
improve security.

Also adds duplicate Heartbeat and Lookup test classes with the middleware
scope enforcement enabled and enforced, to ensure that we do not adversely
impact these special API endpoints.

Change-Id: I89176b3adf1489e12493c62b908bf135c912e017
This commit is contained in:
Lance Bragstad 2020-11-18 21:31:24 +00:00 committed by Julia Kreger
parent ff883486e6
commit 69b28ca99c
2 changed files with 63 additions and 8 deletions
ironic
common
tests/unit/api/controllers/v1

@ -95,6 +95,8 @@ default_policies = [
'role:admin or role:administrator',
description='Legacy rule for cloud admin access'),
# is_public_api is set in the environment from AuthPublicRoutes
# TODO(TheJulia): Once legacy policy rules are removed, is_public_api
# can be removed from the code base.
policy.RuleDefault('public_api',
'is_public_api:True',
description='Internal flag for public API routes'),
@ -1023,17 +1025,41 @@ vendor_passthru_policies = [
),
]
deprecated_ipa_heartbeat = policy.DeprecatedRule(
name='baremetal:node:ipa_heartbeat',
check_str='rule:public_api'
)
deprecated_ipa_lookup = policy.DeprecatedRule(
name='baremetal:driver:ipa_lookup',
check_str='rule:public_api'
)
deprecated_utility_reason = """
The baremetal utility API is now aware of system scope and default
roles.
"""
# NOTE(TheJulia): Empty check strings basically mean nothing to apply,
# and the request is permitted.
utility_policies = [
policy.DocumentedRuleDefault(
'baremetal:node:ipa_heartbeat',
'rule:public_api',
'Send heartbeats from IPA ramdisk',
[{'path': '/heartbeat/{node_ident}', 'method': 'POST'}]),
name='baremetal:node:ipa_heartbeat',
check_str='',
description='Receive heartbeats from IPA ramdisk',
operations=[{'path': '/heartbeat/{node_ident}', 'method': 'POST'}],
deprecated_rule=deprecated_ipa_heartbeat,
deprecated_reason=deprecated_utility_reason,
deprecated_since=versionutils.deprecated.WALLABY
),
policy.DocumentedRuleDefault(
'baremetal:driver:ipa_lookup',
'rule:public_api',
'Access IPA ramdisk functions',
[{'path': '/lookup', 'method': 'GET'}]),
name='baremetal:driver:ipa_lookup',
check_str='',
description='Access IPA ramdisk functions',
operations=[{'path': '/lookup', 'method': 'GET'}],
deprecated_rule=deprecated_ipa_lookup,
deprecated_reason=deprecated_utility_reason,
deprecated_since=versionutils.deprecated.WALLABY
),
]
volume_policies = [

@ -19,6 +19,7 @@ from http import client as http_client
from unittest import mock
import fixtures
from keystonemiddleware import auth_token
from oslo_config import cfg
from oslo_utils import uuidutils
@ -338,3 +339,31 @@ class TestHeartbeat(test_api_base.BaseApiTest):
headers={api_base.Version.string: '1.67'},
expect_errors=True)
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
@mock.patch.object(auth_token.AuthProtocol, 'process_request',
lambda *_: None)
class TestLookupScopedRBAC(TestLookup):
"""Test class to execute the Lookup tests with RBAC enforcement."""
def setUp(self):
super(TestLookupScopedRBAC, self).setUp()
cfg.CONF.set_override('enforce_scope', True, group='oslo_policy')
cfg.CONF.set_override('enforce_new_defaults', True,
group='oslo_policy')
cfg.CONF.set_override('auth_strategy', 'keystone')
@mock.patch.object(auth_token.AuthProtocol, 'process_request',
lambda *_: None)
class TestHeartbeatScopedRBAC(TestHeartbeat):
"""Test class to execute the Heartbeat tests with RBAC enforcement."""
def setUp(self):
super(TestHeartbeatScopedRBAC, self).setUp()
cfg.CONF.set_override('enforce_scope', True, group='oslo_policy')
cfg.CONF.set_override('enforce_new_defaults', True,
group='oslo_policy')
cfg.CONF.set_override('auth_strategy', 'keystone')