dotnet-inspect: private NuGet feeds
Use this skill when package evidence lives outside NuGet.org. Start with a credential-free source configuration and a NuGet credential provider; keep tokens out of repositories and command lines.
dnx dotnet-inspect -y -- <command>
Select the feed
--nugetconfig uses exactly the named configuration. --source replaces the
configured source set and can repeat; --add-source augments it for one run.
Use a source-only config when a credential provider supplies authentication:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="private" value="https://example.com/nuget/v3/index.json" />
</packageSources>
</configuration>
dnx dotnet-inspect -y -- package MyCompany.Widget --nugetconfig ./NuGet.Config
dnx dotnet-inspect -y -- package MyCompany.Widget --versions-with-feed \
--nugetconfig ./NuGet.Config
package query currently uses NuGet.org only; it rejects private-feed source
overrides rather than silently querying the wrong authority.
Version discovery combines all eligible sources and chooses the highest
semantic version; source order is not precedence. Pin Package@Version when
the exact coordinate matters.
Share a private-feed Workspace with Inspect Web
Author a credential-free format-5 URL that declares an authentication-required source:
dnx dotnet-inspect -y -- workspace \
--package Private.Package@1.2.3 \
--tfm net10.0 \
--nuget-source-auth-required \
https://nuget.pkg.github.com/example/index.json \
--share url
Inspect Web prompts once per exact endpoint for a username and personal access token. Credentials remain in page-session memory only: activation-local copies are cleared after settlement, while the active realization or incumbent-recovery binding may retain them until replacement or disposal. They are not placed in the packet or URL, retained Workspace definition, browser storage, logs, diagnostics, or telemetry. Reloading prompts again. Cancellation or failure before publication preserves the prior visible Workspace; if recovery after cutover also fails, Inspect Web enters a blocking retry state rather than exposing the failed tentative Workspace. Declared anonymous sources activate without a prompt.
Query versions from a folder feed
Online version queries support NuGet V2/V3 folder feeds, specified as a
path, a file:// URI, or a mapped source in NuGet.Config:
dnx dotnet-inspect -y -- package MyCompany.Widget --versions --source ./feed
dnx dotnet-inspect -y -- package MyCompany.Widget --versions -n 5 --preview \
--source ./feed --jsonl
dnx dotnet-inspect -y -- package MyCompany.Widget --versions -n 1 --source ./feed
dnx dotnet-inspect -y -- package MyCompany.Widget@latest --versions --source ./feed
dnx dotnet-inspect -y -- package MyCompany.Widget --version 1.2.3 --source ./feed
dnx dotnet-inspect -y -- package MyCompany.Widget@1.0.0..2.0.0 --versions \
--source ./feed --include-unlisted
dnx dotnet-inspect -y -- package MyCompany.Widget --versions-with-feed \
--source ./feed --add-source https://api.nuget.org/v3/index.json
Local and HTTP versions are combined and sorted before the result limit.
Use --versions -n 1 for one newest listed version row, or
Package@latest --versions to force a fresh latest-version check.
For online single-package inspection, an unpinned ID can reuse the tool's
prior version settlement within its jittered one-hour window. A stale prior is
refreshed within five seconds; if refresh fails, the tool serves the prior with
one warning naming its age. Use Package@latest when the inspection must make
a fresh version check. Version-listing, range, and wildcard queries retain
their own selection paths.
Missing folders or invalid archives are source failures, not package absence;
usable peer results carry an explicit partial warning on stderr. Local reads
use bounded enumeration rather than treating filenames as version evidence.
Latest, single-version discovery, and range selection require complete
evidence: an unreadable peer makes them fail instead of choosing from a
healthy subset. A pinned verification may report a coordinate observed on a
readable feed, with peer failures disclosed. --include-unlisted and
--versions-with-feed retain their listing and feed columns; local versions
use the non-Gallery listed convention.
These version queries are metadata-only and do not use --offline.
Inspect a package from a folder feed
Pin one coordinate to inspect its payload through the configured folder source:
dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 --source ./feed
dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 --source ./feed \
--path @readme --content --raw
dnx dotnet-inspect -y -- package MyCompany.Widget --source ./feed
dnx dotnet-inspect -y -- package 'MyCompany.Widget@1.*' --source ./feed \
--path @readme --content --raw
Online single-package inspection also supports latest, --preview, and
wildcard payload selection. It freshly queries every eligible source and
requires complete evidence before choosing a version; a failed peer blocks
automatic selection even when another source has a warm payload cache.
Only sources that reported the selected version may supply its payload.
Wildcards use a case-insensitive version prefix and may match prereleases.
Caller-pinned acquisition tries local sources before HTTP sources.
Declaration order is not precedence within a tier. One eligible source can
supply the exact package even when an earlier peer fails; --verbose retains
those diagnostics. Tool-wrapper redirects independently reapply mapping.
Local payload caches are scoped to the canonical configured folder, not just
package ID/version or producer identity. HTTP payloads currently use temporary
authority-scoped materialization and do not reuse persistent payload caches.
Automatic selection does not reuse legacy candidate caches. package --versions
can enumerate a range, but ordinary package payload inspection does not
accept a range or --at.
Inspect APIs and history from a folder feed
Online API commands support omitted/latest and wildcard selection, exact pins, and explicitly addressed ranges:
dnx dotnet-inspect -y -- type MyCompany.Widget --package MyCompany.Widget \
--source ./feed
dnx dotnet-inspect -y -- type MyCompany.Widget \
--package 'MyCompany.Widget@1.*' --source ./feed
dnx dotnet-inspect -y -- type MyCompany.Widget --package MyCompany.Widget@1.2.3 \
--source ./feed
dnx dotnet-inspect -y -- type MyCompany.Widget \
--package MyCompany.Widget@1.0.0..2.0.0 --at last --source ./feed
dnx dotnet-inspect -y -- diff --history --package MyCompany.Widget@1.0.0..2.0.0 \
--type MyCompany.Widget --type-presence --at first --at last --source ./feed
Omitted and @latest API selection chooses the highest stable listed version.
Wildcards use the package selection contract's case-insensitive prefix
semantics and may select a prerelease.
Ranges require complete fresh discovery and acquire only from sources that
reported each selected coordinate. Diff History retains one vector for all its
probes. Omit --at for full-population evaluation, repeat it for explicit
checkpoints, use --max-probes for adaptive bisection, or use
--major-versions for one representative per major. API findings use the
first stable version, with the latest prerelease fallback for preview-only
majors; Analysis findings use the latest admitted version per major. An
unreadable peer prevents selection.
API/history vectors exclude unlisted observations, including endpoints.
An exact pin can still inspect an unlisted coordinate. Do not copy ordinals
from a --include-unlisted metadata listing into a listed-only vector.
Diff History probe recommendations retain source/configuration and selection
options. match --similar retains the reporting configured sources in its
exact-package replay, without depending on temporary extraction paths.
Exact API pins and range probes use the same local authority caches and HTTP temporary storage as package inspection. HTTP payloads are downloaded anew in each invocation. Multi-package and dependency commands, and offline extraction remain on their existing paths.
Restrict package ids to feeds
dotnet-inspect honors <packageSourceMapping> from the selected NuGet
configuration:
<packageSourceMapping>
<packageSource key="private">
<package pattern="MyCompany.*" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
An exact package id wins over prefixes; otherwise the longest matching prefix
wins. Mapping is applied independently to top-level packages, dependencies,
RID companions, platform packs, tool redirects, searches, and routing probes.
Every package id must match an active named source. --source and
--add-source do not disable mapping; an override must match the configured
endpoint to retain its mapped source name.
Azure Artifacts credential provider
Install Microsoft's provider as a global tool. dotnet-inspect discovers
NUGET_NETCORE_PLUGIN_PATHS, then NUGET_PLUGIN_PATHS, then
~/.nuget/plugins/netcore/ and nuget-plugin-* executables on PATH.
dotnet tool install --global Microsoft.Artifacts.CredentialProvider.NuGet.Tool
Credential plugins run only after a feed answers 401. dotnet-inspect requests
credentials noninteractively: cached and environment-supplied credentials work,
but it never opens a sign-in prompt. az login alone does not supply a NuGet
credential.
In Azure Pipelines, authenticate before restore or inspection:
- task: NuGetAuthenticate@1
- script: dotnet restore
- script: dnx dotnet-inspect -y -- package MyCompany.Widget
Outside Azure Pipelines, provide the provider's documented unattended credential input. Do not print the expanded value:
export ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS='{"endpointCredentials":[{"endpoint":"https://example.com/nuget/v3/index.json","username":"unused","password":"'"$TOKEN"'"}]}'
For an Azure Pipelines-compatible build identity, the provider also accepts
ARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES with
ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN. Service-principal certificate
configuration uses ARTIFACTS_CREDENTIALPROVIDER_FEED_ENDPOINTS.
Explicit credentials
When no provider serves the feed, dotnet-inspect accepts both Username and
ClearTextPassword under a matching packageSourceCredentials key. Keep that
config outside the repository and select it with --nugetconfig.
Do not rely on %VAR% expansion, encrypted <Password>,
NuGetPackageSourceCredentials_*, or credentials embedded in a source URL;
dotnet-inspect does not use those forms.
Diagnose failures and caches
A reported 401 Unauthorized means the source was unreadable, not that the
package is absent. Check provider discovery, URI matching, token scope, and
expiration before changing the package id.
dotnet-inspect's package payload and candidate caches retain source provenance.
The NuGet global folder is payload-only: it can fulfill an exact resolved
coordinate only when .nupkg.metadata.source names an authorized producer.
Missing or mismatched provenance is a cache miss, and installed payloads do not
introduce version candidates. Use --no-nuget-cache to exclude that layer.
--offline forbids network access and does not start credential plugins, so it
succeeds only from producer-authorized caches. Online version queries bypass
these legacy caches. Online single-package extraction, exact API pins, and
API/history range probes use authority-scoped
payload storage instead: old producer-keyed entries cannot authorize it, and HTTP
global-packages entries are not reused. A local global-packages entry must
name the same canonical configured folder in .nupkg.metadata.source.
Other unmigrated paths still skip configured folder feeds; --verbose
reports the skip. Passing a local .nupkg file remains supported separately.
dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 \
--source https://example.com/nuget/v3/index.json --no-nuget-cache
dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 \
--nugetconfig ./NuGet.Config --offline