Inspect packages from private and custom NuGet feeds safely — select and map sources, use credential providers or explicit configuration, diagnose authentication failures, and reason about source-bound caches and offline operation.
Install
npx skillscat add richlander/dotnet-inspect/dotnet-inspect-private-feeds Install via the SkillsCat registry.
This skill enables safe inspection of packages from private and custom NuGet feeds by allowing source selection, credential management via providers or explicit configuration, and diagnosis of authentication issues. It addresses challenges in accessing non-public package repositories while maintaining security by avoiding hardcoded credentials. Use it when working with private feeds, custom package sources, or when needing to audit package availability and authentication behavior without exposing sensitive information.
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 search Widget --nugetconfig ./NuGet.Config
dnx dotnet-inspect -y -- package MyCompany.Widget --versions-with-feed \
--nugetconfig ./NuGet.ConfigVersion discovery combines all eligible sources and chooses the highest
semantic version; source order is not precedence. Pin Package@Version when
the exact coordinate matters.
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 5 --preview \
--source ./feed --jsonl
dnx dotnet-inspect -y -- package MyCompany.Widget --latest-version --source ./feed
dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 --version --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.jsonLocal and HTTP versions are combined and sorted before the result limit.
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 --bare
dnx dotnet-inspect -y -- package MyCompany.Widget --source ./feed
dnx dotnet-inspect -y -- package 'MyCompany.Widget@1.*' --source ./feed \
--path @readme --content --bareOnline 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. Multi-package
inspection, range-addressed payload commands, package-scoped API and dependency
commands, and offline extraction have not migrated yet. package --versions
can enumerate a range, but ordinary package payload inspection does not
accept a range or --at.
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 discoversNUGET_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.ToolCredential 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.WidgetOutside 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 acceptsARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES withARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN. Service-principal certificate
configuration uses ARTIFACTS_CREDENTIALPROVIDER_FEED_ENDPOINTS.
Explicit credentials
When no provider serves the feed, dotnet-inspect accepts both Username andClearTextPassword 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 uses 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