Single Sign-On
Single Sign-On (SSO) allows a user to authenticate once with a central identity provider and then access multiple applications without logging in again. Log into your company’s identity provider and you’re automatically signed into Slack, GitHub, Salesforce, and every other integrated tool — with a single set of credentials, enforced by a single system.
What is SSO
Without SSO, each application manages its own user accounts. Users have separate passwords for each tool; IT has no central place to revoke access when an employee leaves; security policies (MFA, password complexity) are enforced inconsistently across apps. SSO solves all three:
- One credential: Users authenticate once. Applications trust the identity provider’s assertion rather than maintaining their own credential store.
- Central access control: Deprovisioning a user in the identity provider immediately revokes their access to all connected applications.
- Consistent policy: MFA, session duration, and password policies are enforced at the identity provider, not per-app.
How SSO Works
SSO relies on a trusted third party — the Identity Provider (IdP) — to vouch for the user’s identity. Applications (called Service Providers in SAML, or Relying Parties in OIDC) trust the IdP’s assertions.
The general flow:
- User tries to access an application (Service Provider).
- The application checks if the user has an active session. If not, it redirects to the Identity Provider.
- The IdP checks if the user has an active SSO session. If not, it presents a login page.
- The user logs in at the IdP (with password, MFA, etc.).
- The IdP establishes an SSO session (typically a cookie on the IdP’s domain).
- The IdP sends an assertion (SAML) or issues tokens (OIDC) back to the application confirming the user’s identity.
- The application creates a local session and the user is logged in.
For subsequent applications: the user is redirected to the IdP, but the IdP already has an active session — it skips the login step and immediately issues the assertion. The user never sees a second login prompt.
SAML 2.0
Security Assertion Markup Language (SAML) 2.0 is the dominant enterprise SSO protocol. It uses XML-based assertions signed by the IdP to prove the user’s identity to Service Providers.
SAML SP-initiated flow:
- User accesses the SP (e.g., Salesforce).
- SP generates a SAML AuthnRequest and redirects the user to the IdP’s SSO URL with the request encoded in the URL (redirect binding) or as a POST.
- IdP authenticates the user and generates a SAML Assertion — an XML document containing the user’s identity attributes (email, name, groups), signed with the IdP’s private key.
- IdP POSTs the assertion to the SP’s Assertion Consumer Service (ACS) URL.
- SP validates the assertion signature using the IdP’s public certificate, checks conditions (audience, expiry, validity window), and creates a local session.
SAML assertions contain attributes — key-value pairs the IdP sends about the user. Common attributes: email, firstName, lastName, groups (for role mapping), department. SPs use these to provision users and assign roles without their own user database.
Popular SAML IdPs: Okta, Microsoft Entra ID (formerly Azure AD), Google Workspace, OneLogin, Ping Identity, ADFS (Active Directory Federation Services).
OIDC-Based SSO
Modern applications increasingly use OpenID Connect for SSO. The flow is the OAuth 2.0 authorization code flow (described in the OAuth guide), extended with the openid scope to get an ID token.
The IdP maintains an SSO session (cookie). When the user visits a second application:
- The application redirects to the IdP’s authorization endpoint.
- The IdP detects the active SSO session and immediately redirects back with an authorization code — no login prompt.
- The application exchanges the code for tokens and creates a local session.
The prompt=none parameter tells the IdP to fail silently (return an error) rather than show a login page if the user has no SSO session — useful for silent token refresh without user interaction.
SAML vs OIDC
| SAML 2.0 | OIDC | |
|---|---|---|
| Protocol | XML over HTTP redirects / POST | JSON over HTTPS (OAuth 2.0) |
| Token format | XML assertion | JWT |
| Ecosystem | Enterprise (Salesforce, ServiceNow, Workday) | Modern web/mobile apps, developer tools |
| Implementation | Complex XML parsing, canonicalization, signature | Simpler — JWT libraries widely available |
| Mobile support | Poor (redirect-heavy, XML parsing) | Excellent (JSON, native SDK support) |
| API authorization | Not designed for APIs | Built in (OAuth 2.0 access tokens) |
| Use when | Enterprise SaaS integrations, legacy systems | New applications, APIs, mobile apps |
Session Management
SSO creates two layers of sessions: the IdP session (the SSO session) and local sessions in each application. Managing them correctly determines how logout and session expiry behave.
Single Logout (SLO): When the user logs out, ideally all sessions are terminated — both the IdP session and every SP’s local session. In SAML, the SP sends a LogoutRequest to the IdP, which propagates LogoutRequests to all other SPs that have active sessions for that user. In OIDC, SLO is handled via front-channel (browser redirects) or back-channel (server-to-server HTTP calls to each SP’s logout endpoint).
In practice, SLO is hard to implement correctly — some SPs may be unreachable, some don’t implement SLO, and browser redirects are fragile. Many deployments accept “best effort” SLO: the IdP session is terminated, and local SP sessions expire after their configured TTL (typically 8–24 hours for enterprise apps).
If the IdP is down, users cannot log in to any SSO-protected application. Deploy the IdP with high availability (multiple instances, cross-AZ). Consider allowing cached sessions to continue working during IdP outages — applications that validate tokens locally can remain functional even if they can’t issue new ones.
Design Considerations
- Keep local session TTL short. Local sessions in each application should expire after a reasonable period (4–8 hours for internal tools, shorter for sensitive systems). This limits the window where a user’s access persists after their IdP account is disabled.
- Use SCIM for user provisioning. SSO handles authentication; provisioning (creating/updating/deactivating user accounts in each SP) is a separate concern. System for Cross-domain Identity Management (SCIM) automates this — the IdP pushes user changes to SPs automatically, so deprovisioning happens in seconds, not the next login.
- Map groups to roles carefully. IdPs send group membership in assertions; SPs map groups to application roles. A user in the “Engineering” group might get “developer” role in GitHub but “viewer” role in a billing system. Test mapping thoroughly — a misconfiguration can grant excessive permissions silently.
- Handle the new user flow. The first time a user accesses an SP via SSO, the SP often needs to create a local account (just-in-time provisioning). Decide what happens if the assertion doesn’t include required attributes (email missing, group mapping fails). Fail closed: deny access and surface a clear error, rather than creating a partially-provisioned account.
- Don’t trust the email claim as a unique identifier. Email addresses change (marriage, company rename). Use the IdP’s stable, opaque subject identifier (
subclaim in OIDC,NameIDin SAML) as the primary key for user accounts. Store the email separately for display and communication.