Add RBAC content guard to pulpcore
Content guards are added to distributions and are used to protect who can download (and view) content available in that distribution from the content app. Users create content guard instances with specific settings for each distribution they want to protect. RBAC in Pulp is provided by Django and DRF and currently has no relation to content guards, so users can protect who can manage content in Pulp using RBAC, but not who can download it. There is a need for an RBAC enabled content guard that protects content based on RBAC permissions.
Add a new RBAC content guard that would ship by default in pulpcore. The access policy for these content guard instances should be customizable by the user and if not set should default to the policy used by the distribution. Some requests go through a plugin's extended REST API first and then redirect to the content app, so an option to authorized requests based on redirection origin should be added to the content guard.
Updated by bmbouter over 2 years ago
AccessPolicies are global, but allow for object level permissions to be checked. So what if the permission was named
dowload and it had object-level permissions relating an instance of a distribution with a ContentGuard? Or maybe it should be on the content guard itself ..... ?
Updated by gerrod over 2 years ago
Talking it over with bmbouter, I think the best implementation would be to add a new permission called
can_download to the RBAC content guard that will determine if a user can download content from a distribution. When creating an RBAC content guard you would specify the users and groups to receive the
can_download permission for that instance of the guard. Then that content guard can be added to any distribution where you want those set of users to be able to download from.
The RBAC content guard would preform authentication and authorization for requests to the content app. It would create a 'fake' DRF view that would convert the aiohttp request to a django request and use the view's authentication and authorization methods defined by DRF settings. Example from container plugin (https://github.com/pulp/pulp_container/blob/master/pulp_container/app/authorization.py#L158) The authentication check will go through each authentication class one by one till the user is found. Then authorization will do a permission check on the user to see if they have the
can_download permission for that content guard.
Additional fields that could be added to content guard:
authentication_classes- a string array listing all the auth classes to use for authenticating the user for the content guard, possible values would come from this setting https://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme. Default empty list would use all classes listed in that setting.
permission_classes- a string array listing all the permission classes to use for authorization, possible values would be the default permissions in DRF(https://www.django-rest-framework.org/api-guide/permissions/#api-reference) and
AccessPolicyFromDB(https://docs.pulpproject.org/pulpcore/plugins/plugin-writer/concepts/rbac/access_policy.html#viewset-enforcement). Default would be
additional_permissions- a string array listing additional permission checks needed on top of
can_downloadpermission. These permissions would use the objects associated with this content guard (the distribution for the request, the repository of the distribution, the publication of the distribution). This field's behavior might not be easy to define with all the permissions available in Pulp.