Repository navigation
nuget-plugin-forge: NuGet authentication plugin written in Rust #164
Copy link
Copy link
Open
Labels
enhancementNew feature or requestNew feature or request
Milestone
Description
Part of #44. Builds on the shared client crate (#162). Depends on #39's device-flow endpoints. One binary, nuget-plugin-forge, serves dotnet, nuget.exe, MSBuild and Visual Studio.
Rust works
- PATH discovery. Since NuGet 6.13 (.NET SDK 9.0.200, Visual Studio 17.13), NuGet searches
PATHfor files namednuget-plugin-*. The prefix must be lowercase. On Linux and macOS the file must be executable; on Windows it must end in.exeor.bat. The implementation language doesn't matter (docs, spec). - Overrides.
PATHis only searched when none of theNUGET_*PLUGIN_PATHSvariables is set. CI can also pointNUGET_PLUGIN_PATHSstraight at the file. - Signing. Plugins don't need an Authenticode signature on Windows any more (6.12 and earlier required one).
- Older clients. NuGet before 6.13 only loads plugins from
~/.nuget/plugins/netcore/<name>/<name>.dll(a .NET assembly) ornetfx/<name>/<name>.exe. NuGet 6.13 is therefore the minimum supported version. - Startup time. The handshake times out after 5 seconds, and a native binary starts well within that.
Protocol (v2.0.0)
NuGet launches the plugin with -Plugin and exchanges UTF-8 JSON messages over stdin/stdout, one per line, each with a RequestId/Type/Method/Payload envelope. Without -Plugin, the binary prints usage instead of waiting for a handshake.
Messages
- NuGet → plugin: Initialize, SetLogLevel, GetOperationClaims, SetCredentials, GetAuthenticationCredentials, MonitorNuGetProcessExit, Close.
- Handshake: goes both ways.
- Plugin → NuGet: Log. NuGet ignores log messages sent before SetLogLevel.
- While a request runs longer than the 5-second request timeout, as the device flow does, the plugin sends Progress messages. It also honours cancellation.
GetOperationClaims
The plugin claims Authentication. NuGet caches claims per plugin path for 30 days, so sources are filtered in GetAuthenticationCredentials, not here.
GetAuthenticationCredentials
- Forge URIs: for a URI on a Forge host the user signed in to or configured, return a username plus the token as the password, auth type
basic. Forge accepts a token as the Basic password (Client login for every format: Nexus-style logins, UI-minted tokens, browser/OAuth login #39). - Other URIs: answer
NotFoundso other providers, such as Azure Artifacts, still get their turn. IsRetry: the cached token was rejected. Drop it and authenticate again.IsNonInteractive: never block. Return the cached or renewed token, or nothing.- Interactive,
CanShowDialog=false: run the device flow and send the instructions as aLogmessage at a level thatdotnet restore --interactiveprints. - Interactive,
CanShowDialog=true: this covers Visual Studio, MSBuild and every client from NuGet 7.0. The plugin may open the browser, but only if a display really is available.
Acceptance criteria
- Protocol tests against recorded NuGet message transcripts, including progress, timeouts and cancellation.
- e2e:
dotnet restore --interactiveagainst an authenticated Forge feed, with the device flow approved through the mock IdP harness. - A second, non-interactive
dotnet restorereuses the cached token. - A non-interactive restore without a cached token fails fast with a message that names
forge loginor--interactive. - A restore that also uses nuget.org and a third-party authenticated feed is unaffected.
- Smoke tests on Linux, macOS and Windows.
- Docs on the NuGet "connect your client" page (Client login for every format: Nexus-style logins, UI-minted tokens, browser/OAuth login #39).
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity