Repository navigation
feat(ENG-13680): add a NuGet credential provider - #494
Draft
cloudsmith-iduffy wants to merge 1 commit into
Draft
cloudsmith-iduffy wants to merge 1 commit into
cloudsmith-iduffy wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Blocking credential operations can exceed NuGet protocol deadlines, and status detection can miss default installations.
3 open issues
What changed in this PR
Adds a NuGet credential provider that authenticates Cloudsmith feeds using the CLI’s existing credentials.
Changes:
- Implements the NuGet plugin protocol and feed matching.
- Adds installation, registration, and saved launcher settings.
- Adds tests and protects protocol output from debug messages.
| File | Description |
|---|---|
| cloudsmith_cli/credential_helpers/nuget/runtime.py | Implements plugin messages and authentication. |
| cloudsmith_cli/credential_helpers/nuget/installer.py | Manages NuGet launcher installation. |
| cloudsmith_cli/credential_helpers/nuget/__init__.py | Exports the runtime entry point. |
| cloudsmith_cli/credential_helpers/launchers.py | Supports saved settings and Windows batch launchers. |
| cloudsmith_cli/credential_helpers/common.py | Allows discovery using existing API configuration. |
| cloudsmith_cli/core/api/init.py | Sends authentication debug output to stderr. |
| cloudsmith_cli/cli/tests/test_credential_helper_nuget.py | Tests protocol, command, and installation behavior. |
| cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py | Tests launcher settings and escaping. |
| cloudsmith_cli/cli/decorators.py | Exposes credential context for renewal. |
| cloudsmith_cli/cli/commands/credential_helper/nuget.py | Adds the NuGet command. |
| cloudsmith_cli/cli/commands/credential_helper/manage.py | Registers installation and captures settings. |
| cloudsmith_cli/cli/commands/credential_helper/__init__.py | Registers the NuGet subcommand. |
| CHANGELOG.md | Documents provider usage and requirements. |
Review effort: Balanced
| ) | ||
| @click.argument("nuget_args", nargs=-1, type=click.UNPROCESSED) | ||
| @common_api_auth_options | ||
| @initialise_api |
Comment on lines
+141
to
+143
| launcher_path = self._launcher_path(resolve_bin_dir()) | ||
| if not launcher_path.exists(): | ||
| return {"launcher": None, "hosts": []} |
| if method == "Close": | ||
| return False | ||
|
|
||
| response = self.handle_request(method, message.get("Payload")) |
cloudsmith-iduffy
marked this pull request as draft
October 19, 2026 09:15
Base automatically changed from
iduffy/shared-credential-helper-code
to
master
October 20, 2026 08:24
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 13:11
091ed1c to
54ddc6e
Compare
cloudsmith-iduffy
removed this pull request from stack #495
October 21, 2026 13:11
cloudsmith-iduffy
changed the base branch from
master
to
iduffy/launcher-install-time-settings
October 21, 2026 13:12
2 of 6 tasks
cloudsmith-iduffy
force-pushed
the
iduffy/launcher-install-time-settings
branch
from
October 21, 2026 14:22
1f65903 to
a7601da
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 14:22
54ddc6e to
22711f2
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/launcher-install-time-settings
branch
from
October 21, 2026 15:08
a7601da to
3b92542
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 15:09
22711f2 to
956f61a
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/launcher-install-time-settings
branch
from
October 21, 2026 15:13
3b92542 to
c2ee2fb
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 15:14
956f61a to
ba516f4
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/launcher-install-time-settings
branch
from
October 21, 2026 15:34
c2ee2fb to
e1a1c2e
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 15:34
ba516f4 to
cc4365d
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/launcher-install-time-settings
branch
from
October 21, 2026 16:30
e1a1c2e to
23abdbd
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 16:31
cc4365d to
6d4af20
Compare
`cloudsmith credential-helper install nuget` writes a `nuget-plugin-cloudsmith` launcher (`.bat` on Windows) on PATH. NuGet 6.13+ finds it and speaks the cross-platform plugin protocol to `cloudsmith credential-helper nuget`. The plugin answers for Cloudsmith hosts and the NuGet domains of the Workspace that is written into the launcher. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # CHANGELOG.md # cloudsmith_cli/cli/commands/credential_helper/manage.py # cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py # cloudsmith_cli/core/api/init.py # cloudsmith_cli/credential_helpers/launchers.py # Conflicts: # cloudsmith_cli/cli/commands/credential_helper/manage.py # cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py
cloudsmith-iduffy
force-pushed
the
iduffy/launcher-install-time-settings
branch
from
October 21, 2026 17:11
23abdbd to
6db2380
Compare
cloudsmith-iduffy
force-pushed
the
iduffy/nuget-credential-provider
branch
from
October 21, 2026 17:11
6d4af20 to
87c0faa
Compare
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.


Description
Adds a NuGet credential provider (ENG-13680). After a one-off install,
dotnet restore, MSBuild and Visual Studio authenticate to Cloudsmith feeds with the CLI's own credentials: an API key, a SAML session from the keyring, or OIDC. No token goes intonuget.config.Install.
credential-helper install nugetwrites anuget-plugin-cloudsmithlauncher next tocloudsmith, as a.baton Windows. NuGet 6.13 and later (.NET SDK 9.0.200+) finds anynuget-plugin-*executable on PATH, so no NuGet config changes.NuGet often runs the plugin from an IDE or a build agent that does not have your shell's environment. So the launcher keeps the
CLOUDSMITH_*settings that you gave at install time as a flag or an environment variable, with the shared code from #511. These values win over the runtime environment. Secrets and the proxy URL are never written.Runtime.
credential-helper nugetspeaks NuGet's cross-platform plugin protocol. NuGet asks every plugin about every feed:httpsfeed on*.cloudsmith.io,*.cloudsmith.comor a NuGet domain of the Workspace → Basictoken:<credential>.NotFound, so NuGet tries its other credential sources.Error, with a message that says how to authenticate.--domain <host>adds hosts that always match.--no-discoverturns off the domain lookup, so only those hosts and the Cloudsmith hosts match. Stdout carries only protocol messages, also under--debug.Changes outside NuGet.
core/api/init.pywrites its--debugcredential messages to stderr. One of them now says "SAML" instead of "SSO".resolve_credentialskeeps itsCredentialContextonoptsfor the retry.is_cloudsmith_domainpassesconfigure_apithrough, so the domain lookup keeps the CLI's proxy and TLS settings.Type of Change
Additional Notes
This replaces #458, which has the earlier review history.
Testing. A temporary workflow ran a real
dotnet restore(SDK 10) on Linux, macOS and Windows, from both a pip install and the PyInstaller binary. It covered a standard feed, a custom domain found by the live lookup with--debugon, and--domain --no-discoverwith an unreachable API host. Each job checks that the restore fails with 401 without the plugin and succeeds with it. All 18 jobs passed: run 38967385354.I also ran
dotnet nuget pushanddotnet restorelocally against a private repo with only a SAML session. Both worked with no API key.Known limits.
NuGet's plugin timeouts are 30 seconds in
ProtocolConstants, not the 5 seconds in the Microsoft docs. Credentials resolve before the handshake, so the plugin needs no threads or progress messages.🤖 Generated with Claude Code