diff --git a/doc/source/admin/secure-rbac.rst b/doc/source/admin/secure-rbac.rst index 075dd1181b..5b5f3b42ac 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 + +.. 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 + +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 4dbcea5bd1..68b1d318ae 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 e9bb78ce20..70cd6e0300 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 5a2612f0f2..364de02633 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 ff872c23ff..1fca38acdc 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 0000000000..c9d81b1dcc --- /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 `_ + 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.