Overview
NuGetGallery.Services is the central business-logic assembly for the NuGet Gallery. It sits between the web
layer and the data layer, providing well-defined service interfaces and their concrete implementations for every
major feature area: authentication (passwords, API keys, OAuth, federated/OIDC credentials), package lifecycle,
user and account management, security policy enforcement, feature flags, telemetry, and cloud storage
abstraction.
The project multi-targets net472 (full .NET Framework, used by the ASP.NET MVC gallery host) and
netstandard2.1 (used by background worker processes). The netstandard2.1 target deliberately excludes the
most UI-coupled directories (Authentication, Mail, Configuration, etc.) via <Compile Remove> directives,
exposing only the subset needed by workers.
The
netstandard2.1 compile exclusions are intentional — many classes in this library depend on
System.Web, OWIN middleware, and ASP.NET MVC types that are not available outside of the full
.NET Framework host. Check the .csproj <Compile Remove> blocks before referencing a type
from a non-net472 context.Role in the System
Gallery Frontend
NuGetGallery (the MVC web app) consumes every service interface defined here — from
IAuthenticationService to IPackageService — via constructor-injected dependencies.Backend Workers
Background job projects reference the
netstandard2.1 slice for shared entities, telemetry
helpers, and infrastructure utilities without pulling in the web-specific stack.NuGetGallery.Core
This library sits directly above
NuGetGallery.Core, which owns EF entity models,
repository abstractions, and low-level package-file operations.NuGet.Services.*
Depends on
NuGet.Services.Configuration, NuGet.Services.Logging, and
NuGet.Services.FeatureFlags for cross-cutting infrastructure.Key Files and Classes
File (relative to NuGetGallery.Services/) | Class / Interface | Purpose |
|---|---|---|
Authentication/AuthenticationService.cs | AuthenticationService | Central auth orchestrator: password login, API key validation, external OAuth sign-in, credential lifecycle |
Authentication/IAuthenticationService.cs | IAuthenticationService | Public contract consumed by controllers and other services |
Authentication/ApiKeyV5.cs | ApiKeyV5 | HISv2-format 84-char API key with embedded user ID, allocation timestamp, expiry, and Marvin32 checksum |
Authentication/ApiKeyV3.cs / ApiKeyV4.cs | ApiKeyV3, ApiKeyV4 | Legacy API key formats retained for backward compatibility |
Authentication/V3Hasher.cs | V3Hasher | PBKDF2/HMAC-SHA256 (10 000 iterations) password hashing, modelled after ASP.NET Core Identity |
Authentication/CredentialBuilder.cs | CredentialBuilder | Factory for creating Credential entities (API keys, passwords, external logins) |
Authentication/Federated/FederatedCredentialService.cs | IFederatedCredentialService | Trusted-publishing: validates OIDC bearer tokens (GitHub Actions, Entra ID service principals) and mints short-lived API keys |
Authentication/Federated/GitHubTokenPolicyValidator.cs | GitHubTokenPolicyValidator | Validates GitHub Actions OIDC JWTs against user-defined federated credential policies |
Authentication/Federated/EntraIdTokenValidator.cs | EntraIdTokenValidator | Validates Entra ID (Azure AD) OIDC tokens for service-principal trusted publishing |
Authentication/Providers/ApiKey/ApiKeyAuthenticator.cs | ApiKeyAuthenticator | OWIN middleware authenticator for X-NuGet-ApiKey header |
Authentication/Providers/AzureActiveDirectoryV2/ | AzureActiveDirectoryV2Authenticator | AAD v2 / MSAL-based external login provider |
Configuration/AppConfiguration.cs | AppConfiguration | Concrete implementation of IAppConfiguration; maps Azure Storage connection strings, SSL settings, feature toggles, and service bus config from app settings |
Configuration/FeatureFlagService.cs | FeatureFlagService | Wraps NuGet.Services.FeatureFlags to expose named flights/features (e.g. NuGetGallery.Typosquatting, NuGetGallery.AsyncAccountDelete) |
Configuration/ConfigurationService.cs | ConfigurationService | Reads and hydrates IAppConfiguration at startup |
Configuration/SecretReader/SecretReaderFactory.cs | SecretReaderFactory | Builds ISecretReader backed by Azure Key Vault for production secret injection |
PackageManagement/PackageService.cs | PackageService | Gallery-specific package CRUD extending CorePackageService; handles dependents, deprecation, vulnerability display |
PackageManagement/IPackageService.cs | IPackageService | Extends ICorePackageService with gallery-only operations |
PackageManagement/PackageOwnershipManagementService.cs | PackageOwnershipManagementService | Add/remove owners, namespace reservation enforcement, audit logging |
PackageManagement/ReservedNamespaceService.cs | ReservedNamespaceService | ID-prefix (namespace) reservation lifecycle |
PackageManagement/PackageVulnerabilitiesManagementService.cs | PackageVulnerabilitiesManagementService | Ingests and stores vulnerability advisories against package versions |
UserManagement/UserService.cs | UserService | User and organization CRUD, credential management, profile updates |
AccountManagement/DeleteAccountService.cs | DeleteAccountService | Synchronous account deletion: clears credentials, transfers/orphans packages, removes from orgs |
AccountManagement/AsynchronousDeleteAccountService.cs | AsynchronousDeleteAccountService | Enqueues account deletion via Azure Service Bus for async processing |
Security/SecurityPolicyService.cs | SecurityPolicyService | Evaluates user-level and package-level security policies (required signer, org-tenant, metadata compliance) |
Storage/ContentObjectService.cs | ContentObjectService | Periodically refreshes JSON configuration blobs (login discontinuation, cert config, typosquatting lists, etc.) from Azure Blob Storage |
Storage/CloudBlobFileStorageService.cs | CloudBlobFileStorageService | Azure Blob Storage adapter implementing IFileStorageService |
Telemetry/TelemetryService.cs | TelemetryService | Application Insights event/metric wrapper; tracks package push, delete, OData queries, search, auth events |
Telemetry/ITelemetryService.cs | ITelemetryService | ~80-method interface covering every tracked domain event |
SupportRequest/SupportRequestService.cs | SupportRequestService | CRUD over the separate support-request SQL database (ISupportRequestDbContext) |
Permissions/ActionsRequiringPermissions.cs | ActionsRequiringPermissions | Static registry of all permission actions (upload, delete, manage owners, etc.) |
Mail/Messages/ | PackageOwnershipRequest*Message | Strongly-typed email message objects for ownership-request flow |
Dependencies
NuGet Package References
| Package | Target | Purpose |
|---|---|---|
Microsoft.ApplicationInsights | both | Telemetry client for Application Insights |
Microsoft.Identity.Web | both | MSAL / Entra ID token validation for federated credentials |
Microsoft.Security.Utilities.Core | both | HISv2 (“Highly Identifiable Secret”) format used in ApiKeyV5 |
System.Text.Json | both | JSON serialisation for content-object blobs |
Microsoft.AspNet.Mvc | net472 | MVC action results, controller base types |
Microsoft.AspNetCore.Cryptography.KeyDerivation | net472 | PBKDF2 key derivation used in V3Hasher |
Microsoft.Owin / Microsoft.Owin.Security.* | net472 | OWIN pipeline, cookie auth, OpenID Connect, Microsoft Account providers |
NuGet.Protocol | net472 | NuGet client protocol types |
NuGet.StrongName.WebBackgrounder | net472 | Background job scheduling within the ASP.NET host |
Internal Project References
| Project | Target | Relationship |
|---|---|---|
NuGetGallery.Core | both | Entity models, repository interfaces, core package-file services |
NuGet.Services.Configuration | net472 | ConfigurationService base, ISecretReader abstractions |
NuGet.Services.Logging | net472 | Structured logging setup and IDiagnosticsService |
Notable Patterns and Implementation Details
Dual-target architecture — The
.csproj uses <Compile Remove> to strip the entire
Authentication, Configuration, Mail, Permissions, Security, Storage, and
Telemetry folders from the netstandard2.1 build. This is the primary mechanism for
keeping background workers free of ASP.NET dependencies.API key versioning (V3 → V5) — Three key formats coexist. V3 uses PBKDF2-hashed GUIDs.
V4 adds scope-aware prefixes. V5 uses the HISv2 standard (84 base62 characters) with embedded
metadata (user ID, allocation time, environment code, expiry) and a Marvin32 checksum for
fast pre-DB validation. All formats are still validated to support existing long-lived keys.
Federated credential / trusted publishing —
FederatedCredentialService issues
short-lived API keys (≤ 15 minutes, encoded in the V5 key body) after validating an OIDC
bearer token from GitHub Actions or an Entra ID service principal against policies stored
per-user in the database. The short lifetime is enforced both in the V5 key metadata and
by the database expiry field.