bitwarden/server
Admin
Active contributors: many — every Bitwarden product team adds tools here.
Purpose
src/Admin/ is the Razor-Pages internal admin UI Bitwarden support and operations staff use to look up users, organisations, billing records, sends, audit events, and licenses. It is not exposed to customers; the cloud deployment runs it behind an internal authentication boundary, and the self-host bundle includes it as the operator UI accessed via the Setup wizard.
Directory layout
src/Admin/
├── Program.cs / Startup.cs
├── Controllers/ # MVC controllers (logins / sessions / scheduled actions)
├── Views/ # Razor views grouped by area: Users, Organizations, Billing, Tools, Logs, Sends, Notifications
├── AdminConsole/ # Org-management views and controllers
├── Auth/ # Sign-in / passwordless link flow (Magic-link based; admins log in with email links)
├── Billing/ # Tools to update subscriptions, generate licenses, run promotion codes
├── HostedServices/ # Background jobs specific to the admin UI
├── IdentityServer/ # Local IdentityServer config for the magic-link sign-in
├── Jobs/ # Quartz jobs (e.g. license refresh, scheduled cleanup)
├── Models/ # ViewModels shared across views
├── Sass/ # SCSS source compiled by webpack
├── TagHelpers/ # Razor tag helpers
├── Tools/ # Tools-controller views (sends, sponsorships, manage data)
├── Utilities/ # Shared helpers
├── package.json + webpack.config.js # JS/SCSS build pipeline
└── appsettings.*.json + Dockerfile + entrypoint.sh + bundleconfig.jsonKey abstractions
| Type | Path | Description |
|---|---|---|
Startup |
src/Admin/Startup.cs |
Pulls in MVC + Razor Pages, distributed cache, the local sign-in IdentityServer, Bitwarden services, and Quartz jobs. |
LoginController (passwordless link) |
src/Admin/Auth/Controllers/LoginController.cs |
Issues a one-time email link; only allow-listed admin emails (in globalSettings.Admin) can authenticate. |
UsersController / Views/Users/ |
src/Admin/Controllers/UsersController.cs |
Look up a user, view orgs, devices, two-factor, premium status, send a recovery email, or delete the account. |
OrganizationsController |
src/Admin/AdminConsole/Controllers/OrganizationsController.cs |
View / edit org plan, license, members, providers; trigger ability-cache invalidation. |
ToolsController |
src/Admin/Controllers/ToolsController.cs (and the Billing-team-owned src/Admin/Views/Tools/) |
Promotion codes, licence generation, manual subscription tweaks. |
LogsController |
src/Admin/Controllers/LogsController.cs |
Reads the Event table to surface a filtered event log. |
JobsHostedService |
src/Admin/HostedServices/ and src/Admin/Jobs/ |
License refresh, expiring sponsorship cleanup, etc. |
How it works
Authentication for the Admin UI is email-link based. The LoginController emails a magic-link, the click validates a Bitwarden Tokenable signed payload, and a session cookie is set. The allow-list of admin emails sits in globalSettings.Admin.Admins (and OwnerAdmins for super-users).
After login, Razor pages render UI that ultimately speaks directly to the database via the same src/Core/ services and repositories the API uses. There is no API client for the Admin UI; it shares the same in-process bindings and writes back through IUserService, IOrganizationService, IPaymentService, and so on.
Integration points
- Same database as
Api. Many actions call intoIUserService,IOrganizationService,IPaymentService,IFeatureService,ILicensingService,IAttachmentStorageService. - Sends
IEventServiceaudit rows for sensitive operations (force-rotate-key, cancel-subscription, etc.). - Generates org licenses (signed with the cert in
src/Core/licensing.cer) — used by self-hosted enterprise customers.
UI build
src/Admin/Sass/→ webpack-bundled CSS (webpack.config.js).src/Admin/wwwroot/→ static assets.src/Admin/package.jsonis the only place where Node tooling is required to build the server.
Entry points for modification
- Adding a support tool → drop a new Razor view under
src/Admin/Views/Tools/and a controller action undersrc/Admin/Controllers/. Wire authorization with[Authorize(Roles = "Admin,Owner")](Roles map to claims set during magic-link sign-in). - Surfacing a new field on the user / org details page → edit the corresponding view model in
src/Admin/Models/and the Razor view. - Adding a Quartz job → register it in
JobsHostedService(src/Admin/HostedServices/JobsHostedService.cs).
For a deeper view of the cross-cutting tools (sponsorships, licences, support actions) see features/billing-and-subscriptions and features/organizations-and-policies.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.