Skip to content

docs: update pnpr docs for registry mounts and the authorization-aware resolver#832

Merged
zkochan merged 1 commit into
mainfrom
update-pnpr-dox
Jul 2, 2026
Merged

docs: update pnpr docs for registry mounts and the authorization-aware resolver#832
zkochan merged 1 commit into
mainfrom
update-pnpr-dox

Conversation

@zkochan

@zkochan zkochan commented Jul 2, 2026

Copy link
Copy Markdown
Member

Updates the pnpr docs to the post-redesign state from pnpm/pnpm#12700 (authorization-aware resolver cache) and pnpm/pnpm#12747 (registry mounts as the only routing model). No legacy info or migration guides are kept — pnpr is still under active development and can change in breaking ways.

What changed

configuration.mduplinks: and packages: proxy: are gone. Documents mounts:/defaultTarget: as the only routing surface (provenance is declared, never inferred; no cross-origin fall-through), the three mount kinds with key tables — hosted (org namespaces, 404 on unauthorized private reads), upstream (public vs auth+access, per-mount cache namespaces, credential-rotation re-keying), router (the four-shape pattern language and every validation error pnpr refuses to start on) — plus packages: as a pure ACL layer and new groups:, secret:, and routes: public: sections.

install-acceleration.md — drops the forwarded-upstream-credentials claim (the server ignores authHeaders now); adds the default-deny fetch allowlist section and a "Private registries" section covering server-owned credentials, public tarballs staying on the CDN vs private ones routed through /~<mount>/, integrity-only lockfile entries, and the authorization-aware resolution cache.

endpoints.md — new "Registry bases: / and /~<mount>/" section (every registry endpoint works under a mount prefix, router no-match is a definitive 404, writes must land on a hosted mount); authHeaders removed from the resolve field list; search corrected to local-only.

quick-start.md — leads with writing a mount-shaped config and notes the bundled default is shaped for pnpm's own test registry.

storage.md, introduction.md, cli.md — R2 example converted to mounts, intro updated with the declared-provenance model, "verdaccio-shaped" dropped.

Everything was verified against the pnpr source at pnpm/pnpm main (config.rs, mount.rs, route.rs, resolver.rs, server.rs, and the bundled config.yaml), not just the PR descriptions.

Summary by CodeRabbit

  • Documentation
    • Updated the CLI, quick-start, storage, and configuration guides to reflect the current YAML-based setup and mount-based routing model.
    • Clarified how packages are routed, how registry access works, and how local, upstream, and router mounts interact.
    • Expanded endpoint and install documentation with clearer behavior for publishing, login, search, token handling, and resolved package URLs.
    • Added guidance on credential handling, private cache behavior, and configuration defaults.

…e resolver

Reflects the pnpr redesign in pnpm/pnpm#12700 (authorization-aware
resolver cache, default-deny fetch allowlist, no forwarded upstream
credentials) and pnpm/pnpm#12747 (registry mounts as the only routing
model): mounts:/defaultTarget: replace uplinks: and packages: proxy:,
packages: is ACL-only, and every mount is served at /~<mount>/.
@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pnpm-io Error Error Jul 2, 2026 4:23pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Documentation across the pnpr docs set (cli, configuration, endpoints, install-acceleration, introduction, quick-start, storage) is rewritten to replace the prior verdaccio-shaped uplinks/packages configuration model with a mounts/defaultTarget routing model, clarifying auth defaults, a new secret key, resolver fetch allowlisting, and endpoint routing semantics.

Changes

pnpr mounts documentation rewrite

Layer / File(s) Summary
Introduction and CLI framing updates
pnpr-docs/introduction.md, pnpr-docs/cli.md
Adds mount/router routing and credential-gateway explanations to the introduction and generalizes the CLI --config description.
Core mounts/defaultTarget configuration model
pnpr-docs/configuration.md
Replaces uplinks/packages proxy model with hosted/upstream/router mounts and defaultTarget, updates auth max_users/token defaults, and adds a secret HMAC key section plus resolver routes classification.
Registry/resolver endpoint routing and security semantics
pnpr-docs/endpoints.md
Documents registry base mount routing, write-to-hosted-mount constraints, ACL enforcement, tarball URL rewriting, resolver fetch allowlist/credential rules, local-only search, and global user/token endpoints.
Install-acceleration allowlist and private registry docs
pnpr-docs/install-acceleration.md
Adds default-deny fetch allowlist, private registry credential/access-policy behavior, public/private tarball URL splitting, and authorization-aware resolution caching.
Quick-start and storage example config updates
pnpr-docs/quick-start.md, pnpr-docs/storage.md
Updates example pnpr.yaml configs and instructions to use mounts/router/defaultTarget instead of uplinks/packages, and describes direct mount addressing and publish routing.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • pnpm/pnpm.io#829: Earlier PR that added the initial pnpr documentation, including cli.md and configuration.md, which this PR directly updates.

Poem

Hop, hop, hooray, the docs are new,
No more uplinks, mounts ring true!
Routers point with first-match grace,
Secrets guard the cache's place. 🥕
A rabbit reads with joyful cheer—
Clearer paths for pnpr here!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main documentation shift to registry mounts and the authorization-aware resolver.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch update-pnpr-dox

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Docs: align pnpr docs with mounts routing and auth-aware resolver cache

📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Document mounts/defaultTarget as the only routing model; remove uplinks/proxy legacy.
• Clarify install acceleration security: default-deny fetch allowlist and server-owned upstream
 creds.
• Update endpoint, quick-start, and examples to reflect mount-prefixed registry bases.
Diagram

graph TD
  C["pnpm client"] --> S["pnpr server"] --> R["Router mount"] --> H["Hosted mount"] --> ST[("Storage backend")]
  R --> U["Upstream mount"] --> CA[("Per-mount cache")]
  S --> CA
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep a legacy/migration appendix for uplinks/proxy
  • ➕ Reduces confusion for existing users following older examples
  • ➕ Provides a clear upgrade path and terminology mapping
  • ➖ Adds ongoing maintenance burden while pnpr is still changing quickly
  • ➖ Risks preserving unsafe mental models (fallback/proxy semantics) that no longer apply
2. Version docs by pnpr release line (v0/v1 docs)
  • ➕ Lets users pin documentation to their deployed server behavior
  • ➕ Avoids breaking older setups while still documenting the new model
  • ➖ Requires doc build/versioning infrastructure and a maintenance policy
  • ➖ Harder to keep multiple versions consistent and correct

Recommendation: The PR’s approach (fully rewriting docs to the post-redesign mounts model and removing legacy guidance) is the best fit for an actively-evolving project, especially given the security-sensitive behavior changes (declared provenance, no cross-origin fall-through, server-owned upstream credentials). If user confusion becomes an issue, consider adding a short “breaking changes since ” page rather than reintroducing legacy configuration details inline.

Files changed (7) +404 / -114

Documentation (7) +404 / -114
cli.mdRemove verdaccio-shaped config wording +1/-1

Remove verdaccio-shaped config wording

• Updates the CLI flag description to refer to a pnpr YAML config without implying Verdaccio compatibility. Keeps behavior description for config lookup and bundled default.

pnpr-docs/cli.md

configuration.mdRewrite configuration docs around mounts/defaultTarget and resolver routes +219/-54

Rewrite configuration docs around mounts/defaultTarget and resolver routes

• Replaces legacy 'uplinks' and 'packages: proxy' routing with the mounts graph ('hosted', 'upstream', 'router') and 'defaultTarget'. Adds detailed semantics around declared provenance/no fall-through, mount name validation, per-mount caching/credential behavior, router pattern language and startup-time validation, and introduces 'groups', 'secret', and 'routes: public' sections; clarifies 'packages' as ACL-only.

pnpr-docs/configuration.md

endpoints.mdDocument mount-prefixed registry bases and resolver allowlist behavior +51/-12

Document mount-prefixed registry bases and resolver allowlist behavior

• Adds a new section explaining '/' vs '/~<mount>/' bases, router 404/no-match semantics, and hosted-only writes. Removes 'authHeaders' from resolver request fields, clarifies server-side fetch allowlist and server-owned credentials, and corrects search to be local-only.

pnpr-docs/endpoints.md

install-acceleration.mdClarify security model: no forwarded creds, allowlist fetches, auth-aware cache +49/-5

Clarify security model: no forwarded creds, allowlist fetches, auth-aware cache

• Removes the claim that clients forward upstream credentials and documents server-owned upstream auth via mounts. Adds a default-deny registry/origin allowlist section plus a private registries section describing mount-prefixed tarballs for private content and authorization-aware resolution caching with credential-rotation cache re-keying.

pnpr-docs/install-acceleration.md

introduction.mdUpdate intro for declared-provenance mounts model +11/-3

Update intro for declared-provenance mounts model

• Reframes pnpr as hosting + proxying via mounts and routers rather than Verdaccio-shaped routing, emphasizing no cross-origin fall-through. Adds credential-gateway capability as a first-class use case.

pnpr-docs/introduction.md

quick-start.mdQuick start now starts from a mount-based config +58/-32

Quick start now starts from a mount-based config

• Adds an explicit mount/router-based sample config and positions it as the primary way to run pnpr (with a note about the bundled default being test-registry shaped). Clarifies that mounts are directly addressable under '/~<mount>/' and that publishes must route to hosted mounts.

pnpr-docs/quick-start.md

storage.mdUpdate storage backend example config to mounts/defaultTarget +15/-7

Update storage backend example config to mounts/defaultTarget

• Converts the R2/S3 example configuration from 'uplinks'/'packages: proxy' to 'mounts' plus a router mount and 'defaultTarget'. Aligns examples with the new routing model and public upstream declaration.

pnpr-docs/storage.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pnpr-docs/configuration.md`:
- Around line 103-106: Clarify the hosted mount collision rule in the
configuration docs by updating the `org`/storage namespace description in the
mount configuration section: explain whether hosted mounts that omit `org` are
rejected or allowed to share the flat `storage` root, since the current text
only covers explicit namespace conflicts. Refer to the `org` and `access` option
descriptions in the mount config table and the note about hosted mount
uniqueness so the wording clearly states the expected behavior for
`name@version` collisions.

In `@pnpr-docs/endpoints.md`:
- Around line 45-47: The documentation claim in the `dist.tarball` section is
too broad because private resolutions can still include `/~<mount>/` tarball
URLs in lockfiles. Reword the text in `endpoints.md` to describe base
canonicalization via `public_url` for the client-addressed base, and avoid
stating that lockfiles never bake in a mount name; keep the wording aligned with
the `dist.tarball` rewrite behavior and the `/~<mount>/` path handling.

In `@pnpr-docs/install-acceleration.md`:
- Around line 99-103: The paragraph in the install acceleration docs uses
“integrity-only” too broadly and conflicts with the public/private lockfile
split described in configuration.md. Update the wording to reflect that public
packages keep upstream tarball URLs, while private packages are rewritten to the
mount URL, and keep the explanation aligned with the behavior described around
the lockfile and mount endpoint in this section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 00915171-44f0-4a77-a1a9-1c0c2b8166bd

📥 Commits

Reviewing files that changed from the base of the PR and between aa7acf2 and a796993.

📒 Files selected for processing (7)
  • pnpr-docs/cli.md
  • pnpr-docs/configuration.md
  • pnpr-docs/endpoints.md
  • pnpr-docs/install-acceleration.md
  • pnpr-docs/introduction.md
  • pnpr-docs/quick-start.md
  • pnpr-docs/storage.md
📜 Review details
⚠️ CI failures not shown inline (1)

Commit Status: Vercel: Vercel

Conclusion: failure

Deployment has failed — run this Vercel CLI command: npx vercel inspect dpl_FV4jdc5S6N9in8VHhY6irLVZcwJB --logs
🧰 Additional context used
🪛 LanguageTool
pnpr-docs/quick-start.md

[style] ~48-~48: Consider an alternative for the overused word “exactly”.
Context: ...04, never a request to npmjs — which is exactly what closes dependency confusion. ## S...

(EXACTLY_PRECISELY)

pnpr-docs/configuration.md

[grammar] ~6-~6: Ensure spelling is correct
Context: ... YAML config. When you don't pass -c, pnpr looks for a global config.yaml in its...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~204-~204: You can shorten this phrase to improve clarity and avoid wordiness.
Context: ...ute's pattern; - a duplicate pattern; - a source that is undefined, the router itself, or another router (...

(NNS_THAT_ARE_JJ)

🔇 Additional comments (7)
pnpr-docs/introduction.md (1)

9-16: LGTM!

Also applies to: 34-36

pnpr-docs/cli.md (1)

14-14: LGTM!

pnpr-docs/configuration.md (1)

6-34: LGTM!

Also applies to: 63-102, 107-253, 272-292, 307-334

pnpr-docs/quick-start.md (1)

6-59: LGTM!

Also applies to: 72-91

pnpr-docs/storage.md (1)

64-81: LGTM!

pnpr-docs/endpoints.md (1)

23-44: LGTM!

Also applies to: 49-50, 63-78, 103-106, 117-118, 134-136

pnpr-docs/install-acceleration.md (1)

44-52: LGTM!

Also applies to: 65-67, 68-79, 80-98, 105-111

Comment on lines +103 to +106
| `org` | Storage namespace for this mount's packages, so two hosted mounts can hold the same `name@version` without colliding. Omitted means the flat `storage` root. Must be a single path-safe segment. |
| `access` | Who may read this mount's packages. Defaults to `$all`. |

Two hosted mounts cannot share an `org` namespace — that's rejected at config

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Clarify the collision rule for hosted mounts without org.

org is optional here, but the uniqueness check only forbids sharing an explicit namespace. As written, two hosted mounts that omit org would both use the flat storage root and could collide on disk. Please state whether that configuration is rejected or make org mandatory for hosted mounts.

💡 Suggested wording
-| `org` | Storage namespace for this mount's packages, so two hosted mounts can hold the same `name@version` without colliding. Omitted means the flat `storage` root. Must be a single path-safe segment. |
+| `org` | Storage namespace for this mount's packages, so two hosted mounts can hold the same `name@version` without colliding. Omitted means the flat `storage` root; only one hosted mount may use that default. Must be a single path-safe segment. |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| `org` | Storage namespace for this mount's packages, so two hosted mounts can hold the same `name@version` without colliding. Omitted means the flat `storage` root. Must be a single path-safe segment. |
| `access` | Who may read this mount's packages. Defaults to `$all`. |
Two hosted mounts cannot share an `org` namespace — that's rejected at config
| `org` | Storage namespace for this mount's packages, so two hosted mounts can hold the same `name@version` without colliding. Omitted means the flat `storage` root; only one hosted mount may use that default. Must be a single path-safe segment. |
| `access` | Who may read this mount's packages. Defaults to `$all`. |
Two hosted mounts cannot share an `org` namespace — that's rejected at config
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pnpr-docs/configuration.md` around lines 103 - 106, Clarify the hosted mount
collision rule in the configuration docs by updating the `org`/storage namespace
description in the mount configuration section: explain whether hosted mounts
that omit `org` are rejected or allowed to share the flat `storage` root, since
the current text only covers explicit namespace conflicts. Refer to the `org`
and `access` option descriptions in the mount config table and the note about
hosted mount uniqueness so the wording clearly states the expected behavior for
`name@version` collisions.

Comment thread pnpr-docs/endpoints.md
Comment on lines +45 to +47
- Served `dist.tarball` URLs are rewritten onto the configured `public_url`
and stay canonical for the base the client addressed (path-less or
`/~<mount>/`), so lockfiles don't bake in a mount name.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Narrow the lockfile claim.

The last clause is too broad: private resolutions intentionally emit /~<mount>/ tarball URLs, so lockfiles can still carry a mount name. Please reword this as base canonicalization, not a blanket “no mount name” guarantee.

Suggested rewording
- so lockfiles don't bake in a mount name.
+ so the tarball URL stays canonical for the base the client addressed.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Served `dist.tarball` URLs are rewritten onto the configured `public_url`
and stay canonical for the base the client addressed (path-less or
`/~<mount>/`), so lockfiles don't bake in a mount name.
- Served `dist.tarball` URLs are rewritten onto the configured `public_url`
and stay canonical for the base the client addressed (path-less or
`/~<mount>/`), so the tarball URL stays canonical for the base the client addressed.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pnpr-docs/endpoints.md` around lines 45 - 47, The documentation claim in the
`dist.tarball` section is too broad because private resolutions can still
include `/~<mount>/` tarball URLs in lockfiles. Reword the text in
`endpoints.md` to describe base canonicalization via `public_url` for the
client-addressed base, and avoid stating that lockfiles never bake in a mount
name; keep the wording aligned with the `dist.tarball` rewrite behavior and the
`/~<mount>/` path handling.

Comment on lines +99 to +103
Because a mount endpoint URL is canonical for a client whose registry
configuration points at it, lockfile entries stay integrity-only — the
registry host lives in the client's `.npmrc`, not in the lockfile — and a
project resolves to the same lockfile whether it installs through `/resolve`
or directly against the registry.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace the “integrity-only” wording.

This paragraph conflicts with the split described just above and in configuration.md: public packages keep upstream tarball URLs, while private packages are rewritten to the mount URL. “Integrity-only” is too broad here; please describe the public/private URL split explicitly.

Suggested rewording
- lockfile entries stay integrity-only — the registry host lives in the client's `.npmrc`, not in the lockfile —
- and a project resolves to the same lockfile whether it installs through `/resolve` or directly against the registry.
+ public packages keep their upstream tarball URL, while private packages are rewritten to the mount endpoint.
+ That keeps the lockfile consistent for a given client-facing base.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Because a mount endpoint URL is canonical for a client whose registry
configuration points at it, lockfile entries stay integrity-only — the
registry host lives in the client's `.npmrc`, not in the lockfile — and a
project resolves to the same lockfile whether it installs through `/resolve`
or directly against the registry.
Because a mount endpoint URL is canonical for a client whose registry
configuration points at it, public packages keep their upstream tarball URL,
while private packages are rewritten to the mount endpoint. That keeps the
lockfile consistent for a given client-facing base.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pnpr-docs/install-acceleration.md` around lines 99 - 103, The paragraph in
the install acceleration docs uses “integrity-only” too broadly and conflicts
with the public/private lockfile split described in configuration.md. Update the
wording to reflect that public packages keep upstream tarball URLs, while
private packages are rewritten to the mount URL, and keep the explanation
aligned with the behavior described around the lockfile and mount endpoint in
this section.

@zkochan zkochan merged commit 2113b03 into main Jul 2, 2026
6 of 7 checks passed
@zkochan zkochan deleted the update-pnpr-dox branch July 2, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant