Allow customizing roles to use JSON RPC

This change allows customizing the roles required for JSON RPC, to use
any roles different from the 'admin' role.

There is a plan, as part of SRBAC effort, to replace usage of the admin
role in each service by the new service role, which has more restricted
access, and we expect the ironic service user would require only
the service role once this work is done.

Change-Id: I143203be7827f73daba32e7c084c5807063ff91d
This commit is contained in:
Takashi Kajinami 2022-01-26 21:24:07 +09:00
parent 38f00d1d7d
commit 4ea8df8e21
4 changed files with 31 additions and 3 deletions

View File

@ -51,6 +51,9 @@ opts = [
secret=True,
help=_("Password to use for HTTP Basic authentication "
"client requests.")),
cfg.ListOpt('allowed_roles',
default=['admin'],
help=_("List of roles allowed to use JSON RPC")),
]

View File

@ -146,9 +146,10 @@ class WSGIService(service.Service):
if json_rpc.auth_strategy() == 'keystone':
roles = (request.headers.get('X-Roles') or '').split(',')
if 'admin' not in roles:
LOG.debug('Roles %s do not contain "admin", rejecting '
'request', roles)
allowed_roles = cfg.CONF.json_rpc.allowed_roles
if set(roles).isdisjoint(allowed_roles):
LOG.debug('Roles %s do not contain any of %s, rejecting '
'request', roles, allowed_roles)
body = {'error': {'code': 403, 'message': _('Forbidden')}}
return webob.Response(status_code=403, json_body=body)(
environment, start_response)

View File

@ -293,11 +293,30 @@ class TestService(base.IronicLibTestCase):
self._request('success', {'context': self.ctx, 'x': 42},
expected_error=401)
def test_authenticated_with_alloed_role(self):
self.config(auth_strategy='keystone', group='json_rpc')
self.config(allowed_roles=['allowed', 'ignored'], group='json_rpc')
self.service = server.WSGIService(FakeManager(), self.serializer,
FakeContext)
self.app = self.server_mock.call_args[0][2]
self._request('success', {'context': self.ctx, 'x': 42},
expected_error=401,
headers={'Content-Type': 'application/json',
'X-Roles': 'allowed,denied'})
def test_authenticated_no_admin_role(self):
self.config(auth_strategy='keystone', group='json_rpc')
self._request('success', {'context': self.ctx, 'x': 42},
expected_error=403)
def test_authenticated_no_allowed_role(self):
self.config(auth_strategy='keystone', group='json_rpc')
self.config(allowed_roles=['allowed', 'ignored'], group='json_rpc')
self._request('success', {'context': self.ctx, 'x': 42},
expected_error=403,
headers={'Content-Type': 'application/json',
'X-Roles': 'denied,notallowed'})
@mock.patch.object(server.LOG, 'debug', autospec=True)
def test_mask_secrets(self, mock_log):
data = {'ipmi_username': 'admin', 'ipmi_password': 'secret'}

View File

@ -0,0 +1,5 @@
---
features:
- |
The new ``[json_rpc] allowed_roles`` parameter has been added. This
parameter determines the list of roles allowed to use JSON RPC.