bitwarden/server
Scim (commercial)
Active contributors: admin console team.
Purpose
bitwarden_license/src/Scim/ implements the SCIM 2.0 (System for Cross-domain Identity Management) provisioning API. Enterprise customers point their identity provider (Okta, Azure AD, OneLogin, JumpCloud, etc.) at this endpoint to push users and groups into a Bitwarden organization automatically.
Like Sso, Scim is part of the commercial license; it lives under bitwarden_license/.
Directory layout
bitwarden_license/src/Scim/
├── Program.cs / Startup.cs
├── Controllers/ # /scim/v2/{orgId}/Users, /Groups, /ServiceProviderConfig, /Schemas, /ResourceTypes
├── Users/ # Get/Patch/Post/Put/Delete user commands + SCIM JSON converters
├── Groups/ # Same for groups
├── Models/ # ScimUser, ScimGroup, ScimListResponse, etc.
├── Context/ # Per-request "scim context" carrying the orgId + auth info
├── Utilities/ # JSON patch parsers, pagination helpers
├── ScimSettings.cs
├── appsettings.*.json
└── Dockerfile / build.sh / entrypoint.shKey abstractions
| Type | Path | Description |
|---|---|---|
Startup |
bitwarden_license/src/Scim/Startup.cs |
Registers MVC + JWT auth + the SCIM context middleware + Bitwarden services. |
UsersController / GroupsController |
bitwarden_license/src/Scim/Controllers/ |
Implement the SCIM 2.0 endpoints. |
Per-resource commands (PostUserCommand, PatchUserCommand, …) |
bitwarden_license/src/Scim/Users/ and Groups/ |
One handler per HTTP verb / resource. They wrap the Admin Console IOrganizationUserService and IGroupService. |
IScimContext |
bitwarden_license/src/Scim/Context/IScimContext.cs |
Per-request bag carrying the org id from the URL and the API key used to authenticate. |
| SCIM JSON converters | bitwarden_license/src/Scim/Utilities/ |
Translate SCIM-flavoured JSON into Bitwarden domain models and back. |
Authentication
Each org generates a long-lived SCIM API key (a special ApiClient issued by the cloud control plane). The IdP attaches it as a Bearer token. The Startup JWT pipeline plus ScimContextMiddleware map the bearer to an OrganizationId and ensure the request URL's {orgId} matches.
How it works
sequenceDiagram
participant IdP as Customer IdP
participant Scim
participant Core as Core domain
participant DB
IdP->>Scim: PUT /scim/v2/{orgId}/Users/{id} (Bearer token, SCIM JSON)
Scim->>Scim: ScimContext extracts orgId + verifies token
Scim->>Core: PutUserCommand → IOrganizationUserService
Core->>DB: Update OrganizationUser, Group memberships
Scim-->>IdP: 200 OK SCIM JSONIntegration points
Api— administrators configure SCIM (enable / regenerate token / map endpoint) through endpoints insrc/Api/AdminConsole/Controllers/ScimConfigsController.cs.- Database — same shared repositories (
IOrganizationUserRepository,IGroupRepository) used byApi. - Email — invitations / removals trigger the standard org-membership emails via
IMailService.
Self-host
Bundled with the commercial self-host stack. Behind the bundled nginx as /scim/*.
Entry points for modification
- Add a new SCIM attribute → extend
ScimUser/ScimGroupand thePatchUserCommand/PutUserCommandmapping logic. - Tighten a SCIM PATCH operation → look at the JSON-Patch parser in
Utilities/. - Change auth or rate-limiting → adjust
ScimContextMiddlewareand the JWT setup inStartup.ConfigureServices.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.