Open-Source Wikis

/

Bitwarden Server

/

Apps

/

Scim (commercial)

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.sh

Key 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 JSON

Integration points

  • Api — administrators configure SCIM (enable / regenerate token / map endpoint) through endpoints in src/Api/AdminConsole/Controllers/ScimConfigsController.cs.
  • Database — same shared repositories (IOrganizationUserRepository, IGroupRepository) used by Api.
  • 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 / ScimGroup and the PatchUserCommand / PutUserCommand mapping logic.
  • Tighten a SCIM PATCH operation → look at the JSON-Patch parser in Utilities/.
  • Change auth or rate-limiting → adjust ScimContextMiddleware and the JWT setup in Startup.ConfigureServices.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Scim (commercial) – Bitwarden Server wiki | Factory