
This guide covers the security levers of Pulp: who can read or write (RBAC), who can download (content guards), what enters your repositories (filters), and how to guarantee integrity (signing). Intended audience: administrators who expose Pulp to several teams or in production. Prerequisites: a working Pulp instance and the CLI configured (see Installing Pulp). You will also see, plainly, what Pulp does not do natively when it comes to software supply chain security.
The security of an artifact manager comes down to three questions: who accesses what, what you let in, and can you trust what is stored. Pulp answers all three, but in its own way, with building blocks to assemble rather than a turnkey dashboard.
What you will learn
- Restrict access with RBAC and its fine-grained roles.
- Protect downloads with content guards.
- Filter what comes in with
--includesand--excludes. - Guarantee integrity with content signing.
- Place Pulp honestly against vulnerability quarantine.
Controlling access with RBAC
Pulp includes a very granular role-based access control (RBAC). Each plugin brings its own roles, so you can authorize a team on the Python repositories without opening the RPM ones. The instance ships with more than 160 predefined roles out of the box.
pulp role list --limit 5Roles follow an explicit naming scheme, for example python.pythonrepository_owner (full power over Python repositories) or rpm.rpmremote_viewer (read-only access to RPM remotes). A role is assigned to a user or to a group, on a specific object or globally.
-
Create a dedicated service user for a team or a pipeline:
Terminal window pulp user create --username ci-python --password "MotDePasseCI" -
Assign it a targeted role, here the management of Python repositories:
Terminal window pulp user role-assignment add \--username ci-python \--role "python.pythonrepository_owner" \--object ""The empty object (
"") grants the role at the global level; you can also restrict it to a specific repository through its href. The least privilege principle applies: a pipeline only receives the rights it needs.
Protecting downloads with content guards
RBAC governs the API. To control who downloads the distributed content, Pulp uses content guards, attached to a distribution. Several types coexist:
| Content guard | Controls | Use case |
|---|---|---|
| RBAC | Based on Pulp roles | Private repository reserved for a team |
| Header | An expected HTTP header | Filtering done by an upstream proxy |
| x509 | A client certificate | Access through mutual certificates (mTLS) |
| Composite | A combination of the above | Multi-criteria policies |
An RBAC content guard attached to a distribution turns a public repository into an authenticated one: only users with the right role get the files. This is the access denial mechanism at the distribution level.
Filtering what enters your repositories
The first line of supply chain defense is to not copy everything. Remotes accept --includes and --excludes filters that define an allowlist or a denylist of packages to synchronize.
pulp python remote create \ --name pypi-maitrise \ --url https://pypi.org/ \ --includes '["requests", "urllib3", "certifi"]' \ --excludes '["requests<2.31.0"]'Here, only three packages are synchronized, and the vulnerable versions of requests (before 2.31.0) are excluded from the repository. You control the exact inventory your machines can install, instead of relaying the whole upstream.
Guaranteeing integrity with signing
To prove that an artifact has not been tampered with, Pulp relies on signing services: signing mechanisms declared in the instance, which run a script backed by a GPG key. Container images follow another path, the Cosign signature being produced on the client side, with Pulp merely hosting it.
pulp signing-service listOnce a signing service is declared, several plugins use it: pulp_rpm signs the repository metadata and pulp_container signs the container manifests. Cosign signatures of images, for their part, are copied at synchronization and verified by the client. Combined with filtering at the entrance and Trivy scanning, signing closes the chain of trust. The full implementation, with Cosign for images and a GPG signing service for manifests, RPMs and collections, is detailed in the guide Signing Pulp artifacts.
Filtering on the presence of a signature is not verifying it
When syncing, Pulp can keep only the images that come with a signature,
through the signed_only: true parameter of the request. It does not
verify that signature, and the field's own documentation says it word for
word: "Signatures are not verified". A forged signature, or one produced
by any key at all, therefore passes this filter.
Verification stays on the client side, with cosign verify or podman's
policy.json policy. The filter rules out unsigned content; it says
nothing about who signed, and confusing the two buys a confidence that
nothing backs.
Immutable versioning, a safety net
Each synchronization or upload creates an immutable repository version. A distribution points to a specific version: if a compromised package is published by mistake, you roll back to the previous version with one command, without restoring a backup. This native traceability is a security asset that is often underrated.
What Pulp does not do: vulnerability quarantine
Let us be clear to avoid a false expectation: Pulp does not ship with automatic quarantine of vulnerable packages. There is no native equivalent to the application firewall of Nexus (blocking a component based on its CVE score) or to the curation of Artifactory Xray.
Pulp provides the building blocks to build this guarantee, but you assemble the policy yourself:
- Filter at the entrance with
--includes/--excludes. - Scan with an external tool such as Trivy in CI, blocking the promotion of a vulnerable artifact.
- Promote only validated content to a production repository.
- Restrict access with RBAC and content guards.
This model takes more integration work than a commercial solution, but it relies entirely on open source tools and stays fully under your control.
Adding an artifact firewall upstream
To get closer to real admission control, you can place an artifact firewall such as
Varnish Orca in front of Pulp. Orca is a vendor-agnostic virtual registry: its
backend (remotes.url) accepts any HTTP registry, Pulp included. The
flow becomes client -> Orca (allow/deny/quarantine decision) -> Pulp.
In the lab, Orca does proxy Pulp (PyPI index and download of artifacts served
through Orca). The most direct setup is the container registry
(/v2/ at the root, like a standard OCI registry); for PyPI, Orca's
redirect wrapper requires aligning CONTENT_ORIGIN. The blocking
decision itself remains a Premium feature of Orca.
Hands-on practice
The lab asks you to create a publishing account that can upload to a single repository, and nothing else. The validation covers both halves of the contract: what the account can do, and what it must not be able to do. It therefore checks that the account uploads to its repository, and that it fails to create another one or to touch a container repository. Since a new Pulp account is already read-only, this second half is what distinguishes a targeted role from an account with no rights.
Key takeaways
- Pulp RBAC offers more than 160 fine-grained roles, per plugin, to apply least privilege.
- Content guards (RBAC, header, x509, composite) control who downloads the distributed content.
- The
--includes/--excludesfilters control what enters your repositories. - Signing services (GPG) sign metadata and manifests on the server side, Cosign signs images on the client side, but nothing is signed by default.
- Pulp has no native CVE quarantine: you build it with an external scanner and a promotion policy.
Knowledge check
Eight questions on the two halves of an access contract: what an account can do, what it must not be able to do, and what Pulp does not do natively.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Signing Pulp artifacts with Cosign and GPG
A new full quiz with random questions
Work again only on the questions you missed