Configuration
AvantiPoint Packages is configured through a combination of appsettings.json and the fluent API in your Program.cs file.
Basic Configuration Structure
Your appsettings.json should include these sections:
{
"Database": {
"Type": "Sqlite"
},
"Storage": {
"Type": "FileStorage",
"Path": "App_Data"
},
"ConnectionStrings": {
"Sqlite": "Data Source=packages.db",
"SqlServer": "Server=(localdb)\\mssqllocaldb;Database=AvantiPointPackages;Trusted_Connection=True;",
"MySql": "Server=localhost;Database=packages;User=root;Password=password;",
"PostgreSql": "Host=localhost;Database=packages;Username=postgres;Password=password;"
},
"Mirror": {
"NuGet.org": {
"FeedUrl": "https://api.nuget.org/v3/index.json"
}
},
"Shields": {
"ServerName": "My Package Feed"
}
}
Database Configuration
AvantiPoint Packages supports four database providers:
SQLite
Perfect for development and small deployments:
{
"Database": {
"Type": "Sqlite"
},
"ConnectionStrings": {
"Sqlite": "Data Source=packages.db"
}
}
In Program.cs:
builder.Services.AddNuGetPackageApi(options =>
{
options.AddSqliteDatabase("Sqlite");
});
SQL Server
Recommended for production Windows deployments:
{
"Database": {
"Type": "SqlServer"
},
"ConnectionStrings": {
"SqlServer": "Server=myserver;Database=AvantiPointPackages;User Id=sa;Password=yourpassword;"
}
}
In Program.cs:
builder.Services.AddNuGetPackageApi(options =>
{
options.AddSqlServerDatabase("SqlServer");
});
MySQL / MariaDB
Great for cross-platform production deployments:
{
"Database": {
"Type": "MySql"
},
"ConnectionStrings": {
"MySql": "Server=localhost;Database=packages;User=root;Password=password;"
}
}
In Program.cs:
builder.Services.AddNuGetPackageApi(options =>
{
// For MySQL
options.AddMySqlDatabase("MySql");
// Or for MariaDB
options.AddMariaDb("MariaDb");
});
PostgreSQL
Excellent for production deployments requiring advanced features:
{
"Database": {
"Type": "PostgreSql"
},
"ConnectionStrings": {
"PostgreSql": "Host=localhost;Database=packages;Username=postgres;Password=password;"
}
}
In Program.cs:
builder.Services.AddNuGetPackageApi(options =>
{
options.AddPostgreSqlDatabase("PostgreSql");
});
Connection String by Name
You can reference connection strings by name from the ConnectionStrings section:
options.AddSqlServerDatabase("SqlServer"); // Uses ConnectionStrings:SqlServer
Environment-Specific Configuration
Use different databases for different environments:
builder.Services.AddNuGetPackageApi(options =>
{
if (options.Environment.IsDevelopment())
{
options.AddSqliteDatabase("Sqlite");
}
else
{
options.AddSqlServerDatabase("SqlServer");
}
});
Or use appsettings.{Environment}.json:
appsettings.Development.json:
{
"Database": {
"Type": "Sqlite"
}
}
appsettings.Production.json:
{
"Database": {
"Type": "SqlServer"
}
}
Storage Configuration
File Storage
Store packages on the local file system:
{
"Storage": {
"Type": "FileStorage",
"Path": "App_Data"
}
}
In Program.cs:
options.AddFileStorage();
The path can be absolute or relative to the application directory. You can also specify a network share:
{
"Storage": {
"Type": "FileStorage",
"Path": "\\\\server\\share\\packages"
}
}
Azure Blob Storage
Store packages in Azure:
First, add the package:
dotnet add package AvantiPoint.Packages.Azure
Configuration:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "my-nuget-feed",
"ConnectionString": "DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"
}
}
Or use account name and key separately:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "my-nuget-feed",
"AccountName": "mystorageaccount",
"AccessKey": "your-access-key"
}
}
In Program.cs:
using AvantiPoint.Packages.Azure;
options.AddAzureBlobStorage();
AWS S3 Storage
Store packages in Amazon S3:
First, add the package:
dotnet add package AvantiPoint.Packages.Aws
Configuration:
{
"Storage": {
"Type": "AwsS3",
"Region": "us-west-2",
"Bucket": "my-nuget-feed",
"Prefix": "packages",
"UseInstanceProfile": true
}
}
For explicit credentials:
{
"Storage": {
"Type": "AwsS3",
"Region": "us-west-2",
"Bucket": "my-nuget-feed",
"AccessKey": "your-access-key",
"SecretKey": "your-secret-key"
}
}
In Program.cs:
using AvantiPoint.Packages.Aws;
options.AddAwsS3Storage();
Upstream Mirrors
Configure upstream package sources to mirror or proxy. In v4, sources are PackageSource entities with a per-source CachingStrategy (IndexAndCache, CacheOnly, or ProxyOnly).
{
"PackageSources": [
{
"Name": "NuGet.org",
"FeedUrl": "https://api.nuget.org/v3/index.json",
"Type": "Upstream",
"CachingStrategy": "IndexAndCache",
"IsEnabled": true
}
],
"Search": {
"Type": "Database",
"IncludeMirroredPackages": true,
"EnableUpstreamSearch": false,
"UpstreamSearchTimeout": "00:00:02",
"MergeStrategy": "LocalPreferred"
}
}
Configure PackageSource rows via the Host UI (/Account/PackageSources), database seeding, or Mirror:NuGetConfigPath. Combine CachingStrategy with Search.IncludeMirroredPackages per Deployment Scenarios.
Deprecated: The legacy
Mirrordictionary andAddUpstreamSourcecode helpers are deprecated in v4.0. See Upstream Mirrors for migration guidance.
Local NuGet cache
The feed can read package archives from an existing NuGet global packages folder before contacting configured upstream sources:
{
"LocalCache": {
"Enabled": true,
"Path": "/nuget-cache",
"CopyToFeedStorage": false
}
}
| Setting | Default | Behavior |
|---|---|---|
Enabled | false | Enables local cache reads |
Path | NUGET_PACKAGES, then ~/.nuget/packages | Root of the NuGet global packages folder |
CopyToFeedStorage | false | Copies cache hits into feed storage without database or search records |
When copying is disabled, the package is streamed directly from the global packages folder and no duplicate is created. The folder can therefore be mounted read-only. Local cache lookups only apply to exact package content requests. Package version discovery still comes from the feed database or configured upstream sources.
Via Code (deprecated)
builder.Services.AddNuGetPackageApi(options =>
{
options.AddFileStorage();
options.AddSqliteDatabase("Sqlite");
// Deprecated in v4 — use PackageSources instead
options.AddUpstreamSource("NuGet.org", "https://api.nuget.org/v3/index.json");
options.AddUpstreamSource("Telerik", "https://nuget.telerik.com/nuget", "user@example.com", "password");
});
Note: Sources added via code will override configuration-based sources.
Shields.io Badges
Enable package version badges:
{
"Shields": {
"ServerName": "My Feed"
}
}
With this enabled, you can use badges in your documentation:

If ServerName is null or empty, the shields endpoint is disabled.
Advanced Options
Package Deletion
Allow or disallow package deletion (default: allow):
{
"PackageDeletion": {
"Enabled": false
}
}
Search and discovery
Configure package search behavior and which package origins appear in browse/search results:
{
"Search": {
"Type": "Database",
"IncludeMirroredPackages": true
}
}
IncludeMirroredPackages
Controls whether mirrored upstream packages appear in search, autocomplete, and registration discovery. Defaults to true.
| Value | Search includes | Restore behavior |
|---|---|---|
true (default) | Published and Mirrored packages | All origins available for restore |
false | Published packages only | Mirrored and cached packages still restorable by id/version |
Packages with origin Cached (CacheOnly strategy) are never included in search, regardless of this setting.
This setting works together with per-source CachingStrategy on PackageSources. See Deployment Scenarios for recommended combinations.
Defaults that preserve existing behavior:
Search.IncludeMirroredPackagesdefaults totruePackageSource.CachingStrategydefaults toIndexAndCache
No changes are required when upgrading unless you want a different deployment pattern (commercial/private feed, lightweight Docker, etc.).
Search provider type
Search.Type selects the search backend: Database (default), Null, AzureSearch, OpenSearch, or Elasticsearch. External search providers honor the same origin filters via IncludeMirroredPackages.
Federated upstream search
Set Search.EnableUpstreamSearch to true to merge each local NuGet search page with live results from enabled upstream PackageSource rows. This is useful for lightweight developer feeds that proxy packages without indexing the entire upstream catalog. It is disabled by default, so existing deployments do not make additional network requests.
UpstreamSearchTimeout limits the complete upstream operation across all configured sources. If that timeout expires, the request returns the local results. A failure from one source does not discard results from other sources.
MergeStrategy accepts these values:
| Value | Behavior |
|---|---|
LocalPreferred (default) | Return one entry per package ID and retain local metadata when the same ID exists upstream |
Deduplicate | Return one entry per package ID and select the entry with the highest package version |
Union | Return all entries in source-priority order, including repeated package IDs |
Federation applies to the NuGet search endpoint only. Autocomplete, version enumeration, and dependent queries continue to use the configured local search provider. Upstream credentials and priority come from the existing PackageSource configuration.
Repository Package Signing
Enable repository-level package signing:
{
"Signing": {
"Mode": "SelfSigned",
"CertificatePasswordSecret": "Signing:CertificatePassword",
"TimestampServerUrl": "http://timestamp.digicert.com",
"PublishSignaturePolicy": "ReSign",
"SelfSigned": {
"SubjectName": "CN=My Repository Signer, O=MyOrg, C=US",
"KeySize": "KeySize4096",
"ValidityInDays": 3650,
"CertificatePath": "certs/repository-signing.pfx"
}
}
}
Signing Modes:
SelfSigned- Automatically generate and manage certificatesStoredCertificate- Use existing certificate from file or certificate storeAzureKeyVault- Use certificate from Azure Key Vault (requiresAvantiPoint.Packages.Signing.Azurepackage)AwsKms- Use AWS KMS with HSM-backed keys (requiresAvantiPoint.Packages.Signing.Awspackage)AwsSigner- Use AWS Signer managed code signing (requiresAvantiPoint.Packages.Signing.Awspackage)GcpKms- Use Google Cloud KMS with HSM protection (requiresAvantiPoint.Packages.Signing.Gcppackage)GcpHsm- Use Google Cloud HSM (requiresAvantiPoint.Packages.Signing.Gcppackage)
Publish-Time Signature Policy:
ReSign(default) - Strip existing repository signatures and replace with our ownReject- Reject packages that already have repository signatures
For detailed signing configuration, see Package Signing.
Complete Example
Here's a complete production configuration:
appsettings.Production.json:
{
"Database": {
"Type": "SqlServer"
},
"Storage": {
"Type": "AzureBlobStorage",
"Container": "packages",
"ConnectionString": "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=...;EndpointSuffix=core.windows.net"
},
"ConnectionStrings": {
"SqlServer": "Server=tcp:myserver.database.windows.net,1433;Database=packages;User ID=admin;Password=...;Encrypt=true;"
},
"Mirror": {
"NuGet.org": {
"FeedUrl": "https://api.nuget.org/v3/index.json"
}
},
"Shields": {
"ServerName": "Contoso Packages"
}
}
Program.cs:
using AvantiPoint.Packages;
using AvantiPoint.Packages.Azure;
using AvantiPoint.Packages.Core;
using AvantiPoint.Packages.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<IPackageAuthenticationService, MyAuthService>();
builder.Services.AddScoped<INuGetFeedActionHandler, MyActionHandler>();
builder.Services.AddNuGetPackageApi(options =>
{
options.AddAzureBlobStorage();
options.AddSqlServerDatabase("SqlServer");
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRouting();
app.MapNuGetApiRoutes();
await app.RunAsync();
See Also
- Deployment Scenarios - Commercial, enterprise mirror, and lightweight dev/Docker patterns
- Database - Detailed database configuration
- Storage - Detailed storage configuration
- Upstream Mirrors - Detailed mirror configuration
- Package Signing - Detailed signing configuration