Skip to main content

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 / InterfacePurpose
Authentication/AuthenticationService.csAuthenticationServiceCentral auth orchestrator: password login, API key validation, external OAuth sign-in, credential lifecycle
Authentication/IAuthenticationService.csIAuthenticationServicePublic contract consumed by controllers and other services
Authentication/ApiKeyV5.csApiKeyV5HISv2-format 84-char API key with embedded user ID, allocation timestamp, expiry, and Marvin32 checksum
Authentication/ApiKeyV3.cs / ApiKeyV4.csApiKeyV3, ApiKeyV4Legacy API key formats retained for backward compatibility
Authentication/V3Hasher.csV3HasherPBKDF2/HMAC-SHA256 (10 000 iterations) password hashing, modelled after ASP.NET Core Identity
Authentication/CredentialBuilder.csCredentialBuilderFactory for creating Credential entities (API keys, passwords, external logins)
Authentication/Federated/FederatedCredentialService.csIFederatedCredentialServiceTrusted-publishing: validates OIDC bearer tokens (GitHub Actions, Entra ID service principals) and mints short-lived API keys
Authentication/Federated/GitHubTokenPolicyValidator.csGitHubTokenPolicyValidatorValidates GitHub Actions OIDC JWTs against user-defined federated credential policies
Authentication/Federated/EntraIdTokenValidator.csEntraIdTokenValidatorValidates Entra ID (Azure AD) OIDC tokens for service-principal trusted publishing
Authentication/Providers/ApiKey/ApiKeyAuthenticator.csApiKeyAuthenticatorOWIN middleware authenticator for X-NuGet-ApiKey header
Authentication/Providers/AzureActiveDirectoryV2/AzureActiveDirectoryV2AuthenticatorAAD v2 / MSAL-based external login provider
Configuration/AppConfiguration.csAppConfigurationConcrete implementation of IAppConfiguration; maps Azure Storage connection strings, SSL settings, feature toggles, and service bus config from app settings
Configuration/FeatureFlagService.csFeatureFlagServiceWraps NuGet.Services.FeatureFlags to expose named flights/features (e.g. NuGetGallery.Typosquatting, NuGetGallery.AsyncAccountDelete)
Configuration/ConfigurationService.csConfigurationServiceReads and hydrates IAppConfiguration at startup
Configuration/SecretReader/SecretReaderFactory.csSecretReaderFactoryBuilds ISecretReader backed by Azure Key Vault for production secret injection
PackageManagement/PackageService.csPackageServiceGallery-specific package CRUD extending CorePackageService; handles dependents, deprecation, vulnerability display
PackageManagement/IPackageService.csIPackageServiceExtends ICorePackageService with gallery-only operations
PackageManagement/PackageOwnershipManagementService.csPackageOwnershipManagementServiceAdd/remove owners, namespace reservation enforcement, audit logging
PackageManagement/ReservedNamespaceService.csReservedNamespaceServiceID-prefix (namespace) reservation lifecycle
PackageManagement/PackageVulnerabilitiesManagementService.csPackageVulnerabilitiesManagementServiceIngests and stores vulnerability advisories against package versions
UserManagement/UserService.csUserServiceUser and organization CRUD, credential management, profile updates
AccountManagement/DeleteAccountService.csDeleteAccountServiceSynchronous account deletion: clears credentials, transfers/orphans packages, removes from orgs
AccountManagement/AsynchronousDeleteAccountService.csAsynchronousDeleteAccountServiceEnqueues account deletion via Azure Service Bus for async processing
Security/SecurityPolicyService.csSecurityPolicyServiceEvaluates user-level and package-level security policies (required signer, org-tenant, metadata compliance)
Storage/ContentObjectService.csContentObjectServicePeriodically refreshes JSON configuration blobs (login discontinuation, cert config, typosquatting lists, etc.) from Azure Blob Storage
Storage/CloudBlobFileStorageService.csCloudBlobFileStorageServiceAzure Blob Storage adapter implementing IFileStorageService
Telemetry/TelemetryService.csTelemetryServiceApplication Insights event/metric wrapper; tracks package push, delete, OData queries, search, auth events
Telemetry/ITelemetryService.csITelemetryService~80-method interface covering every tracked domain event
SupportRequest/SupportRequestService.csSupportRequestServiceCRUD over the separate support-request SQL database (ISupportRequestDbContext)
Permissions/ActionsRequiringPermissions.csActionsRequiringPermissionsStatic registry of all permission actions (upload, delete, manage owners, etc.)
Mail/Messages/PackageOwnershipRequest*MessageStrongly-typed email message objects for ownership-request flow

Dependencies

NuGet Package References

PackageTargetPurpose
Microsoft.ApplicationInsightsbothTelemetry client for Application Insights
Microsoft.Identity.WebbothMSAL / Entra ID token validation for federated credentials
Microsoft.Security.Utilities.CorebothHISv2 (“Highly Identifiable Secret”) format used in ApiKeyV5
System.Text.JsonbothJSON serialisation for content-object blobs
Microsoft.AspNet.Mvcnet472MVC action results, controller base types
Microsoft.AspNetCore.Cryptography.KeyDerivationnet472PBKDF2 key derivation used in V3Hasher
Microsoft.Owin / Microsoft.Owin.Security.*net472OWIN pipeline, cookie auth, OpenID Connect, Microsoft Account providers
NuGet.Protocolnet472NuGet client protocol types
NuGet.StrongName.WebBackgroundernet472Background job scheduling within the ASP.NET host

Internal Project References

ProjectTargetRelationship
NuGetGallery.CorebothEntity models, repository interfaces, core package-file services
NuGet.Services.Configurationnet472ConfigurationService base, ISecretReader abstractions
NuGet.Services.Loggingnet472Structured 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.
LegacyHasher (Authentication/LegacyHasher.cs) implements the old MD5/SHA1-based credential hashing that predates V3Hasher. It is retained solely to validate credentials created before the PBKDF2 migration and automatically upgrades them on successful login. New credentials must never use this hasher.
Federated credential / trusted publishingFederatedCredentialService 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.
ContentObjectService caches JSON blobs from Azure Blob Storage with a 5-minute refresh interval (RefreshInterval = TimeSpan.FromMinutes(5)). Feature-gated configuration objects (typosquatting lists, login discontinuation rules, cert allowlists) are all loaded this way, allowing live updates without redeployment.
SecurityPolicyService handlers are registered as static Lazy<IEnumerable<...>> singletons. Adding a new policy handler requires updating both CreateUserHandlers() and CreatePackageHandlers() factory methods inside SecurityPolicyService.cs, otherwise the new handler will never be evaluated.