A package from a named registry can carry a repository_url qualifier in its package URL, so the same name and version from two registries stay distinct. Tools should strip credentials, and pnpm documents that it removes userinfo and query strings. Still review any SBOM before sharing, because hostnames and paths remain.
Why the qualifier exists
The Package URL specification lists repository_url among its example qualifiers, key and value pairs that narrow which package is meant. This matters when two registries can serve a package with the same name and version but different content. Without the qualifier, an SBOM would show one identity for two things.
The pnpm documentation says that since version 11.20.0, components from a named registry get a repository_url qualifier for this reason. It also says credentials, meaning userinfo or query string, are stripped from the qualifier, while the origin and path are kept.
What that means for sharing
The origin and path stay. If your internal registry has a hostname that reveals a project name, a team or an environment, an SBOM exposes it. This is often fine inside a company and sometimes not fine for a customer.
| Item in the file | Usually safe to share? | Check |
|---|---|---|
| Public registry coordinates | Yes | None |
| Internal registry hostname | Depends | Does it reveal structure? |
| Path to a scoped feed | Depends | Does it name a client or project? |
| Tokens or user names | No | Should be absent, confirm |
| Internal package names | Depends | Are they confidential? |
Steps before you send a file
- Search the file for common credential shapes: at signs inside URLs, long random strings, the words token, key and password.
- List every distinct host in repository_url values.
- Decide for each host whether a customer may see it.
- If not, redact or replace the value, and note the redaction in your cover letter so the change is honest.
- Re-validate the file after editing.
Redaction has a cost. A purl without its qualifier may be ambiguous, so keep enough to identify the package, and say what you removed.
How to prevent it going wrong
Use registry configuration that keeps secrets in environment variables or credential helpers, not in URLs. Then even a careless tool has nothing to leak. Run the search step in CI, not just by hand, and fail a release if a secret like pattern shows up. That is a check you own at the pipeline level, separate from any SBOM tool.
What to ask a tool vendor
- Does the tool strip credentials from URLs it writes?
- Is that behavior documented?
- Can I choose which fields are exported?
- Is there an audit of what was shared with whom?
A worked example
Imagine a company with a public registry dependency named logging-lib at version 2.4.0 and an internal fork of the same name and version, hosted on a private feed. Without a qualifier, both would look identical in an SBOM. With the repository_url qualifier, the package URLs differ and a reader can tell them apart. This is a constructed example.
| Component | Package URL idea | What the reader learns |
|---|---|---|
| Public logging-lib 2.4.0 | No qualifier, or the public registry | Comes from the public registry |
| Internal fork 2.4.0 | Qualifier naming the private feed | Comes from an internal feed |
The distinction matters for security. An advisory on the public package does not necessarily apply to the internal fork, and the reverse is also true. Without the qualifier, a vulnerability match could wrongly flag the fork or wrongly clear it.
Dependency confusion and why the qualifier helps
A known risk is a public package with the same name as an internal one. If a build resolves the wrong one, malicious code can enter. An SBOM that records where each component came from lets a reviewer spot a component that came from the public registry when you expected the private feed. That is a useful check, not a prevention on its own.
Reviewing a file before sharing
Take the file you plan to send and run through this list:
- Extract every package URL and list the distinct hosts in repository_url values.
- For each host, decide whether the name reveals anything sensitive: a project code name, a client name, an environment name.
- Search for strings that look like secrets, even though pnpm documents stripping userinfo and query strings.
- Check internal package names. Some names are harmless, some describe unreleased products.
- Decide what to redact, and write a one line note about the redaction.
Choosing a policy
| Audience | Suggested approach |
|---|---|
| Internal security team | Full detail, including registry hosts |
| Customer under contract | Keep qualifiers that matter for identity, redact sensitive hostnames |
| Public release | Include public registry components, describe internal ones generically |
The right level depends on the relationship and on any confidentiality terms you have. Your legal or security lead should decide.
How redaction can go wrong
Replacing a hostname with a placeholder is fine if you do it consistently. Deleting the qualifier completely may merge two distinct packages in the reader's eyes. Editing the file by hand without validating it afterwards may break the schema. Always validate after editing, and keep the original file in a restricted location.
Preventing leaks at the source
Keep credentials out of URLs in registry configuration. Use environment variables or credential helpers so that no tool has a secret to write into a file. Rotate any token that was ever printed in a log or a file. That is an operational habit for your CI system, separate from the SBOM.
Where Safeguard fits
Safeguard offers SBOM scanning and compliance evidence workflows. Try a file through the free scan at gold.safeguard.sh/scan, and keep redaction decisions on your side of the process.
Try it yourself
Click through it at your own pace, or open it full screen.
Click into a few components and note how direct and transitive packages are separated.
Quick check
Does a repository_url qualifier contain my token?
pnpm documents that it strips userinfo and query strings. Other tools may differ, so search the file.
Can I remove repository_url to be safe?
You can, but identity may become ambiguous. Replace it carefully and say so in your cover note.
Why does the same package name appear twice with different registries?
They may be two distinct packages. The repository_url qualifier is what keeps them apart.
Sources
Last reviewed: 19 October 2026.