{
    "componentChunkName": "component---src-pages-blog-markdown-remark-fields-slug-js",
    "path": "/blog/saml-vs-sso",
    "result": {"data":{"markdownRemark":{"html":"<p>A common moment in B2B SaaS engineering: an enterprise prospect declares that they require “SAML SSO” before signing the contract. The documentation that follows is dense with XML schemas, OASIS specifications, and a stack of acronyms (SP, IdP, ACS, AuthnRequest, SLO). The question of what to actually build and whether SAML is even the right call, instead of using an existing OIDC integration, gets lost in the terminology.</p>\n<p>This article is written for backend and full-stack engineers at B2B SaaS companies who need to add enterprise SSO to unblock a deal. The goal is to make the underlying protocols legible, without reverse-engineering them from vendor docs.</p>\n<p>The single most important sentence to internalize:</p>\n<p><strong>SAML is not the same thing as SSO. SSO is the goal. SAML is one protocol that gets you there.</strong></p>\n<p>Everything else in this article follows from that distinction.</p>\n<h2 id=\"what-is-sso\" style=\"position:relative;\"><a href=\"#what-is-sso\" aria-label=\"what is sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is SSO?</h2>\n<p><a href=\"https://supertokens.com/features/single-sign-on\" target=\"_blank\" rel=\"nofollow\">SSO (Single Sign-On)</a> is an authentication strategy that lets a user log in once with one identity provider and access multiple applications without re-authenticating. It is a user-experience pattern, not a protocol. SAML, OIDC, OAuth, and Kerberos are all things that can be used to <a href=\"https://supertokens.com/blog/sso-implementation\" target=\"_blank\" rel=\"nofollow\">implement SSO</a>. They are not synonyms for it.</p>\n<p>The mechanics are conceptually simple:</p>\n<ol>\n<li>An <strong>Identity Provider (IdP)</strong> authenticates the user once.</li>\n<li>The IdP issues a signed token or assertion proving the user’s identity.</li>\n<li><strong>Service Provider (SP)</strong>, the actual application the user wants to use, trusts that signature and grants access without asking for credentials again.</li>\n</ol>\n<p>Consumer SSO is familiar from daily life. Logging into Google grants access to Gmail, Drive, Calendar, and YouTube under a single session. The B2B version is structurally identical, but the IdP is a corporate identity platform. A marketing analyst at a Fortune 500 logs into Okta once in the morning, and from that single session can launch Salesforce, Slack, Workday, Zoom, and the SaaS product being purchased, without typing another password.</p>\n<p>That second example is the one that matters for revenue. When an enterprise IT team states an SSO requirement, the meaning is specific: employees should be able to access the product through the corporate identity platform, with offboarding, access reviews, and audit logs flowing through the same system that handles every other application. That is the requirement. SAML is one way to fulfill it. OIDC is another.</p>\n<p>The benefits stack quickly: one set of credentials to rotate, MFA enforced centrally, instant deprovisioning when an employee leaves, and a single audit log to satisfy compliance. These benefits do not come from SAML specifically — they come from SSO as an architecture. SAML is just the message format that some enterprises happen to insist on.</p>\n<h2 id=\"what-is-saml\" style=\"position:relative;\"><a href=\"#what-is-saml\" aria-label=\"what is saml permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is SAML?</h2>\n<p><a href=\"https://supertokens.com/blog/demystifying-saml\" target=\"_blank\" rel=\"nofollow\">Security Assertion Markup Language (SAML)</a> is an open XML-based standard for exchanging authentication and authorization data between an Identity Provider and a Service Provider. SAML 2.0, <a href=\"https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf\" target=\"_blank\" rel=\"nofollow\">ratified as an OASIS Standard in March 2005</a>, is the version meant whenever SAML is discussed today. SAML 1.1 still exists in legacy environments, but new integrations should never be built against it.</p>\n<p>SAML has three core building blocks worth understanding before any code gets written:</p>\n<ul>\n<li><strong>Assertions</strong> are the actual statements about a user, packaged as XML and signed by the IdP. A SAML assertion typically carries three kinds of statements: an authentication statement (proving the user authenticated, when, and how), an attribute statement (email, name, group memberships, employee ID, anything else the IdP wants to share), and optionally an authorization decision statement. The assertion is the payload an application actually consumes.</li>\n<li><strong>Protocols</strong> are the request-response patterns used to ask for and deliver assertions. The most important is the Authentication Request Protocol: the SP sends an <code class=\"language-text\">&lt;AuthnRequest></code> to the IdP, the IdP responds with a signed <code class=\"language-text\">&lt;Response></code> containing an assertion. Other protocols defined in SAML 2.0 include Single Logout, Artifact Resolution, and Name Identifier Management.</li>\n<li><strong>Bindings</strong> define how SAML messages travel over the wire. The two that appear most often are HTTP-Redirect (used for the initial <code class=\"language-text\">AuthnRequest</code> from SP to IdP) and HTTP-POST (used to deliver the signed <code class=\"language-text\">Response</code> back to the SP). A SOAP binding exists for back-channel communication, and an Artifact binding exists for higher-security flows.</li>\n</ul>\n<p>Trust between the SP and IdP is established through metadata exchange: an XML file containing endpoint URLs, supported bindings, and the X.509 public certificate that the SP will use to verify the IdP’s signatures. These metadata files (or URLs that serve them) are exchanged during the initial configuration of every SAML connection.</p>\n<p>The major SAML IdPs encountered in enterprise integrations are Microsoft Entra ID (formerly Azure AD), Okta, Google Workspace, Ping Identity, OneLogin, and Active Directory Federation Services (ADFS). When an enterprise customer states a SAML SSO requirement, one of these is almost certainly the IdP in use.</p>\n<h2 id=\"saml-vs-sso-the-core-distinction\" style=\"position:relative;\"><a href=\"#saml-vs-sso-the-core-distinction\" aria-label=\"saml vs sso the core distinction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>SAML vs. SSO: The Core Distinction</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/5b9c0abac65edc0ef4ea07243d94519e/a878e/SAML-vs-SSO.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.65822784810127%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACGUlEQVQoz5WRy27TQBSG/QaVWFUBp60KBdpEcdTuKlGpu4qHqYTaNFdYg1hVvFloSCrbsRM7TuMmvmTmzNUOsk0REmLBp1+jo5n5z/wzo5AnKKXFyLlgjEkppJRCCP5vlNHo3jRNwzB+ZAx1XTfNsa4blmXZ9kTXjSiKGGOUMsY4pawQY5wxroRhFIZhGISrnCAIi5miWK2COI4RwoRQxniabjabTZpuWI5SBMhacVFICE6ZJFTEa2BcUiaydc4BwDDMPOkYgGRmmiOlpFkaSggFIGssbDcc3Duej1cRDWJMWNq/Gx0eVk9P32na8WQySZJEye9DTcNgnEeIhnGmaE2BcEIFBoaBIgRCpneD4c7O/u7uq4ODt5ZlF+Ysz3A45FKuESCEIWf56Huet1wuCSEIISnl4G5wpNVfvzmqVmq2PZEyUQghACTfTzEGhDHGABhQBs57ZeYkSfr97+r+yxfqTrm8Z47HUkplvUa/hdCvIghCz5vPZt5s5kVRHEUxBrAsu9FqN25arVbX8+bZV6XF8/8naZoCgPL5y9dWr9ftfep0Prbb3U6n1+n02u1uo9HM1XoqmtfXzaurm0ajeXn54fb2GwBRzs7Ojyo1TTuu10+q1Vq9fqJpx5VKTVX3VHWvVCpvbz//U6WSurX17OLifXay582nU8dx3OnUdZyZ47iO47ruzPcfff9xsfD/1sPDYrlcIYR/An8DeYxFoNzBAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"SAML-vs-SSO\"\n        title=\"SAML-vs-SSO\"\n        src=\"/static/5b9c0abac65edc0ef4ea07243d94519e/f058b/SAML-vs-SSO.png\"\n        srcset=\"/static/5b9c0abac65edc0ef4ea07243d94519e/c26ae/SAML-vs-SSO.png 158w,\n/static/5b9c0abac65edc0ef4ea07243d94519e/6bdcf/SAML-vs-SSO.png 315w,\n/static/5b9c0abac65edc0ef4ea07243d94519e/f058b/SAML-vs-SSO.png 630w,\n/static/5b9c0abac65edc0ef4ea07243d94519e/40601/SAML-vs-SSO.png 945w,\n/static/5b9c0abac65edc0ef4ea07243d94519e/78612/SAML-vs-SSO.png 1260w,\n/static/5b9c0abac65edc0ef4ea07243d94519e/a878e/SAML-vs-SSO.png 2048w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>The cleanest way to think about it: SSO is the destination. SAML is one of the routes.</p>\n<p>A comparison table makes the asymmetry explicit:</p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th><strong>SSO</strong></th>\n<th><strong>SAML</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>What it is</strong></td>\n<td>An authentication strategy or goal.</td>\n<td>An open protocol / message format.</td>\n</tr>\n<tr>\n<td><strong>What it defines</strong></td>\n<td>The user experience of “one login, many apps.”</td>\n<td>The structure and exchange of identity messages.</td>\n</tr>\n<tr>\n<td><strong>Existence</strong></td>\n<td>Can be implemented without SAML, by using OIDC, Kerberos, or proprietary protocols.</td>\n<td>Only makes sense in the context of SSO.</td>\n</tr>\n<tr>\n<td><strong>Governance</strong></td>\n<td>Determined by architecture and product choices.</td>\n<td>Governed by the OASIS open standard.</td>\n</tr>\n<tr>\n<td><strong>Typical context</strong></td>\n<td>Any multi-application environment.</td>\n<td>Enterprise B2B, federated identity, legacy systems.</td>\n</tr>\n</tbody>\n</table>\n<p>The takeaway: <strong>not all SSO is SAML, but all SAML is SSO.</strong> A competitor’s homepage that says “this product supports SSO” reveals nothing about which protocol is implemented. A claim of “SAML SSO” support is specific. It means the product speaks the XML-based OASIS standard that enterprise IT teams expect.</p>\n<p>So the next question is the one that actually matters: how does SAML implement SSO in practice?</p>\n<h2 id=\"how-saml-sso-works-step-by-step\" style=\"position:relative;\"><a href=\"#how-saml-sso-works-step-by-step\" aria-label=\"how saml sso works step by step permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How SAML SSO Works, Step By Step</h2>\n<p>SAML SSO has two flows. Both will eventually need to be supported. Understanding one well first is the path to handling both.</p>\n<h3 id=\"sp-initiated-flow-the-common-case\" style=\"position:relative;\"><a href=\"#sp-initiated-flow-the-common-case\" aria-label=\"sp initiated flow the common case permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>SP-Initiated Flow (The Common Case)</strong></h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/762231c708222fa34583d4428b9a288c/60708/SP-Initiated-SAML-Flow.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.39240506329114%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB+UlEQVQoz3WSh46jMBRF8/+ftkXaHaXMpEBoKcwQmgu2gbPCTDKzDenIBvSur9+7i6IoWS53rDd7Ns8BP59eWK72vGxDdruAzfOO1fqF9Wb7wFqLc86vn3HOspBSkiQp+31AmmYcDiFhGBHHKVGUEMUpQRD5/fX6SnY6+8IZR9/P3A9YjOPI0/LZFxjT8fGMnq8rSZpdSZOEorj5P1OxMh3f4y3HKCaKYsqywvWOhXXWCynd0QpN/tYSxhVhVHK61DStpqwVSilMp3HW0DvrsdbQdZ3HGDNf+d4PYyxCdpSVoKxabmVLcWv8t1YYTFsiswARbhDxluawQp5CbJP7Q5yb++gd2veXvrcMQ/8bc49mN0IIWiEQQlK3NWmecbwkhJeYvHrF2G4WvKv/j8n9dItxGGAcfXuN1SR5wiEL2GcB4fmI6uTfgu7d8X2Sk7u+N8hO0qiGvC4omorz7com3XM4R0TXlCTPUJ36h8NPgrqz1K3h9aaJriXb44ldkhCfM6Jzxim/ILXEumlQztctHiLWPAJ7p1UD673iy4+ab08N21Aj9cjQ9wz94Nc/zXiHQ+8Q0lCUmjirORwnSnZhRXJueSs1Qlmkthj7EWr7582mKU/5kUIghaRtW+q69lRVRV1VNHWNkhKtFVpNeZQ+k9PEp/zNguYh/AuDo5c3p93kJAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"SP-Initiated-SAML-Flow\"\n        title=\"SP-Initiated-SAML-Flow\"\n        src=\"/static/762231c708222fa34583d4428b9a288c/f058b/SP-Initiated-SAML-Flow.png\"\n        srcset=\"/static/762231c708222fa34583d4428b9a288c/c26ae/SP-Initiated-SAML-Flow.png 158w,\n/static/762231c708222fa34583d4428b9a288c/6bdcf/SP-Initiated-SAML-Flow.png 315w,\n/static/762231c708222fa34583d4428b9a288c/f058b/SP-Initiated-SAML-Flow.png 630w,\n/static/762231c708222fa34583d4428b9a288c/40601/SP-Initiated-SAML-Flow.png 945w,\n/static/762231c708222fa34583d4428b9a288c/78612/SP-Initiated-SAML-Flow.png 1260w,\n/static/762231c708222fa34583d4428b9a288c/60708/SP-Initiated-SAML-Flow.png 2872w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>This is the flow that runs when a user clicks “Log in” on the application:</p>\n<ol>\n<li><strong>The user visits the application</strong> (the Service Provider) and hits a protected route.</li>\n<li><strong>The application detects no active session</strong> and redirects the browser to the IdP, attaching a SAML <code class=\"language-text\">&lt;AuthnRequest></code> (typically via HTTP-Redirect binding, with the request encoded in the URL).</li>\n<li><strong>The IdP authenticates the user</strong> through whatever mechanism it controls: password, MFA, hardware key, certificate, or any combination.</li>\n<li><strong>The IdP builds a signed SAML assertion</strong> containing the user’s identity and attributes, wrapped in a <code class=\"language-text\">&lt;Response></code> element.</li>\n<li><strong>The IdP POSTs the response</strong> to the application’s <strong>Assertion Consumer Service (ACS) URL</strong>, a specific endpoint on the backend whose only job is to receive SAML responses. This step uses the HTTP-POST binding; the browser auto-submits a form containing the base64-encoded SAML response.</li>\n<li><strong>The application validates the response.</strong> It checks the XML signature against the IdP’s public certificate (from the metadata configured during setup), validates the <code class=\"language-text\">NotBefore</code> and <code class=\"language-text\">NotOnOrAfter</code> timestamps, confirms the <code class=\"language-text\">Audience</code> matches the application’s entity ID, and verfies the <code class=\"language-text\">InResponseTo</code> attribute matches the original <code class=\"language-text\">AuthnRequest</code>.</li>\n<li><strong>The application creates a session</strong> and grants the user access.</li>\n</ol>\n<h3 id=\"idp-initiated-flow\" style=\"position:relative;\"><a href=\"#idp-initiated-flow\" aria-label=\"idp initiated flow permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>IdP-Initiated Flow</strong></h3>\n<p>The second flow starts at the IdP instead of the application. The user logs into the Okta dashboard, sees a tile for the application, clicks it, and the IdP pushes a SAML response to the ACS URL without any prior <code class=\"language-text\">AuthnRequest</code>.</p>\n<p>This is the flow that powers the “app launcher” tiles enterprise users see inside Okta or Entra ID portals. It is also the flow that quietly creates the most security headaches, because there is no <code class=\"language-text\">AuthnRequest</code> to bind the response to. The application receives an unsolicited assertion and has to decide whether to trust it. <strong>This is a real attack surface.</strong> Without an <code class=\"language-text\">InResponseTo</code> value to validate against, the only defenses are signature, audience, and replay protection. The mistakes section below covers this in more detail.</p>\n<h3 id=\"single-logout\" style=\"position:relative;\"><a href=\"#single-logout\" aria-label=\"single logout permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Single Logout</strong></h3>\n<p>A question every enterprise customer will eventually ask: <em>“When a user logs out of Okta, do they get logged out of the application too?”</em></p>\n<p>Single Logout (SLO) is the SAML protocol designed to answer “yes.” When the user signs out at the IdP, the IdP sends a <code class=\"language-text\">&lt;LogoutRequest></code> to every SP that has an active session, and each SP terminates its local session. In theory, the user is logged out everywhere simultaneously.</p>\n<p>In practice, SLO is one of the messiest parts of SAML. Implementations vary widely between IdPs. Some send LogoutRequests synchronously and wait for responses, others fire and forget. Browser session state, cookies, and back-channel versus front-channel logout each behave differently. Most B2B SaaS teams ship SP-initiated SSO first and defer SLO until an enterprise customer files a security review finding about it. That is a defensible sequence, but the conversation is coming. Not implementing SLO means a user who logs out of an IdP can still walk back into the application on the same browser if the session cookie is alive.</p>\n<h2 id=\"saml-vs-oidc-vs-oauth-the-full-protocol-picture\" style=\"position:relative;\"><a href=\"#saml-vs-oidc-vs-oauth-the-full-protocol-picture\" aria-label=\"saml vs oidc vs oauth the full protocol picture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>SAML vs. OIDC vs. OAuth: The Full Protocol Picture</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/eab21f59ceae198d81ce7fb203c9d9c2/a878e/SAML-vs-OIDC-vs-OAuth.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.65822784810127%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB/UlEQVQoz22R2W7bMBBF9bspUFi2ZFty+lS0QV+C/lpemlqWLCdd7Do2V4nbcFFLOUgX9OBiOCTmcoZgokZkRGmtYMRaa4yxfwD/I1mv103drNdV2+6qalM320jbxrxudrvdZrOp61oIYf4FEnRGlFLOGWeUM8oYpYRQQhgbV9pj0iPc9RKMHTT4ZxlnjEn2R0I66JQnvX3CGneWS8+lZzJo3Xm5c/LByweFq/70SfMa+h30WxBfo/lI7B7BkdoDtoez/nbSP7A9UncgoePEoHuFPuvzZ3W6V+d7gyugNZAN8EetdbL/vm+ahhIyDIP3rm1bjPEwAmCb+OovHe+Hv/E+RLPWWghprR2GwVrLOe97EUII41aI3hjjn3HDEC7y3imlE0oZQkhKeTF3XXfJx86AMEGEEMIwJrzr4pXPnb1SKhFC9BEBAM45SmOdUmr8XeeUckI4KYMxXmuvdQAIAA5ASpUghA77fS9655zSCiOMMWaMAYDRmm23p7s7UlWsbbvHR3N8sgjZ8xk4l0ol4WWUyzyjfhPiiFHOxvhyHIIQMnn77n2a5XlRzPL5bJZPR2XZfDrNZzFZZHnULF+k02wymaZp9urq9e3tRyllcnPzYb4oytWborwuy+uyuF4uyuWyLIpVsVwVxaosYpzPl5NJOpnM0jS7Gs2/Ov8EPtyvqI/WkGEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"SAML-vs-OIDC-vs-OAuth\"\n        title=\"SAML-vs-OIDC-vs-OAuth\"\n        src=\"/static/eab21f59ceae198d81ce7fb203c9d9c2/f058b/SAML-vs-OIDC-vs-OAuth.png\"\n        srcset=\"/static/eab21f59ceae198d81ce7fb203c9d9c2/c26ae/SAML-vs-OIDC-vs-OAuth.png 158w,\n/static/eab21f59ceae198d81ce7fb203c9d9c2/6bdcf/SAML-vs-OIDC-vs-OAuth.png 315w,\n/static/eab21f59ceae198d81ce7fb203c9d9c2/f058b/SAML-vs-OIDC-vs-OAuth.png 630w,\n/static/eab21f59ceae198d81ce7fb203c9d9c2/40601/SAML-vs-OIDC-vs-OAuth.png 945w,\n/static/eab21f59ceae198d81ce7fb203c9d9c2/78612/SAML-vs-OIDC-vs-OAuth.png 1260w,\n/static/eab21f59ceae198d81ce7fb203c9d9c2/a878e/SAML-vs-OIDC-vs-OAuth.png 2048w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>This is where most developers get confused, and where most competitor articles wave their hands. Precision matters here.</p>\n<p><strong>SAML, OIDC, and OAuth solve different problems.</strong> They are not three options on a menu where the prettiest one wins. Specifically:</p>\n<ul>\n<li><strong>OAuth 2.0</strong> is an <em>authorization</em> protocol. It answers “can this client take this action on this resource?” For example, “can this third-party app post tweets on behalf of this user?” OAuth alone is not authentication. The OAuth 2.0 specification itself is deliberately silent on user identity.</li>\n<li><strong>OpenID Connect (OIDC)</strong> is an authentication layer built on top of OAuth 2.0. The <a href=\"https://openid.net/specs/openid-connect-core-1_0.html\" target=\"_blank\" rel=\"nofollow\">OpenID Connect Core 1.0 specification</a> describes it as “a simple identity layer on top of the OAuth 2.0 protocol.” OIDC adds an <strong>ID Token</strong>, a JWT containing identity claims signed by the IdP, plus a userinfo endpoint and a discovery mechanism (<code class=\"language-text\">.well-known/openid-configuration</code>). When developers casually say “OAuth login,” the actual protocol is almost always OIDC.</li>\n<li><strong>SAML 2.0</strong> is an XML-based authentication protocol designed for browser-based <a href=\"https://supertokens.com/blog/enterprise-sso\" target=\"_blank\" rel=\"nofollow\">enterprise SSO</a>. It predates OIDC by nearly a decade.</li>\n</ul>\n<p>So the question of whether to use <a href=\"https://supertokens.com/blog/saml-vs-oauth\" target=\"_blank\" rel=\"nofollow\">OAuth or SAML</a> for login is malformed. OAuth alone should not be doing login. The real comparison is <a href=\"https://supertokens.com/blog/oidc-vs-saml\" target=\"_blank\" rel=\"nofollow\">OIDC vs. SAML</a>, and here is how the two stack up:</p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th><strong>SAML 2.0</strong></th>\n<th><strong>OIDC</strong></th>\n<th><strong>OAuth 2.0</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Purpose</strong></td>\n<td>Authentication (browser SSO)</td>\n<td>Authentication</td>\n<td>Authorization</td>\n</tr>\n<tr>\n<td><strong>Token format</strong></td>\n<td>Signed XML assertion</td>\n<td>JWT (ID Token)</td>\n<td>Access token (opaque or JWT)</td>\n</tr>\n<tr>\n<td><strong>Transport</strong></td>\n<td>HTTP-Redirect + HTTP-POST</td>\n<td>HTTP + REST/JSON</td>\n<td>HTTP + REST/JSON</td>\n</tr>\n<tr>\n<td><strong>Released</strong></td>\n<td>2005 (OASIS)</td>\n<td>2014 (OpenID Foundation)</td>\n<td>2012 (IETF RFC 6749)</td>\n</tr>\n<tr>\n<td><strong>Best for</strong></td>\n<td>Enterprise customers, legacy IdPs</td>\n<td>Modern web, mobile, SPAs, APIs</td>\n<td>Delegated API access</td>\n</tr>\n<tr>\n<td><strong>Mobile experience</strong></td>\n<td>Painful</td>\n<td>Native</td>\n<td>Native</td>\n</tr>\n<tr>\n<td><strong>Developer experience</strong></td>\n<td>Complex; XML, certificates, profiles</td>\n<td>Familiar; JSON, JWTs, discovery URLs</td>\n<td>Familiar</td>\n</tr>\n<tr>\n<td><strong>Discovery</strong></td>\n<td>Static metadata XML exchange</td>\n<td>Dynamic .well-known endpoint</td>\n<td>N/A</td>\n</tr>\n</tbody>\n</table>\n<p>There are two practical observations the table does not capture.</p>\n<p>First: <strong>SAML and OIDC are not competitors.</strong> Most B2B SaaS products at scale support both. New consumer-facing apps default to OIDC because mobile, SPAs, and API-first architectures work better with JSON and JWTs than with browser-bound XML POSTs. The moment a customer’s procurement team starts asking about identity requirements, the answer involves SAML, because that is what their existing IT stack speaks. The realistic question is rarely “OIDC or SAML?” The question is “OIDC first, then SAML when the first enterprise deal closes.”</p>\n<p>Second: <strong>OAuth alone is not a login system.</strong> This point cannot be repeated often enough. If an “OAuth login” is actually doing authentication, it is doing so via OIDC under the hood (by consuming the ID token), or it is doing so incorrectly (by using an access token to identify the user, which has the wrong audience and no defined identity claims). The <a href=\"https://auth0.com/docs/authenticate/protocols/openid-connect-protocol\" target=\"_blank\" rel=\"nofollow\">Auth0 protocol documentation</a> puts it cleanly: OAuth 2.0 is about resource access, OIDC is about user authentication.</p>\n<h2 id=\"when-to-use-saml-vs-oidc-a-decision-framework\" style=\"position:relative;\"><a href=\"#when-to-use-saml-vs-oidc-a-decision-framework\" aria-label=\"when to use saml vs oidc a decision framework permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When To Use SAML vs. OIDC: A Decision Framework</h2>\n<p>Most articles dodge this section. Here is the opinionated version.</p>\n<p><strong>Use SAML when:</strong></p>\n<ul>\n<li>An enterprise customer’s IT team explicitly requires it. Okta, Entra ID, Ping, and ADFS all support both protocols, but procurement checklists frequently still mandate SAML by name.</li>\n<li>Integration with legacy on-premises enterprise systems is required (older HR platforms, ERPs, SAP, Oracle products) and those systems only speak SAML.</li>\n<li>The customer needs attribute-based access control driven by SAML attribute assertions (group memberships, department codes, employee classifications).</li>\n<li>The compliance environment (FedRAMP, certain HIPAA configurations, defense-adjacent work) expects federated identity with auditable XML assertions.</li>\n</ul>\n<p><strong>Use OIDC when:</strong></p>\n<ul>\n<li>Building greenfield consumer or SMB-facing features where the customer does not care which protocol is used.</li>\n<li>Mobile apps, single-page apps, or API-first architectures are part of the picture. OIDC’s JSON/JWT model fits these cleanly; SAML does not.</li>\n<li>Developer experience matters and the team is small. OIDC’s discovery endpoint, dynamic client registration, and standard claims make integration dramatically faster than SAML’s metadata-and-certificate dance.</li>\n<li>Social login (Sign in with Google, GitHub, Microsoft consumer accounts) is sufficient.</li>\n</ul>\n<p><strong>Use both when:</strong></p>\n<ul>\n<li>The product serves SMB customers (via OIDC) and enterprise customers (via SAML). This is the most common real-world scenario. The choice is not “pick one.” The choice is “support OIDC by default, add SAML per enterprise tenant.”</li>\n<li>The deployment is multi-tenant and different tenants have different identity stacks. Per-tenant protocol configuration becomes mandatory.</li>\n</ul>\n<p>The shortest version of the decision: ship OIDC for the default flow, and treat SAML as a per-tenant extension that gets enabled when an enterprise customer requires it. Resist the temptation to make every customer use SAML, and resist the temptation to ask enterprise prospects to switch to OIDC because it would be easier on the engineering side.</p>\n<h2 id=\"common-saml-sso-implementation-mistakes\" style=\"position:relative;\"><a href=\"#common-saml-sso-implementation-mistakes\" aria-label=\"common saml sso implementation mistakes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Common SAML SSO Implementation Mistakes</h2>\n<p>These are the failure modes that burn engineering time on the first SAML integration. Most have known mitigations. Knowing they exist before they surface as customer-facing failures is the goal of this section.</p>\n<p><strong>1. Skipping or weakly validating the XML signature.</strong> The OWASP SAML Security Cheat Sheet is unambiguous: signature validation must happen on every response, with schema validation against a trusted local schema. The class of attack to know by name is <strong>XML Signature Wrapping (XSW)</strong>, <a href=\"https://cheatsheetseries.owasp.org/cheatsheets/SAML_Security_Cheat_Sheet.html\" target=\"_blank\" rel=\"nofollow\">documented in detail by OWASP</a>. An attacker takes a legitimately signed assertion, wraps it inside a manipulated XML document, and exploits the gap between what the signature covers and what the application reads. As recently as 2026, <a href=\"https://portswigger.net/research/the-fragile-lock\" target=\"_blank\" rel=\"nofollow\">PortSwigger research</a> has continued finding novel canonicalization bypasses in popular SAML libraries. Use battle-tested libraries. Do not write a custom XML signature validator. Pin library versions.</p>\n<p><strong>2. Clock skew between application servers and the IdP.</strong> SAML assertions carry <code class=\"language-text\">NotBefore</code> and <code class=\"language-text\">NotOnOrAfter</code> timestamps that are typically valid for only a few minutes. If server clocks drift more than that, every valid assertion gets rejected. The fix is operational, not architectural: run NTP, monitor drift, and allow a small clock-skew tolerance (60 to 120 seconds is typical) in validation logic.</p>\n<p><strong>3. Wrong ACS URL configuration.</strong> Roughly half of all “SAML doesn’t work” tickets are an ACS URL mismatch between what the IdP posts to and what the SP expects. Protocol, host, path, and query must match exactly. Applications behind a load balancer or proxy that rewrites paths face additional risk here. Log the destination of every incoming assertion during integration testing.</p>\n<p><strong>4. Missing or rigid attribute mappings.</strong> Enterprise IdPs send user attributes under wildly non-standard claim names. Okta might send <code class=\"language-text\">email</code>, Entra ID might send <code class=\"language-text\">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress</code>, and a custom Ping deployment might send <code class=\"language-text\">urn:oid:0.9.2342.19200300.100.1.3</code>. Build an attribute mapping layer that allows configuring which IdP attribute maps to which user field per tenant. Hardcoding a single attribute name will fail on the first non-Okta customer.</p>\n<p><strong>5. Trusting IdP-initiated flows without InResponseTo validation.</strong> By design, IdP-initiated SAML has no <code class=\"language-text\">AuthnRequest</code> to bind the response to, and this removes one of the protocol’s strongest replay defenses. When accepting IdP-initiated assertions, validation must be aggressive: signature, audience, recipient, NotOnOrAfter, and a one-time-use check to prevent replay. Many security teams disable IdP-initiated entirely as a result. Make that choice consciously, not by default.</p>\n<p><strong>6. Skipping Single Logout entirely.</strong> Skipping SLO is a defensible early-stage choice. Never planning to add it is not. Enterprise security questionnaires routinely require it, and “no SLO support” can become a deal-blocker after the technical integration is otherwise complete.</p>\n<p><strong>7. Hardcoding one SAML connection for the whole application.</strong> This is the architectural mistake that costs the most to fix later. In B2B SaaS, every enterprise customer brings their own IdP, metadata, certificate, and attribute schema. If the initial implementation supports one SAML connection globally, the second enterprise customer breaks the model. Design for multi-tenant SAML from day one: per-tenant metadata, per-tenant ACS URLs (or a single ACS URL with tenant resolution from the SAML response), per-tenant attribute mapping.</p>\n<h2 id=\"implementing-saml-sso-with-supertokens\" style=\"position:relative;\"><a href=\"#implementing-saml-sso-with-supertokens\" aria-label=\"implementing saml sso with supertokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implementing SAML SSO with SuperTokens</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/6fa4065ded87b3f572deabf473f6d7c5/a878e/Supertokens.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 47.46835443037975%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAACBklEQVQozyXQSW/TQABAYQsJGtvjscez2eM1aZq0NF3pvlBU6KGtQBTEcuFY/v8/eAg4PH33F+1MHW8WNQerTYa+R1uPsoHctOgww7ZzfL/EhHVcO8fWI77uqOoW62qs85Ra8/z8m/v7e6KNRjF4ReMMzjoKUyN0R2oGZLWBm+3Tj68ZF4fMlgeEekbtWipbo5Ulk5pUFLx8NWFtEhO1VhJsgTeGUluE8kyk50ViWd8+4fDijsXqlMPjG06Or9nf3icUhlY7gq0xuiFTAVFUpFITOSUwSqJUSZZr1kSJqads7Z1yfPmep2+/uHv4wuPjEz+//uD7x898OLtkZ5zT2QbvRgo7I9UDaRGIpEjJRIbIcmJRsCYUynXsHl6wvXfCau+Yq6t3vD2/5PbsnIfLKz5d33A032R0PbVfp6yWCLdgojqiOI5JkpRUSJJUkmQlE1GSZJqqaujbjlnXsTl0rIaOnTaw5RwLF5hWI5WfofwmstrCNAuiJInJ0hQlJUrmFLmiUOafNkvpm8DYBNb7liHU2DRmqkvmPtDYBmN6hJ5iuhUHR7dEMk2xuaDVkqbMCVrhyxL3N5UTjGLR1yz7mtGVdDqnN4pQanRhyHJPUgQKN9IOCyItU3qdsXQ5Gy5n7goGo2hMSesN02DYmXfszls2WsPgS7zKyYUgSQRx8n9TIkrWYskf7I3uCELTsPwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Supertokens\"\n        title=\"Supertokens\"\n        src=\"/static/6fa4065ded87b3f572deabf473f6d7c5/f058b/Supertokens.png\"\n        srcset=\"/static/6fa4065ded87b3f572deabf473f6d7c5/c26ae/Supertokens.png 158w,\n/static/6fa4065ded87b3f572deabf473f6d7c5/6bdcf/Supertokens.png 315w,\n/static/6fa4065ded87b3f572deabf473f6d7c5/f058b/Supertokens.png 630w,\n/static/6fa4065ded87b3f572deabf473f6d7c5/40601/Supertokens.png 945w,\n/static/6fa4065ded87b3f572deabf473f6d7c5/78612/Supertokens.png 1260w,\n/static/6fa4065ded87b3f572deabf473f6d7c5/a878e/Supertokens.png 2048w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>The accurate way to describe how SuperTokens handles SAML: <strong>SuperTokens is not a direct SAML client.</strong> It speaks OAuth and OIDC natively, and it delegates SAML to a separate component called <a href=\"https://github.com/boxyhq/jackson\" target=\"_blank\" rel=\"nofollow\">SAML Jackson</a> (built by BoxyHQ, now also distributed as Ory Polis). Jackson runs as its own microservice and converts SAML flows into an OAuth 2.0 flow that SuperTokens can consume through its standard ThirdParty provider configuration.</p>\n<p>This architecture has a real benefit: application code only ever deals with OAuth and OIDC, regardless of whether the underlying enterprise IdP is SAML, OIDC, or both. SAML Jackson absorbs the XML, the signature validation, and the IdP-specific quirks. SuperTokens absorbs the session, the user model, and the multi-tenancy.</p>\n<p>A typical setup runs SAML Jackson alongside SuperTokens, both self-hosted or both managed:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"68311981920228710000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied!\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# Run SAML Jackson alongside SuperTokens\ndocker run \\\n  -p 5225:5225 \\\n  -e JACKSON_API_KEYS=&quot;your-secret&quot; \\\n  -e DB_ENGINE=&quot;sql&quot; \\\n  -e DB_TYPE=&quot;postgres&quot; \\\n  -e DB_URL=&quot;postgres://postgres:postgres@localhost:5432/postgres&quot; \\\n  -d boxyhq/jackson`, `68311981920228710000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Run SAML Jackson alongside SuperTokens</span>\n<span class=\"token function\">docker</span> run <span class=\"token punctuation\">\\</span>\n  -p <span class=\"token number\">5225</span>:5225 <span class=\"token punctuation\">\\</span>\n  -e <span class=\"token assign-left variable\">JACKSON_API_KEYS</span><span class=\"token operator\">=</span><span class=\"token string\">\"your-secret\"</span> <span class=\"token punctuation\">\\</span>\n  -e <span class=\"token assign-left variable\">DB_ENGINE</span><span class=\"token operator\">=</span><span class=\"token string\">\"sql\"</span> <span class=\"token punctuation\">\\</span>\n  -e <span class=\"token assign-left variable\">DB_TYPE</span><span class=\"token operator\">=</span><span class=\"token string\">\"postgres\"</span> <span class=\"token punctuation\">\\</span>\n  -e <span class=\"token assign-left variable\">DB_URL</span><span class=\"token operator\">=</span><span class=\"token string\">\"postgres://postgres:postgres@localhost:5432/postgres\"</span> <span class=\"token punctuation\">\\</span>\n  -d boxyhq/jackson</code></pre></div>\n<p>Once Jackson is running, a tenant’s SAML connection gets registered by posting their IdP metadata to it. Then, on the SuperTokens side, a ThirdParty provider is configured for that tenant pointing at the Jackson instance, using one of the supported provider IDs (<code class=\"language-text\">boxy-saml</code>, or a suffixed variant for tenants with multiple connections).</p>\n<p>The <a href=\"https://supertokens.com/docs/authentication/enterprise/saml\" target=\"_blank\" rel=\"nofollow\">SuperTokens enterprise SAML integration guide</a> walks through the full setup including multi-tenancy. The short version: each enterprise customer becomes a SuperTokens tenant, each tenant gets its own SAML connection in Jackson, and the same SuperTokens session layer handles users from every protocol.</p>\n<p>If you’re still evaluating which SSO provider to build on, <a href=\"https://supertokens.com/blog/sso-providers\" target=\"_blank\" rel=\"nofollow\">this comparison of open source SSO providers</a> covers the main options. For teams that have landed on SuperTokens: it supports both modern OIDC (native) and SAML (via Jackson) under a unified multi-tenant session layer, is open source and self-hostable, so there is no vendor lock-in, and works with the SAML IdPs enterprise customers actually use: Entra ID, Okta, Google Workspace, ADFS, Ping, OneLogin, JumpCloud, and Rippling.</p>\n<h2 id=\"faq\" style=\"position:relative;\"><a href=\"#faq\" aria-label=\"faq permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>FAQ</h2>\n<h3 id=\"is-saml-the-same-as-sso\" style=\"position:relative;\"><a href=\"#is-saml-the-same-as-sso\" aria-label=\"is saml the same as sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Is SAML the same as SSO?</strong></h3>\n<p>No. SSO is the authentication strategy where one login grants access to multiple applications. SAML is one of the protocols that implements SSO. OIDC and Kerberos are others.</p>\n<h3 id=\"is-saml-still-relevant-in-2026\" style=\"position:relative;\"><a href=\"#is-saml-still-relevant-in-2026\" aria-label=\"is saml still relevant in 2026 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Is SAML still relevant in 2026?</strong></h3>\n<p>Yes. SAML 2.0 has been the OASIS Standard since March 2005 and remains the dominant protocol for enterprise IdP integrations. Any B2B SaaS that wants enterprise customers will eventually need to support SAML.</p>\n<h3 id=\"can-oidc-replace-saml\" style=\"position:relative;\"><a href=\"#can-oidc-replace-saml\" aria-label=\"can oidc replace saml permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Can OIDC replace SAML?</strong></h3>\n<p>For new integrations and modern IdPs, often yes. Okta, Entra ID, and Google Workspace all speak OIDC fluently. But if a specific enterprise customer’s IT team has standardized on SAML (common with ADFS, legacy Okta tenants, or compliance-heavy environments), SAML support is required to land the deal.</p>\n<h3 id=\"what-is-a-saml-assertion\" style=\"position:relative;\"><a href=\"#what-is-a-saml-assertion\" aria-label=\"what is a saml assertion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>What is a SAML assertion?</strong></h3>\n<p>A signed XML document issued by the IdP that proves a user’s identity to a Service Provider. It typically contains an authentication statement (when and how the user logged in), an attribute statement (email, name, group memberships), and validity timestamps. The SP validates the signature against the IdP’s public certificate before trusting the contents.</p>\n<h3 id=\"what-is-the-difference-between-sp-initiated-and-idp-initiated-sso\" style=\"position:relative;\"><a href=\"#what-is-the-difference-between-sp-initiated-and-idp-initiated-sso\" aria-label=\"what is the difference between sp initiated and idp initiated sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>What is the difference between SP-initiated and IdP-initiated SSO?</strong></h3>\n<p><strong>SP-initiated:</strong> The user starts at the application, the application redirects them to the IdP with an <code class=\"language-text\">AuthnRequest</code>, the IdP authenticates and sends back a response. This is the common case.</p>\n<p><strong>IdP-initiated:</strong> The user is already logged into the IdP dashboard, clicks a tile for the application, and the IdP pushes an unsolicited assertion to the ACS URL. Convenient, but riskier because there is no <code class=\"language-text\">AuthnRequest</code> to validate against.</p>\n<h3 id=\"does-supertokens-support-saml\" style=\"position:relative;\"><a href=\"#does-supertokens-support-saml\" aria-label=\"does supertokens support saml permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Does SuperTokens support SAML?</strong></h3>\n<p>Yes, through integration with BoxyHQ’s SAML Jackson. Jackson runs as a microservice alongside SuperTokens and exposes SAML flows as OAuth 2.0 for the application backend. SuperTokens natively supports OIDC for modern flows. Both can run side-by-side per tenant in a multi-tenant deployment.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>SAML and SSO are not the same thing, and conflating them is the single most common source of confusion in enterprise authentication. SSO is the goal: one login, many apps. SAML is one specific, XML-based, OASIS-standardized protocol that gets there, and the one that enterprise customers will most often demand by name.</p>\n<p>For a B2B SaaS engineer trying to unblock an enterprise deal: ship OIDC as the default and add SAML as a per-tenant capability when the customer requires it. Avoid trying to make OIDC do SAML’s job, and avoid asking enterprise customers to switch protocols to make engineering simpler. Multi-tenancy from day one. Signature validation done by a battle-tested library. SLO on the roadmap before the first security review.</p>\n<p><a href=\"https://supertokens.com\" target=\"_blank\" rel=\"nofollow\">SuperTokens</a> handles this combined reality with native OIDC support and SAML-via-Jackson under a unified multi-tenant session layer. Open source, self-hostable, and built so application code stays simple regardless of which protocol an individual customer brings.</p>\n<p><em><strong>Add enterprise SAML SSO in minutes → <a href=\"https://supertokens.com/docs/authentication/enterprise/saml\" target=\"_blank\" rel=\"nofollow\">supertokens.com/docs/authentication/enterprise/saml</a></strong></em></p>","frontmatter":{"date":"May 22, 2026","title":"SAML vs. SSO: What's the Difference, How They Work Together, and Which One You Actually Need","cover":"saml-vs-sso.png","author":"Mostafa Ibrahim","description":"SAML and SSO aren't the same thing. Learn the key differences, how SAML-based SSO works step by step, when to use SAML vs. OIDC, and how to implement it with SuperTokens."},"fields":{"slug":"/saml-vs-sso/"}},"site":{"siteMetadata":{"title":"SuperTokens Blog"}}},"pageContext":{"id":"30928ffc-2d06-567c-9aea-8d238941c272","fields__slug":"/saml-vs-sso/","__params":{"fields__slug":"saml-vs-sso"}}},
    "staticQueryHashes": []}