Controlling Which Packages Users Can Install
By the end of this lesson, you will be able to:
- Explain why controlling package installation matters for organizational security
- Distinguish between blocklist rules and curated (allowlist) sources
- Describe the criteria blocklist rules can use to block packages
- Explain why curated sources should be anchored with a snapshot date
Introduction
The threat of real-world package vulnerability exploitation is a genuine concern for security professionals. Your ability to prevent malicious or insecure packages from being installed is necessary to protect your organization. Package Manager supports this directly by giving you control over which packages users are allowed to install.
There are two complementary mechanisms for this control: blocklist rules and curated sources. Blocklist rules deny access to specific packages even if they exist in a repository, based on criteria you define. Curated sources take the opposite approach, exposing only an explicitly approved set of packages and nothing else. Understanding when to reach for each is the focus of this lesson, and the accompanying lab has you configure both.
- Reading time: 10 minutes
- Documentation reading time: 5 minutes
- Hands-on exercise time: 15 minutes
Blocklist Rules: Denying Specific Packages
A blocklist denies access to packages that would otherwise be available in a repository. You apply blocklist rules to a repository, and they take effect even though the underlying source still contains the blocked packages.
Rules can block packages based on a variety of criteria:
- Package name and version
- Vulnerability severity, for example blocking every package with a vulnerability score of 5.0 or higher
- License type, for example blocking every package with a GPL license
This makes blocklists well suited to a permissive posture: users get broad access to a repository, but specific packages, or whole categories of risky packages, are denied. Vulnerability-based rules are particularly powerful because they react to CVE data automatically, blocking newly discovered vulnerable versions without you having to track them by hand.
Curated Sources: Allowing Only What Is Approved
Some teams require an external approval process before a new package can be used. For them, Package Manager provides curated sources, which expose only a pre-approved subset of packages rather than all of CRAN or PyPI.
The approved packages are defined in a requirements.txt file that lists package names and version constraints. For R packages, you can also control how the dependencies of approved packages are handled by adding an “extra” block to a line. This is a more restrictive posture than blocklists: instead of denying specific packages, you allow only what is on the list and exclude everything else.
The two mechanisms are complementary. Curated sources define what exists in a repository; blocklist rules block the download of specific packages even when they exist.
Why Snapshot Dates Matter for Curated Sources
Packages rarely stand alone: every package in your allowlist carries its own dependencies. To keep a curated repository accurate, the list must be anchored with a snapshot date.
Without a snapshot date, Package Manager resolves dependencies against the current state of CRAN or PyPI. If a new version is released upstream that changes the dependency graph of your allowlist, new packages could enter your curated repository without you ever explicitly approving them. Specifying a snapshot date anchors dependency resolution to a fixed CRAN state, making the full dependency graph deterministic, not just the packages you approved, but every dependency they pull in. This is what makes a curated repository trustworthy as an approved set.
Delaying Package Updates to Let Vulnerabilities Surface
Blocklist rules that act on vulnerability data are powerful, but they can only block what is already known. There is a window between the moment a new package version is published upstream and the moment a vulnerability in it is discovered, reported to a database like OSV, and synchronized into Package Manager. A malicious or simply flawed version can sit in that window looking perfectly healthy.
A useful complement is to deliberately serve packages as they existed a few days ago rather than the very latest. By trailing the upstream repositories, you give the wider community time to discover problems, and give maintainers time to patch or pull a bad version, before that version ever reaches your production users. You can think of this as a quarantine period for new package versions: just as a quarantine holds something new in isolation until enough time has passed to trust it, this delay keeps the newest releases out of your users’ reach until they have had time to prove themselves. The difference is that this hold is purely time-based: it applies uniformly to every new version, rather than flagging or inspecting individual packages.
Package Manager supports this directly with the DelaySyncDuration setting. When set, Package Manager will not serve any snapshot newer than the configured duration: the “latest” view your users see is held back by that amount, and the cutoff advances automatically as time passes. You do not have to move it by hand. The setting is configured per ecosystem, in the corresponding section of the configuration file:
/etc/rstudio-pm/rstudio-pm.gcfg
[CRAN]
DelaySyncDuration = 3d
[PyPI]
DelaySyncDuration = 3d
[Bioconductor]
DelaySyncDuration = 3dThe duration accepts a number of days (for example, 3d) or hours (for example, 72h); the default is 0, meaning no delay. After editing the configuration file, restart Package Manager for the change to take effect.
If you want to use this feature, we recommend trailing by about 3 days, which is usually enough time for serious issues to surface while keeping your packages reasonably current. Treat 3 days as a sensible starting point and adjust it to your organization’s risk tolerance.
Because the delay applies uniformly to every new version, it also holds back the fixes. If a new release is published specifically to patch a known vulnerability, your users will still have to wait the full delay period before that fix becomes available to them. The longer you set the delay, the longer this exposure lasts. This is why the delay is a complement to blocklist rules, not a replacement: when a fix for a known issue must reach users immediately, you can block the vulnerable version directly rather than relying on the delay.
This delay applies to the snapshots synchronized from the Posit Package Service (CRAN, PyPI, Bioconductor, and Open VSX). It is independent of, and complementary to, freezing a repository to a fixed date with a pinned URL: DelaySyncDuration provides an always-current view that simply trails by a set amount, whereas a pinned URL holds a project to one specific date.
This trailing strategy and the blocklist rules reinforce each other. The blocklist reacts the moment a vulnerability becomes known; the delay shrinks the chance that your users install a version during the brief period before anyone knows it is dangerous. Together they reduce both known and not-yet-known risk.