bitwarden/server
Configuration & secrets
Active contributors: platform team.
Purpose
Every Bitwarden service reads its configuration from the same strongly-typed object: GlobalSettings (src/Core/Settings/GlobalSettings.cs). It is built by services.AddGlobalSettingsServices(Configuration, Environment) and bound from the standard ASP.NET Core configuration sources — appsettings.json, appsettings.<Environment>.json, environment variables, user-secrets, and (in cloud) Azure Key Vault.
Directory layout
src/Core/Settings/
├── GlobalSettings.cs # Root object. Sub-objects for SqlServer, Stripe, Notifications, Mail, ...
├── ConfigurationExtensions.cs # Helpers for binding nested sections
├── DataProtectionSettings.cs
├── DistributedCacheSettings.cs
├── ServiceBusSettings.cs
├── ...
└── (one file per logical config section)
src/Core/Auth/Settings/
└── PasswordlessAuthSettings.cs # Auth-team-owned overrides
src/Identity/IdentityServerSettings.cs
src/Billing/BillingSettings.cs
src/Notifications/ (no separate settings file — uses GlobalSettings)
src/Admin/AdminSettings.csHow it's bound
SharedWeb.Utilities.ServiceCollectionExtensions.AddGlobalSettingsServices:
public static GlobalSettings AddGlobalSettingsServices(
this IServiceCollection services,
IConfiguration configuration,
IWebHostEnvironment env)
{
var globalSettings = new GlobalSettings();
ConfigurationBinder.Bind(configuration.GetSection("globalSettings"), globalSettings);
services.AddSingleton(globalSettings);
services.AddSingleton<IGlobalSettings>(globalSettings);
return globalSettings;
}Sub-objects are bound automatically; e.g. globalSettings.Stripe.ApiKey comes from globalSettings:stripe:apiKey in the configuration.
The configuration sources are layered (later sources override earlier):
appsettings.json— defaults checked into the repo.appsettings.<Environment>.json— environment-specific overrides (Development,Production,QA,SelfHosted).- Environment variables — used heavily by the self-host Docker stack (the
Setuputility writes them toglobal.override.env). - User secrets — for local dev.
- Azure Key Vault (cloud only) — read via the Azure provider when
globalSettings.Vault.AzureKeyvaultUriis set.
Self-host: the Setup utility
util/Setup/ is a small console app that runs once on the operator's host before the stack comes up. It collects an installation id / installation key (issued by the Bitwarden cloud installation API), generates an Identity signing certificate, and writes global.override.env with everything the rest of the stack needs:
- DB connection strings (one per provider, with the right host/user/db).
- Azure Storage connection strings (for Azurite or remote storage).
- Push relay credentials.
- License-server pointer.
- Reverse-proxy URLs.
The compose file generated by Setup mounts global.override.env into every service container.
Per-app appsettings.*.json
Each deployable service has its own appsettings.json that fills in defaults specific to that service (port numbers, log levels, the IpRateLimit policy table). Look at src/Api/appsettings.json, src/Identity/appsettings.json, etc.
The appsettings.SelfHosted.json variants are loaded when the BWS_ENABLE_SELF_HOST env var (or the equivalent settings flag) is set, and override the cloud defaults that don't apply on-prem.
Sensitive values
Never hardcode secrets:
- Cloud — secrets land in Key Vault and are bound at boot via the Azure config provider.
- Self-host — secrets are written to
global.override.envby the Setup utility (encrypted at rest using OS-level mechanisms). - Dev —
dev/setup_secrets.ps1populatesdotnet user-secretsfor each project.
Key fields (Stripe.ApiKey, Mail.Smtp.Password, SqlServer.ConnectionString, OidcIdentityClientKey) must always be supplied via secrets, never appsettings.*.json.
Hot reload
Most settings are bound once at boot. A few — feature flags via IFeatureService, application-cache invalidation via the Service Bus topic — are refreshed at runtime. If you change a config value that's used inside a singleton, you need to restart the service.
Entry points for modification
- New top-level config section → add a property to
GlobalSettingsand a sub-object class undersrc/Core/Settings/. - Read it from a service → inject
GlobalSettings(or a typed sub-object) rather thanIConfiguration. - Change Setup behaviour → edit
util/Setup/. Be aware that self-hosted operators will not re-run Setup automatically; they must runbitwarden.sh updateself.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.