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
SSO Initiation
User enters email or clicks SSO login button
Organization Lookup
SSO service identifies organization by domain or identifier
SAML Request
SSO service generates SAML AuthnRequest and redirects to IdP
IdP Authentication
User authenticates with organization’s identity provider
SAML Response
IdP sends SAML assertion back to SSO service
Validation
SSO service validates SAML signature and assertions
Token Exchange
SSO service redirects to Identity service with authorization code
Access Token
Identity service issues OAuth tokens for client application
OpenID Connect Flow
SSO Initiation
User initiates login via organization SSO
OIDC Authorization
SSO service redirects to OIDC provider with authorization request
User Authentication
User authenticates with OIDC provider
Authorization Code
OIDC provider returns authorization code
Token Exchange
SSO service exchanges code for ID token and access token
User Info
SSO service retrieves user information from OIDC UserInfo endpoint
Bitwarden Login
SSO service creates/updates user and redirects to Identity service
Configuration
From bitwarden_license/src/Sso/Startup.cs:26:
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
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:
Signature verification
Timestamp validation (NotBefore/NotOnOrAfter)
Audience restriction
Attribute extraction
User provisioning/update
Required SAML Attributes
Attribute Description Required email or emailaddressUser email address Yes name or displaynameFull name No firstname or givennameFirst name No lastname or surnameLast name No
OpenID Connect Implementation
Configuration Discovery
The SSO service discovers OIDC provider configuration via:
{authority}/.well-known/openid-configuration
Required OIDC Claims
Claim Description Required emailUser email address Yes nameFull name No given_nameFirst name No family_nameLast name No subSubject identifier Yes
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:
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
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:
Add Domain
Navigate to Organization Settings → Verified Domains
Generate DNS Record
System generates TXT record for verification
Add DNS Record
Add TXT record to domain’s DNS configuration
Verify Domain
Click “Verify” to validate DNS record
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:
User authenticates via SSO
SSO service checks if user exists
If new user, create invitation
Auto-confirm invitation
Add to default group (if configured)
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.
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
PingFederate Ping Identity solutions
Auth0 Auth0 OIDC integration
Troubleshooting
SAML Common Issues
Issue Solution Invalid signature Verify IdP certificate in configuration Timestamp validation failed Check server time synchronization (NTP) Missing email attribute Configure email claim in IdP Audience restriction Verify Entity ID matches configuration
OIDC Common Issues
Issue Solution Invalid client Verify client ID in configuration Redirect URI mismatch Check redirect URI matches registration Invalid scope Ensure openid email scopes are granted Token validation failed Verify 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