-
Notifications
You must be signed in to change notification settings - Fork 11
Upstream trust docs #369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ertzL
wants to merge
10
commits into
main
Choose a base branch
from
upstream-trust-docs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+127
−0
Open
Upstream trust docs #369
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
7604bc7
Create upstream-trust.mdx
ertzL c79d4a7
Update upstream-trust.mdx
ertzL 831d278
Remove the trailing space inside the Note headline attribute
ertzL eba8b97
spelling mistake fix
ertzL 2dd9d18
Update menu.json
ertzL d28818d
Update menu.json
ertzL 1902618
Update upstream-trust.mdx
ertzL 899ce3a
Potential fix for pull request finding
ertzL 92cc38f
Potential fix for pull request finding
ertzL 950dc88
Potential fix for pull request finding
ertzL File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| import { Note } from '@/components' | ||
|
|
||
| # Upstream Trust | ||
| Upstream trust is a supply chain security feature that protects your repositories from dependency confusion and namesquatting attacks. By designating upstream sources as trusted or untrusted, you control which sources are permitted to serve versions of packages that exist in your private repository or other trusted sources. | ||
| This is particularly important for organizations that publish private packages alongside public open-source dependencies. Without upstream trust, a malicious actor could publish a package with the same name as your private package to a public registry, potentially tricking your build systems into pulling the attacker's version instead of your own. | ||
|
|
||
| <Note variant="important" headline="Early Access"> | ||
| Upstream Trust is in Early Access (EA) as part of Cloudsmith's Advanced Security feature. | ||
| </Note> | ||
|
|
||
| ## How it works | ||
| Every upstream source configured for a repository has a trust status that can be set to either Trusted or Untrusted. Your local Cloudsmith repository is always implicitly trusted. | ||
| When a package is requested from a repository with upstreams configured, Cloudsmith evaluates trust as follows: | ||
| 1. Cloudsmith checks whether the requested package name (including any format-specific qualifiers or scopes, such as @cloudsmith/cloudsmith-web for npm) exists in any trusted source — either the local repository or any upstream marked as trusted. | ||
| 2. If the package name is found in a trusted source, any upstream marked as untrusted is blocked from serving versions of that package. Only versions available from trusted sources will resolve. | ||
| 3. If the package name is not found in any trusted source, versions from all sources (including untrusted upstreams) will resolve as normal. | ||
ertzL marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| This means your private packages are protected from namesquatting, while open-source packages that don't collide with your private package names continue to resolve without interruption. | ||
|
|
||
| <Note variant="note" headline="Proxied and cached packages"> | ||
| If a package has already been proxied or cached from a particular upstream, that upstream is permitted to continue serving versions of that package — even if it is marked as untrusted. The block only applies to other untrusted upstreams that have not previously served the package. This ensures that your existing open-source dependencies (such as requests or numpy proxied from PyPI) continue to resolve without disruption. | ||
| </Note> | ||
|
|
||
| ## Examples | ||
| The following examples illustrate how upstream trust affects package resolution for a package named cloudsmith_web across different source configurations. | ||
ertzL marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Untrusted upstream with multiple trusted sources | ||
| | Source | Trust Status | Available Versions | | ||
| | :-------------------------------------------------------------------------------------- | :--------------: | :--------------: | | ||
| | PyPI | Untrusted | 2.1.1, 2.1.2, 2.1.3 | | ||
| | Private repository | Trusted | 2.1.1, 2.1.2 | | ||
| | Local repository | Trusted | 2.1.1 | | ||
|
|
||
| Resolved versions: 2.1.1 (local), 2.1.2 (private) | ||
| The package cloudsmith_web exists in trusted sources (private and local), so PyPI is blocked from serving any versions. Only versions from trusted sources resolve. | ||
|
|
||
| ### Untrusted upstream with local trusted source only | ||
| | Source | Trust Status | Available Versions | | ||
| | :-------------------------------------------------------------------------------------- | :--------------: | :--------------: | | ||
| | PyPI | Untrusted | 2.1.1, 2.1.2, 2.1.3 | | ||
| | Local repository | Trusted | 2.1.1 | | ||
|
|
||
| Resolved versions: 2.1.1 (local) | ||
| The package exists in the local repository (trusted), so all versions from the untrusted PyPI upstream are blocked. | ||
|
|
||
| ### Untrusted upstream with no trusted sources containing the package | ||
| | Source | Trust Status | Available Versions | | ||
| | :-------------------------------------------------------------------------------------- | :--------------: | :--------------: | | ||
| | PyPI | Untrusted | 2.1.1, 2.1.2, 2.1.3 | | ||
|
|
||
| Resolved versions: 2.1.1, 2.1.2, 2.1.3 (PyPI) | ||
| No trusted source contains a package with this name, so all versions from PyPI resolve normally. This is the typical flow for open-source packages that don't collide with any of your private package names. | ||
|
|
||
| ### Untrusted upstream with trusted upstream (no local package) | ||
| | Source | Trust Status | Available Versions | | ||
| | :-------------------------------------------------------------------------------------- | :--------------: | :--------------: | | ||
| | PyPI | Untrusted | 2.1.1, 2.1.2, 2.1.3 | | ||
| | Private repository | Trusted | 2.1.1, 2.1.2 | | ||
|
|
||
| Resolved versions: 2.1.1, 2.1.2 (private) | ||
| The package exists in a trusted upstream (private repository), so PyPI is blocked. Only the versions available from the private repository resolve. | ||
|
|
||
| ### All trusted sources | ||
| | Source | Trust Status | Available Versions | | ||
| | :-------------------------------------------------------------------------------------- | :--------------: | :--------------: | | ||
| | PyPI | Trusted | 2.1.1, 2.1.2, 2.1.3 | | ||
| | Local repository | Trusted | 2.1.1 | | ||
|
|
||
| Resolved versions: 2.1.1 (local), 2.1.2, 2.1.3 (PyPI) | ||
| When all sources are trusted, versions from every source resolve. No blocking is applied. | ||
|
|
||
| # Configuring upstream trust | ||
| Trust status can be configured when creating a new upstream or by editing an existing upstream. | ||
|
Comment on lines
+72
to
+73
|
||
|
|
||
| ## Setting trust on a new upstream | ||
| 1. Navigate to your repository and select Upstreams. | ||
| 2. Click Add Upstream and select the format for your upstream source. | ||
| 3. Complete the upstream configuration fields as usual. | ||
| 4. Under Trust Status, select either Trusted or Untrusted. | ||
| 5. Click Create Upstream. | ||
|
|
||
| ## Updating trust on an existing upstream | ||
| 1. Navigate to your repository and select Upstreams. | ||
| 2. Click the upstream you want to modify. | ||
| 3. Toggle the Trust Status between Trusted and Untrusted. | ||
| 4. Click Save. | ||
|
|
||
| <Note variant="important" headline="Default trust status"> | ||
| All upstreams are set to Trusted by default. To take advantage of namesquatting protection, you should mark public registries (such as PyPI, npmjs, or Maven Central) as Untrusted if you also publish private packages with the same format. | ||
| </Note> | ||
|
|
||
| # Package identity and scoping | ||
| Upstream trust matches packages by their full identifier, which includes any format-specific qualifiers or scopes. For example: | ||
|
|
||
| ### Example identifiers | ||
| | Format | Example Identifier| | ||
| | :-------------------------------------------------------------------------------------- | :--------------: | | ||
| | Python (PyPI) | cloudsmith-web | | ||
| | npm | @cloudsmith/cloudsmith-web | | ||
| | Maven | io.cloudsmith:cloudsmith-web | | ||
| | NuGet | Cloudsmith.Web | | ||
|
|
||
| A match occurs when the full package identifier in an untrusted upstream is identical to a package identifier in a trusted source. There is no partial or fuzzy matching. | ||
|
|
||
| # Recommended configuration | ||
| For most organizations that publish private packages, we recommend the following approach: | ||
| - Mark public registries (PyPI, npmjs, Maven Central, NuGet Gallery, etc.) as Untrusted. | ||
| - Mark internal upstreams (private Artifactory instances, other Cloudsmith repositories, etc.) as Trusted. | ||
| - Your local repository is always trusted automatically. | ||
| This ensures that your private packages are only sourced from locations you control, while open-source dependencies that don't share names with your private packages continue to resolve from public registries as expected. | ||
|
|
||
| <Note variant="important" headline="Important"> | ||
| Upstream trust protects against namesquatting by controlling which sources can serve packages. It does not replace other supply chain security practices such as vulnerability scanning, package signing, or policy enforcement. For a comprehensive security posture, use upstream trust alongside Cloudsmith's other security features. | ||
| </Note> | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way this reads right now, it implies Upstream Trust protects from both dependency confusion and namesquatting, but I believe it's just namesquatting, a subset of dependency confusion. Suggestion to edit to:
Upstream trust is a supply chain security feature that prevents namesquatting attacks where bad actors hijack your internal package name in public repositories.