diff options
author | Julia Kreger <juliaashleykreger@gmail.com> | 2021-03-04 11:12:17 -0800 |
---|---|---|
committer | Julia Kreger <juliaashleykreger@gmail.com> | 2021-03-17 15:27:46 +0000 |
commit | 426353c3f5665cfecaafe6f6ec3f1b583badd13d (patch) | |
tree | 737d19550d6ab7114b1c5a5a7cc20ed4ffb1461a | |
parent | 043de26884c4b0014b019d1112ea8af9fad37d30 (diff) | |
download | ironic-426353c3f5665cfecaafe6f6ec3f1b583badd13d.tar.gz |
Deprecate legacy policies, update project scoped docs
Deprecates legacy policies which will be removed at a later point in
time. Notes these in a release note which covers project scoped access
enablement, and updates the Secure RBAC docs to cover additional details
Special thanks to Rammstein Radio on Pandora, for without this and all
of the amazing artists it brought to my coding jam sessions, this effort
would not have reached any sort of conclusion in the relatively short
time for such a massive amount of work.
Change-Id: I3bf0fa0de07e19d6058f0299e7abbff91b48b360
-rw-r--r-- | doc/source/admin/secure-rbac.rst | 37 | ||||
-rw-r--r-- | ironic/common/context.py | 3 | ||||
-rw-r--r-- | ironic/common/glance_service/service_utils.py | 7 | ||||
-rw-r--r-- | ironic/common/policy.py | 53 | ||||
-rw-r--r-- | ironic/drivers/modules/agent_base.py | 4 | ||||
-rw-r--r-- | releasenotes/notes/project-scoped-rbac-063c44ba593bb82a.yaml | 45 |
6 files changed, 124 insertions, 25 deletions
diff --git a/doc/source/admin/secure-rbac.rst b/doc/source/admin/secure-rbac.rst index 075dd1181..5b5f3b42a 100644 --- a/doc/source/admin/secure-rbac.rst +++ b/doc/source/admin/secure-rbac.rst @@ -191,13 +191,44 @@ from "Does the user user broadly has access to the API?" to "Does user have access to the node, and then do they have access to the specific resource?". +What is an owner or lessee? +--------------------------- + +An ``owner`` or ``lessee`` is the project which has been assigned baremetal +resources. Generally these should be service projects as opposed to a project +dedicated to a specific user. This will help prevent the need to involve a +``system`` scoped administrator from having to correct ownership records +should a project need to be removed due to an individual's departure. + +The underlying ``project_id`` is used to represent and associate the owner or +lessee. + How do I assign an owner? ------------------------- -.. todo: need to add information on the owner assignment - and also cover what this generally means... maybe? +.. code-block:: console + + # baremetal node set --owner <project_id> <node> + +.. note:: + With the default access policy, an ``owner`` is able to change + the assigned ``lessee`` of a node. However the ``lessee`` is unable to do + the same. How do I assign a lessee? ------------------------- -.. todo: Need to cover how to assign a lessee. +.. code-block:: console + + # baremetal node set --lessee <project_id> <node> + +What is the difference between an owner and lessee? +--------------------------------------------------- + +This is largely covered in `How Project Scoped Works`_ although +as noted it is largely in means of access. A ``lessee`` is far more +restrictive and an ``owner`` may revoke access to ``lessee``. + +Access to the underlying baremetal node is not exclusive between the +``owner`` and ``lessee``, and this use model expects that some level of +communication takes place between the appropriate parties. diff --git a/ironic/common/context.py b/ironic/common/context.py index 4dbcea5bd..68b1d318a 100644 --- a/ironic/common/context.py +++ b/ironic/common/context.py @@ -52,6 +52,9 @@ class RequestContext(context.RequestContext): def get_admin_context(): """Create an administrator context.""" + # TODO(TheJulia): Revise in Xena, is_admin should + # no longer be a default, much less passed as it is + # deprecated. context = RequestContext(auth_token=None, project_id=None, is_admin=True, diff --git a/ironic/common/glance_service/service_utils.py b/ironic/common/glance_service/service_utils.py index e9bb78ce2..70cd6e030 100644 --- a/ironic/common/glance_service/service_utils.py +++ b/ironic/common/glance_service/service_utils.py @@ -110,8 +110,15 @@ def is_image_available(context, image): # The presence of an auth token implies this is an authenticated # request and we need not handle the noauth use-case. if hasattr(context, 'auth_token') and context.auth_token: + # We return true here since we want the *user* request context to + # be able to be used. return True + # TODO(TheJulia): This is potentially a bug below. Admin context doesn't + # necessarilly mean the object is *actually* accessible. We should likely + # just ask glance... Although everything should also have an auth_token + # as noted above. Ultimately we need to tease the is_admin logic apart + # and treat things appropriately by checking them as needed. if getattr(image, 'visibility', None) == 'public' or context.is_admin: return True diff --git a/ironic/common/policy.py b/ironic/common/policy.py index 5a2612f0f..364de0263 100644 --- a/ironic/common/policy.py +++ b/ironic/common/policy.py @@ -148,13 +148,19 @@ TARGET_PROPERTIES_READER = ( '(' + SYSTEM_READER + ') or (role:admin)' ) +pre_rbac_deprecated_reason = 'Pre-RBAC default rule. This rule does not support scoping system scoping and as such is deprecated.' # noqa + default_policies = [ # Legacy setting, don't remove. Likely to be overridden by operators who # forget to update their policy.json configuration file. # This gets rolled into the new "is_admin" rule below. policy.RuleDefault('admin_api', 'role:admin or role:administrator', - description='Legacy rule for cloud admin access'), + description='Legacy rule for cloud admin access', + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason + ), # 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. @@ -178,22 +184,40 @@ default_policies = [ # TODO(TheJulia): Lets nuke demo from high orbit. policy.RuleDefault('is_member', '(project_domain_id:default or project_domain_id:None) and (project_name:demo or project_name:baremetal)', # noqa - description='May be used to restrict access to specific projects'), # noqa + description='May be used to restrict access to specific projects', # noqa + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason), policy.RuleDefault('is_observer', 'rule:is_member and (role:observer or role:baremetal_observer)', # noqa - description='Read-only API access'), + description='Read-only API access', + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason), policy.RuleDefault('is_admin', 'rule:admin_api or (rule:is_member and role:baremetal_admin)', # noqa - description='Full read/write API access'), + description='Full read/write API access', + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason), policy.RuleDefault('is_node_owner', 'project_id:%(node.owner)s', - description='Owner of node'), + description='Owner of node', + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason), policy.RuleDefault('is_node_lessee', 'project_id:%(node.lessee)s', - description='Lessee of node'), + description='Lessee of node', + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason), policy.RuleDefault('is_allocation_owner', 'project_id:%(allocation.owner)s', - description='Owner of allocation'), + description='Owner of allocation', + deprecated_for_removal=True, + deprecated_since=versionutils.deprecated.WALLABY, + deprecated_reason=pre_rbac_deprecated_reason), ] # NOTE(tenbrae): to follow policy-in-code spec, we define defaults for @@ -582,21 +606,6 @@ node_policies = [ deprecated_reason=deprecated_node_reason, deprecated_since=versionutils.deprecated.WALLABY ), - # TODO(TheJulia): So multiple additional fields need policies. This needs - # to be reviewed/audited/addressed. - # * Get ability on last_error - policy added - # * Get ability on reservation (conductor names) - policy added - # * get ability on driver_internal_info (internal addressing) added - # * ability to get driver_info - policy added - # * ability to set driver_info - policy added - # * ability to set properties. - added - # * ability to set chassis_uuid - added - # * ability to set instance_uuid - added - # * ability to set a lessee - default only to admin or owner. added - # * ability to set driver/*_interface - added - # * ability to set network_data - added - # * ability to set conductor_group -added - # * ability to set name -added policy.DocumentedRuleDefault( name='baremetal:node:update_instance_info', check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN, diff --git a/ironic/drivers/modules/agent_base.py b/ironic/drivers/modules/agent_base.py index ff872c23f..1fca38acd 100644 --- a/ironic/drivers/modules/agent_base.py +++ b/ironic/drivers/modules/agent_base.py @@ -1345,6 +1345,10 @@ class AgentDeployMixin(HeartbeatMixin, AgentOobStepsMixin): image_source = node.instance_info.get('image_source') try: context = task.context + # TODO(TheJulia): Uhh, is_admin likely needs to be + # addressed in Xena as undesirable behavior may + # result, or just outright break in an entirely + # system scoped configuration. context.is_admin = True glance = image_service.GlanceImageService( context=context) diff --git a/releasenotes/notes/project-scoped-rbac-063c44ba593bb82a.yaml b/releasenotes/notes/project-scoped-rbac-063c44ba593bb82a.yaml new file mode 100644 index 000000000..c9d81b1dc --- /dev/null +++ b/releasenotes/notes/project-scoped-rbac-063c44ba593bb82a.yaml @@ -0,0 +1,45 @@ +--- +features: + - | + Adds capability to use ``project`` scoped requests in concert with + ``system`` scoped requests for a composite Role Based Access Control + (RBAC) model. As Ironic is mainly an administrative service, + this capability has only been extended to API endpoints which are + not purely administrative in nature. This consists of the following + API endpoints: nodes, ports, portgroups, volume connectors, volume + targets, and allocations. + - | + Project ``scoped`` requests for baremetal allocations, will automatically + record the ``project_id`` of the requestor as the ``owner`` of the node. +deprecations: + - > + Pre-RBAC support rules have been deprecated. These consist of: + * admin_api + * is_member + * is_observer + * is_node_owner + * is_node_lessee + * is_allocation_owner + + These rules will likely be removed in the Xena development cycle. + Operators are advised to review any custom policy rules for these + rules and move to the `Secure Role Based Access Controls <https://docs.openstack.org/ironic/latest/admin/secure-rbac.html>`_ + model. +issues: + - | + The addition of both ``project`` and ``system`` scoped Role Based Access + controls does add additional database queries when linked resources are + accessed. Example, when attempting to access a ``port`` or ``portgroup``, + the associated node needs to be checked as this helps govern overall + object access to the object for ``project`` scoped requests. This does not + impact ``system`` scoped requests. Operators who adopt project scoped + access may find it necessary to verify or add additional database indexes + in relation to the node ``uuid`` column as well as ``node_id`` field in + any table which may recieve heavy project query scope activity. + The ``ironic`` project anticipates that this will be a future work item + of the project to help improve database performance. +upgrade: + - | + Legacy policy rules have been deprecated. Operators are advised to review + and update any custom policy files in use. Please see + `Secure Role Based Access Controls`_ for more information. |