SSO Service: Low-Level Design
A Single Sign-On (SSO) service lets users authenticate once and access multiple service providers (SPs) without re-entering credentials. Supporting both SAML 2.0 (dominant in enterprise) and OIDC (dominant in cloud-native) from a single platform is the modern baseline. The core challenges are secure session cookie management, handling SP-initiated and IdP-initiated flows correctly, and maintaining a reliable session state at scale.
Requirements
Functional
- Support SAML 2.0 SP-initiated login, IdP-initiated login, and Single Logout (SLO)
- Support OIDC Authorization Code flow with PKCE for SP-initiated login
- Issue a centralized SSO session cookie on the IdP domain after successful authentication
- Allow silent re-authentication (no login prompt) when a valid SSO session exists
- Propagate logout to all SPs that established sessions in the current SSO context
- Support per-SP attribute release policies: define which user claims are sent to each SP
Non-Functional
- Authentication round-trip under 300 ms p95 for returning users with a valid session
- Support 500,000 concurrent SSO sessions
- High availability: no single point of failure; session state survives a single node loss
Data Model
- sso_sessions: session_id (UUID), user_id, created_at, last_active_at, expires_at, ip_address, user_agent, active (BOOL)
- sp_sessions: sp_session_id (UUID), sso_session_id, sp_entity_id (TEXT), name_id (TEXT), name_id_format (TEXT), session_index (TEXT), established_at
- saml_providers: entity_id (TEXT PRIMARY KEY), metadata_url (TEXT), acs_url (TEXT), slo_url (TEXT), signing_certificate (TEXT), attribute_mapping (JSONB), created_at
- oidc_clients: client_id (UUID), client_secret_hash (TEXT), redirect_uris (ARRAY), scopes (ARRAY), attribute_policy (JSONB)
- saml_request_cache: request_id (TEXT PRIMARY KEY), relay_state (TEXT), sp_entity_id, authn_request_xml (TEXT), created_at, expires_at
SSO session state is stored in Redis (with a configured TTL for the session lifetime, typically 8 hours) and checkpointed to Postgres for durability. The Redis copy is the hot path; Postgres is consulted only on cache miss.
Core Algorithms
SP-Initiated SAML Flow
The SP constructs a SAML AuthnRequest, signs it (if configured), and redirects the user to the IdP SSO URL via HTTP-Redirect binding (deflate + base64 + URL-encode). The IdP parses and validates the request, stores it in saml_request_cache keyed by the request ID, and checks for an existing SSO session cookie. On valid session: skip authentication, generate SAML Response, POST to the SP ACS URL via auto-submitted HTML form (HTTP-POST binding). On no session: present the login UI, authenticate, create the SSO session, then issue the response.
Centralized Session Cookie
After successful authentication the IdP sets an HttpOnly, Secure, SameSite=None cookie on the IdP domain (e.g. sso.company.com). The cookie value is a signed, opaque session token (HMAC-SHA256 of session_id + random nonce + timestamp). On each SSO request, the IdP validates the cookie signature, looks up the session in Redis, and checks expiry and active status. The cookie is rotated (new nonce) on each successful use to limit the replay window.
Single Logout Propagation
On logout, the IdP queries sp_sessions for all SPs in the current sso_session. For each SP with a configured slo_url, it sends a SAML LogoutRequest via HTTP-Redirect (front-channel) or HTTP-POST (back-channel). The IdP waits for LogoutResponse (with a 3-second timeout per SP) before invalidating the SSO session cookie. SPs that do not respond within the timeout are logged but do not block the user-facing logout completion.
Scalability and Architecture
The SSO service is stateless at the application layer; all session state lives in Redis Cluster (6 shards, 3 replicas each). A consistent hashing ring maps session_id to a Redis shard. Postgres is the source of truth for SP/client registration and audit logs. The saml_request_cache uses Redis with a 10-minute TTL, sized for the maximum concurrent in-flight AuthnRequests.
- SAML XML parsing is CPU-intensive: dedicate a thread pool and cache parsed SP metadata (loaded from metadata_url daily or on-demand)
- SAML responses are signed using RS256; private keys are stored in HSM or KMS with in-process caching of the signing context
- Rate limiting: 10 authentication attempts per minute per IP using a Redis sliding window counter
- Health checks: each node exposes a liveness probe; a failed node is removed from the load balancer within 10 seconds without dropping active sessions (they remain in Redis)
API Design
SAML Endpoints
GET /saml/sso?SAMLRequest=X&RelayState=X&SigAlg=X&Signature=X— SP-initiated SSO entry point (HTTP-Redirect binding)POST /saml/sso— SP-initiated SSO via HTTP-POST bindingPOST /saml/acs— assertion consumer service (IdP-initiated: IdP POSTs response directly)GET /saml/slo?SAMLRequest=X— single logout entry pointGET /saml/metadata— IdP SAML metadata XML for SP self-registration
OIDC Endpoints
GET /oidc/authorize— OIDC authorization endpoint with SSO session awarenessPOST /oidc/token— token endpoint (code exchange, refresh)GET /.well-known/openid-configuration— discovery document
Admin API
POST /admin/saml/providers— register a new SAML SP from metadata URLPUT /admin/saml/providers/{entity_id}/attribute-policy— configure attribute release rulesGET /admin/sessions/{session_id}— inspect an SSO session and its sp_sessions
Interview Tips
Be ready to contrast SP-initiated and IdP-initiated flows: IdP-initiated skips the AuthnRequest entirely (no request_id to validate), which opens a replay vector; mitigate by enforcing a short assertion validity window (NotOnOrAfter within 5 minutes of issuance) and storing assertion IDs to prevent reuse. Discuss the SameSite=None requirement for the SSO cookie: cross-site redirects from SP to IdP require the cookie to be sent cross-origin, which mandates SameSite=None plus Secure. Also explain how attribute mapping works: the IdP translates internal user attributes (role, department) to SP-specific claim names defined in the attribute_mapping JSONB field per SP registration.
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “What are the key differences between SAML 2.0 and OIDC for SSO?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “SAML 2.0 uses XML assertions exchanged via browser redirects and is dominant in enterprise/B2B contexts. OIDC uses JSON/JWT tokens over OAuth 2.0 flows and is preferred for modern web and mobile apps. SAML has richer attribute statement support; OIDC has simpler client libraries. SAML SP metadata and IdP metadata are exchanged upfront; OIDC uses discovery documents. Both support SSO and SLO but with different protocol mechanics.”
}
},
{
“@type”: “Question”,
“name”: “What is the difference between SP-initiated and IdP-initiated SSO flows?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “In SP-initiated flow, the user starts at the service provider, which redirects to the IdP with an AuthnRequest. The IdP authenticates the user and posts an assertion back to the SP's ACS endpoint. In IdP-initiated flow, the user starts at the IdP portal, selects an app, and the IdP posts an unsolicited assertion directly to the SP. IdP-initiated flow skips the AuthnRequest and is considered less secure because it's harder for the SP to prevent replay attacks.”
}
},
{
“@type”: “Question”,
“name”: “How does a centralized session cookie work in an SSO service?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “The SSO service issues a session cookie on its own domain after the user authenticates. The cookie is HttpOnly, Secure, and SameSite=None (for cross-site flows). Its value maps to a server-side session record storing the user's authenticated identity and session expiry. Every SP that needs to verify the user redirects to the SSO service, which checks the cookie and issues a short-lived SP-specific token without re-prompting for credentials.”
}
},
{
“@type”: “Question”,
“name”: “How is Single Logout (SLO) propagated across all service providers?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “When a user logs out, the SSO service invalidates the central session, then iterates over all SPs that participated in that session. For SAML, it sends a LogoutRequest to each SP's SLO endpoint (via front-channel redirect or back-channel SOAP). For OIDC, it uses back-channel logout tokens (RFC 8935) or front-channel iframes. SPs invalidate their local sessions on receipt. SPs that fail to acknowledge are logged; the user's central session is still terminated.”
}
}
]
}
See also: Scale AI Interview Guide 2026: Data Infrastructure, RLHF Pipelines, and ML Engineering
See also: Atlassian Interview Guide