Role based access control in Pulp Python is configured using access policies for the following viewset_names:
content/python/packagesdistributions/python/pypipublications/python/pypiremotes/python/pythonrepositories/python/pythonrepositories/python/python/versionspypi/rootpypi/simplepypi/pypipypi/legacy
This document will focus on describing the default access policies for the PyPI specific APIs and how they may be customized. The access policies for the Pulp APIs follow the same scheme as the Pulp File plugin which can be read about here: Pulp File RBAC. Use the Pulp CLI to follow along with the examples here.
!!! note This feature is currently in tech preview and is subject to change in future releases.
By default, the read APIs of the index are accessible to any user, authenticated or not, while the upload APIs require permission to modify the backing repository.
"statements": [
{
"action": ["list", "retrieve"],
"principal": "*",
"effect": "allow",
},
{
"action": ["create"],
"principal": "authenticated",
"effect": "allow",
"condition": "index_has_repo_perm:python.modify_pythonrepository",
},
],The root and pypi endpoints are solely read APIs while the legacy endpoint is solely an upload API. The
simple endpoint is both a read and upload API and thus has two actions in its access policy. The defaults on
these endpoints match the default behavior found on public repositories like PyPI and ensure the maximum compatibility
with Python tooling.
Also by default, the download links for the Python packages in the index are accessible by anyone. If you wish to protect who can download Python content then do so by adding a content guard to your distribution.
pulp python distribution update --name foo --content-guard $CONTENT_GUARD_HREF_OR_NAMEExample pulp-cli workflow to add RBAC-based access to download from the index:
pulp content-guard rbac create --name foo-guard
pulp content-guard rbac assign --name foo-guard --user user1 --user user2 --group group1 --group group2
CG_HREF=$(pulp content-guard rbac list --name foo-guard | jq -r ".[0].pulp_href")
pulp python distribution update --name foo --content-guard $CG_HREFLinks for using basic auth with various python package tools to pass the new RBACContentGuard:
!!! warning
The PyPI access policies do not support creation_hooks or queryset_scoping.
The PackagePermissionGuard provides fine-grained, package-level access control within a single distribution/index. Unlike RBACContentGuard which applies to all packages in a distribution, PackagePermissionGuard allows you to control download and upload permissions for individual PyPI packages.
pulp content-guard package-permission create --name my-package-guardPackagePermissionGuard uses two separate policies:
download_policy: Controls who can download specific packagesupload_policy: Controls who can upload specific packages
Both policies map package names (normalized) to lists of user/group PRNs.
Use the add action to grant users/groups access to packages:
# Add download permissions for multiple packages
pulp content-guard package-permission add \
--name my-package-guard \
--packages shelf-reader django \
--users-groups prn:core.user:alice prn:core.group:developers \
--policy-type download
# Add upload permissions
pulp content-guard package-permission add \
--name my-package-guard \
--packages shelf-reader \
--users-groups prn:core.user:bob \
--policy-type uploadUse the remove action to revoke access:
# Remove specific users/groups from a package
pulp content-guard package-permission remove \
--name my-package-guard \
--packages shelf-reader \
--users-groups prn:core.user:alice \
--policy-type download
# Remove all permissions for a package (use '*' in users-groups)
pulp content-guard package-permission remove \
--name my-package-guard \
--packages django \
--users-groups '*' \
--policy-type download
# Remove all packages from a policy (use '*' in packages)
pulp content-guard package-permission remove \
--name my-package-guard \
--packages '*' \
--users-groups '' \
--policy-type download-
Downloads: During downloads the guard's
permit()method checks thedownload_policyto see if there is a policy for the package. If no policy the download is permited. If there is one it then checks that the user of the request is in the policy list for that package. -
Uploads: For uploads, the endpoint's access policy checks the
upload_policyto see if the user/group has permission for the package being uploaded. If the package or user is not in the policy the upload is denied.
!!! note
For the content guard to properly protect uploads the legacy and simple AccessPolies must
use the package_permission_check condition for their create action. This is the current
default with a fallback to index_has_repo_perm when there is no content guard on the distro.
Pulp Python comes with two specific access condition methods that can be used in the PyPI access policies.
This access condition checks if the user has the supplied permission on the index's backing repository. If the index
has no repository this will return True. If no permission is specified for the method then it will use
python.view_pythonrepository as its default. This is the default condition that is used for the upload APIs with
the modify python repository permission.
This access condition checks if the user has the supplied permission on the index (distribution) itself. If no
permission is specified for the method then it will use python.view_pythondistribution as its default.
This access condition checks PackagePermissionGuard for package-level permissions. It extracts the package name from the request (from URL path for downloads,from filename for uploads) and checks if the user/group has permission for that specific package in the guard's policy. This condition is used by default in PyPI upload endpoints to enable package-level upload control when a PackagePermissionGuard is attached to the distribution.
- For downloads: Checks
download_policyand denies only if package in policy and user/group is not. - For uploads: Checks
upload_policyand denies access if package not in policy or user/group not allowed
!!! note All access condition methods are compatible with the Pulp Domains feature.