Skip to main content
The SSO service provides enterprise Single Sign-On authentication using SAML 2.0 and OpenID Connect protocols, enabling organizations to integrate with their existing identity providers.

Overview

SSO is an enterprise feature available in the commercial version of Bitwarden Server.
The SSO service provides:
  • SAML 2.0: Service Provider implementation for SAML-based SSO
  • OpenID Connect: Relying Party for OIDC authentication
  • Multi-Tenancy: Organization-specific SSO configurations
  • Just-In-Time Provisioning: Automatic user account creation
  • Domain Verification: Trusted domain-based login routing
  • Member Decryption Options: Support for Key Connector and Account Recovery

Architecture

Authentication Flows

SAML 2.0 Flow

1

SSO Initiation

User enters email or clicks SSO login button
2

Organization Lookup

SSO service identifies organization by domain or identifier
3

SAML Request

SSO service generates SAML AuthnRequest and redirects to IdP
4

IdP Authentication

User authenticates with organization’s identity provider
5

SAML Response

IdP sends SAML assertion back to SSO service
6

Validation

SSO service validates SAML signature and assertions
7

Token Exchange

SSO service redirects to Identity service with authorization code
8

Access Token

Identity service issues OAuth tokens for client application

OpenID Connect Flow

1

SSO Initiation

User initiates login via organization SSO
2

OIDC Authorization

SSO service redirects to OIDC provider with authorization request
3

User Authentication

User authenticates with OIDC provider
4

Authorization Code

OIDC provider returns authorization code
5

Token Exchange

SSO service exchanges code for ID token and access token
6

User Info

SSO service retrieves user information from OIDC UserInfo endpoint
7

Bitwarden Login

SSO service creates/updates user and redirects to Identity service

Configuration

From bitwarden_license/src/Sso/Startup.cs:26:
Service Configuration
public void ConfigureServices(IServiceCollection services)
{
    // Settings
    var globalSettings = services.AddGlobalSettingsServices(Configuration, Environment);
    
    // Stripe Billing
    StripeConfiguration.ApiKey = globalSettings.Stripe.ApiKey;
    
    // Data Protection
    services.AddCustomDataProtectionServices(Environment, globalSettings);
    
    // Repositories
    services.AddDatabaseRepositories(globalSettings);
    
    // Caching
    services.AddMemoryCache();
    services.AddDistributedCache(globalSettings);
    
    // MVC with views
    services.AddControllersWithViews();
    
    // Authentication
    services.AddDistributedIdentityServices();
    services.AddAuthentication()
        .AddCookie(AuthenticationSchemes.BitwardenExternalCookieAuthenticationScheme);
    
    // SSO Services
    services.AddSsoServices(globalSettings);
    
    // IdentityServer
    services.AddSsoIdentityServerServices(Environment, globalSettings);
    
    // Identity
    services.AddCustomIdentityServices(globalSettings);
    
    // Business Services
    services.AddBaseServices(globalSettings);
    services.AddDefaultServices(globalSettings);
    services.AddCoreLocalizationServices();
    services.AddBillingOperations();
}

SAML 2.0 Implementation

Service Provider Metadata

The SSO service exposes SAML metadata for IdP configuration:
GET /saml2/{organizationId}/metadata
Metadata includes:
  • Entity ID
  • Assertion Consumer Service URL
  • Single Logout Service URL
  • Signing certificates
  • Supported bindings (HTTP-POST, HTTP-Redirect)

Assertion Consumer Service

Receives and validates SAML assertions:
POST /saml2/{organizationId}/Acs
Validation steps:
  1. Signature verification
  2. Timestamp validation (NotBefore/NotOnOrAfter)
  3. Audience restriction
  4. Attribute extraction
  5. User provisioning/update

Required SAML Attributes

AttributeDescriptionRequired
email or emailaddressUser email addressYes
name or displaynameFull nameNo
firstname or givennameFirst nameNo
lastname or surnameLast nameNo

OpenID Connect Implementation

Configuration Discovery

The SSO service discovers OIDC provider configuration via:
{authority}/.well-known/openid-configuration

Required OIDC Claims

ClaimDescriptionRequired
emailUser email addressYes
nameFull nameNo
given_nameFirst nameNo
family_nameLast nameNo
subSubject identifierYes

Token Validation

ID tokens are validated for:
  • Signature (using IdP’s public keys)
  • Issuer matches configuration
  • Audience matches client ID
  • Expiration timestamp
  • Nonce validation

SSO Configuration Models

Organizations configure SSO via the web vault:

SAML 2.0 Settings

{
  "configType": 1,
  "data": {
    "spEntityId": "https://sso.bitwarden.com/saml2/{orgId}",
    "spMetadataUrl": "https://sso.bitwarden.com/saml2/{orgId}/metadata",
    "spAcsUrl": "https://sso.bitwarden.com/saml2/{orgId}/Acs",
    "idpEntityId": "https://idp.example.com",
    "idpBindingType": "HttpPost",
    "idpSingleSignOnServiceUrl": "https://idp.example.com/sso",
    "idpSingleLogOutServiceUrl": "https://idp.example.com/slo",
    "idpX509PublicCert": "-----BEGIN CERTIFICATE-----...",
    "idpAllowUnsolicitedAuthnResponse": false,
    "idpWantAuthnRequestsSigned": false,
    "outboundSigningAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
  }
}

OIDC Settings

{
  "configType": 2,
  "data": {
    "authority": "https://login.microsoftonline.com/{tenant}/v2.0",
    "clientId": "client_id",
    "clientSecret": "client_secret",
    "metadataAddress": "https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration",
    "redirectUri": "https://sso.bitwarden.com/oidc-signin",
    "postLogoutRedirectUri": "https://sso.bitwarden.com/logged-out",
    "scopes": "openid profile email",
    "acrValues": "",
    "expectedReturnAcrValue": ""
  }
}

Middleware Pipeline

From bitwarden_license/src/Sso/Startup.cs:91:
Request Pipeline
public void Configure(IApplicationBuilder app)
{
    // Security headers
    app.UseMiddleware<SecurityHeadersMiddleware>();
    
    // Set server origin
    if (!environment.IsDevelopment())
    {
        var uri = new Uri(globalSettings.BaseServiceUri.Sso);
        app.Use(async (ctx, next) =>
        {
            ctx.RequestServices.GetRequiredService<IServerUrls>().Origin = 
                $"{uri.Scheme}://{uri.Host}";
            await next();
        });
    }
    
    // Self-hosted path base
    if (globalSettings.SelfHosted)
    {
        app.UsePathBase("/sso");
        app.UseForwardedHeaders(globalSettings);
    }
    
    // Localization
    app.UseCoreLocalization();
    
    // Static files (login pages)
    app.UseStaticFiles();
    
    // Routing
    app.UseRouting();
    
    // CORS
    app.UseCors(policy => policy
        .SetIsOriginAllowed(o => CoreHelpers.IsCorsOriginAllowed(o, globalSettings))
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
    
    // Current context
    app.UseMiddleware<CurrentContextMiddleware>();
    
    // IdentityServer with custom authentication
    app.UseIdentityServer(new IdentityServerMiddlewareOptions
    {
        AuthenticationMiddleware = app => app.UseMiddleware<SsoAuthenticationMiddleware>()
    });
    
    // Authorization and Controllers
    app.UseAuthorization();
    app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute());
}

Controllers

The SSO service includes several controllers:

Account Controller

Handles SSO login flows:
/Account/Login - Initiate SSO login
/Account/ExternalChallenge - Challenge external IdP
/Account/Callback - Handle IdP callback
/Account/Logout - SSO logout

Metadata Controller

SAML metadata endpoints:
/saml2/{orgId}/metadata - SAML SP metadata
/saml2/{orgId}/Acs - Assertion Consumer Service

Home Controller

Error pages and information:
/Error - Error display
/Alive - Health check

Domain Verification

Organizations can verify domains to enable automatic SSO routing:
1

Add Domain

Navigate to Organization Settings → Verified Domains
2

Generate DNS Record

System generates TXT record for verification
3

Add DNS Record

Add TXT record to domain’s DNS configuration
4

Verify Domain

Click “Verify” to validate DNS record
5

Enable SSO

Users with verified domain email can use SSO automatically

Member Decryption Options

SSO supports different vault decryption methods:

Master Password

Traditional approach - users decrypt vault with master password after SSO login.

Key Connector

Stores encryption keys on customer’s infrastructure:

Trusted Devices

Device-based encryption key approval:

Just-In-Time Provisioning

When enabled, SSO automatically creates user accounts:
JIT provisioning creates organization members but does not grant collection access automatically.
JIT workflow:
  1. User authenticates via SSO
  2. SSO service checks if user exists
  3. If new user, create invitation
  4. Auto-confirm invitation
  5. Add to default group (if configured)
  6. Redirect to vault

Deployment

Environment Variables

GLOBALSETTINGS__SELFHOSTED=true
GLOBALSETTINGS__SQLSERVER__CONNECTIONSTRING=<connection>
GLOBALSETTINGS__BASESERVICEURI__SSO=https://sso.example.com
GLOBALSETTINGS__STRIPE__APIKEY=<stripe_key>

Docker

docker run -d \
  --name bitwarden-sso \
  -p 5006:5000 \
  -e GLOBALSETTINGS__SelfHosted=true \
  -e GLOBALSETTINGS__SqlServer__ConnectionString="<connection>" \
  bitwarden/sso:latest

Self-Hosted Configuration

In self-hosted deployments, the SSO service runs at /sso path.
Nginx Configuration
location /sso {
    proxy_pass http://sso:5000/sso;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Supported Identity Providers

Azure AD

Microsoft Entra ID via OIDC or SAML

Okta

Okta Identity Cloud (OIDC/SAML)

OneLogin

OneLogin SAML integration

ADFS

Active Directory Federation Services

Google Workspace

Google SAML integration

Duo

Duo SSO with SAML

PingFederate

Ping Identity solutions

Auth0

Auth0 OIDC integration

Troubleshooting

SAML Common Issues

IssueSolution
Invalid signatureVerify IdP certificate in configuration
Timestamp validation failedCheck server time synchronization (NTP)
Missing email attributeConfigure email claim in IdP
Audience restrictionVerify Entity ID matches configuration

OIDC Common Issues

IssueSolution
Invalid clientVerify client ID in configuration
Redirect URI mismatchCheck redirect URI matches registration
Invalid scopeEnsure openid email scopes are granted
Token validation failedVerify authority URL and client secret

Debug Logging

{
  "Logging": {
    "LogLevel": {
      "Bit.Sso": "Debug",
      "Duende.IdentityServer": "Debug"
    }
  }
}

Security Considerations

SSO implementations must follow security best practices:
  • Certificate Validation: Always validate IdP certificates
  • Timestamp Checks: Enforce NotBefore/NotOnOrAfter
  • Signature Verification: Require signed assertions
  • HTTPS Only: Never use SSO over HTTP
  • Domain Verification: Verify email domains before JIT provisioning
  • Audit Logging: Monitor SSO authentication events

Build docs developers (and LLMs) love