{"id":212,"date":"2025-03-07T15:29:45","date_gmt":"2025-03-07T15:29:45","guid":{"rendered":"https:\/\/discovery.cevolution.co.uk\/ciam\/?p=212"},"modified":"2026-03-13T11:13:52","modified_gmt":"2026-03-13T11:13:52","slug":"oidc-saml-and-oauth-2-0","status":"publish","type":"post","link":"https:\/\/discovery.cevolution.co.uk\/ciam\/2025\/03\/07\/oidc-saml-and-oauth-2-0\/","title":{"rendered":"OIDC, SAML and OAuth 2.0"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 9<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>\n<p>Many developers have encountered the terms <span class=\"popup-trigger popmake-407\" data-popup-id=\"407\" data-do-default=\"0\">OIDC<\/span>, <span class=\"popup-trigger popmake-470\" data-popup-id=\"470\" data-do-default=\"0\">SAML<\/span> and <span class=\"popup-trigger popmake-467\" data-popup-id=\"467\" data-do-default=\"0\">OAuth 2.0<\/span>. However, hearing about them and knowing what they are, as well as when to use them, are different things.<\/p>\n\n\n\n<p>For instance, can you say which are protocols primarily intended for <a href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/authorize\/\" data-type=\"page\" data-id=\"9\" target=\"_blank\" rel=\"noreferrer noopener\">Authorization<\/a> and which should be used for <a href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/authenticate\/\" data-type=\"page\" data-id=\"6\" target=\"_blank\" rel=\"noreferrer noopener\">Authentication<\/a>? Which protocols only support Browser-based workflows and which provide other workflow mechanisms, too? Which produces a <span class=\"popup-trigger popmake-1899\" data-popup-id=\"1899\" data-do-default=\"0\">JWT<\/span> and which produces an Assertion?<\/p>\n\n\n\n<p>Whilst I don&#8217;t necessarily disagree with @JustDeezGuy (below) \u2014 particularly the part &#8220;<em>&#8230;and you shouldn&#8217;t rely on third-party <span class=\"popup-trigger popmake-3335 \" data-popup-id=\"3335\" data-do-default=\"0\">SDKs<\/span>&#8230;<\/em>&#8221; \u2014 Auth, with all its various permutations and combinations, isn&#8217;t exactly as easy as @Ashref might lead folks to believe. Read my <em><a href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/2025\/02\/22\/diy-or-buy\/\" data-type=\"post\" data-id=\"127\">Build, Buy or DIY<\/a><\/em> post if you want to know more about my thoughts on the matter.<\/p>\n\n\n\n<div class=\"wp-block-group is-content-justification-center is-nowrap is-layout-flex wp-container-core-group-is-layout-23441af8 wp-block-group-is-layout-flex\">\n<figure class=\"wp-block-embed aligncenter is-type-rich is-provider-twitter wp-block-embed-twitter has-text-align-center\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"embed-twitter\"><blockquote class=\"twitter-tweet\" data-width=\"500\" data-dnt=\"true\"><p lang=\"en\" dir=\"ltr\">I wouldn&#39;t put it quite this harshly, but it IS true there are ~2 relevant standards, OIDC and SAML, and you shouldn&#39;t rely on third-party SDKs (I&#39;m looking at you, Okta, Auth0&#8230;) for them.<br><br>Working with literally any conformant OIDC or SAML system is not hard. <a href=\"https:\/\/t.co\/smejiN6P8I\">https:\/\/t.co\/smejiN6P8I<\/a><\/p>&mdash; Paul Snively (@JustDeezGuy) <a href=\"https:\/\/twitter.com\/JustDeezGuy\/status\/1860342601875927549?ref_src=twsrc%5Etfw\">November 23, 2024<\/a><\/blockquote><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/div>\n<\/div><\/figure>\n<\/div>\n\n\n\n<p>I do, however, concur with @JustDeezGuy&#8217;s follow-up comment, which says &#8220;<em>&#8230;avoid both nonconformance and vendor-specific features, both of which introduce significant risk as well as defeating the purpose of standardisation in the first place.<\/em>&#8221; Because that&#8217;s largely the problem: vendor-specific implementations quite frequently <em>are <\/em>nonconformant, often because there&#8217;s a lot of confusion around even the standards specs, which makes it hard for implementers to make the right choices.<\/p>\n\n\n\n<p>My name&#8217;s <span class=\"popup-trigger popmake-378\" data-popup-id=\"378\" data-do-default=\"0\">Peter Fernandez<\/span>, and in this article \u2014 a corollary to my companion article, linked below \u2014 I&#8217;m going to discuss some of the various aspects regarding the specifications associated with modern security protocols.<\/p>\n\n\n\n<div class=\"wp-block-group is-content-justification-center is-nowrap is-layout-flex wp-container-core-group-is-layout-23441af8 wp-block-group-is-layout-flex\">\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-discover-ciam wp-block-embed-discover-ciam\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"6B5flEc0BR\"><a href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/2026\/03\/12\/auth-in-the-world-of-customer-identity\/\">Auth In The World Of Customer Identity<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Auth In The World Of Customer Identity&#8221; &#8212; Discover CIAM\" src=\"https:\/\/discovery.cevolution.co.uk\/ciam\/2026\/03\/12\/auth-in-the-world-of-customer-identity\/embed\/#?secret=dqQeCSItxp#?secret=6B5flEc0BR\" data-secret=\"6B5flEc0BR\" width=\"500\" height=\"282\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"oauth2\">OAuth 2.0<\/h2>\n\n\n<p>Let&#8217;s start with Open Authorization 2.0 (a.k.a. <span class=\"popup-trigger popmake-467 \" data-popup-id=\"467\" data-do-default=\"0\">OAuth 2.0<\/span>). OAuth 2.0 was first introduced in <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc6749\" target=\"_blank\" rel=\"noreferrer noopener\">RFC 6749<\/a>, which was published in late 2012. It was introduced as a direct replacement for its predecessor, OAuth 1.0, which was obsoleted due to various security\/operational issues.<\/p>\n\n\n\n<p>OAuth 2.0 is an <strong><a data-type=\"page\" data-id=\"9\" href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/authorize\/\">Authorization<\/a><\/strong> protocol, specifically one intended to primarily deal with Delegated Authorization, as opposed to anything else. <\/p>\n\n\n\n<p>What is Delegated Authorization, you may ask? Well, authorisation has been around as long as authentication (arguably longer), and most know it as a function of access control \u2014 as in, what someone is allowed to do based on policy and permission. Delegated authorisation complements this by including the ability for a user to consent to what an application can access on their behalf. <\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-581f538e872c38a1d824cfda1279c8e6 is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>In essence, <span class=\"popup-trigger popmake-2149\" data-popup-id=\"2149\" data-do-default=\"0\">Delegated Authorization<\/span> refers to the situation where an authenticated User consents to the access of specific information, on their behalf, thus delegating authorisation to some (third-party) application.<\/em><\/p>\n<\/div>\n\n\n\n<p>Let me elaborate. At that time, SAML was the protocol of choice for modern Browser-based application <strong><a data-type=\"page\" data-id=\"6\" href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/authenticate\/\">Authentication<\/a><\/strong>, particularly in an Enterprise environment. SAML isn&#8217;t used for authorisation, and wasn&#8217;t the only authentication protocol being used either; authentication in an application context was still being performed using LDAP, explicit UserID\/Password validation, and even the likes of Kerberos and Radius. However, SAML introduced a new standard for user authentication and, essentially, <span class=\"popup-trigger popmake-397\" data-popup-id=\"397\" data-do-default=\"0\">SSO<\/span> was born.<\/p>\n\n\n\n<p>Around the same time, the rise of the public-facing Web <span class=\"popup-trigger popmake-2876\" data-popup-id=\"2876\" data-do-default=\"0\">API<\/span> (accessed using the HTTP protocol) was giving developers the ability to build rich applications, supporting system expansion at an unprecedented rate. <\/p>\n\n\n\n<p>With these Web APIs enabling the likes of mobile apps, single-page applications, etc, new security and security-related challenges were emerging. For web APIs \u2014 or just APIs as we now call them; the term <span class=\"popup-trigger popmake-3335\" data-popup-id=\"3335\" data-do-default=\"0\">SDK<\/span> is now typically used for what was arguably the classic definition of an API, but I digress \u2014 secure access is an important factor, and the only mechanisms then available for that were <strong>Basic Authentication<\/strong> or an <strong>API Key<\/strong>.<\/p>\n\n\n\n<p>Authorisation is pretty much predicated on an authenticated context being established. For authorised API access, <em>Basic Authentication<\/em> essentially provides the ID \u2014 e.g. the UserID \u2014 and the Password of the accessing party for validation (against some known credentials). <\/p>\n\n\n\n<p>Whilst HTTPS provides a mechanism for the secure transport of an ID and Password, those ID and Password credentials end up being handled by a number of different parties and potentially exposed to all sorts of vulnerabilities. <\/p>\n\n\n\n<p>Further, the ubiquitous use of HTTPS was still in its infancy, and anyway, who could say that the API being called wasn&#8217;t created by some malicious third party intent on stealing those vulnerable credentials?<\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-5ee6cfac8001c7e43b9c281a78cdc15a is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>The use of an API typically involves a RESTful process. REST (a.k.a. Representational State Transfer) does not make use of a session context for communication. Ergo, any and every REST request must carry enough information to establish an authenticated context.<\/em><\/p>\n<\/div>\n\n\n\n<p>An <em>API key<\/em> gets around credential vulnerability by using an opaque &#8220;token&#8221; \u2014 i.e. something akin to a GUID (Globally Unique Identifier), that&#8217;s representative of credentials rather than being the actual credentials themselves. <\/p>\n\n\n\n<p>However, an API Key is typically not issued for a specific entity. API Keys are notoriously difficult to manage, and as an API Key is often used by more than one accessing party, it&#8217;s almost impossible to tell what actually made the API call and, more importantly, on whose behalf.<\/p>\n\n\n\n<p>Additionally, there&#8217;s no real way with either <em>Basic Authentication<\/em> or an <em>API Key<\/em> for a user to consent to an application accessing information (on their behalf). With regulatory compliance, such as modern GDPR, in its infancy, that wasn&#8217;t necessarily an immediate issue, but it was going to become a challenge.<\/p>\n\n\n\n<p>Remember, too, that an API (also known as a <em>Resource Server<\/em> in OAuth 2.0) typically provides access to resources either owned or managed by the entity on whose behalf the API is being called. Calling an API involves the use of HTTP \u2014 or more specifically HTTPS \u2014 but doesn&#8217;t involve the use of a Browser. Hence, there&#8217;s no mechanism for a user to interactively provide consent, or anything else, as part of the API calling process.<\/p>\n\n\n\n<p>The solution to the problem became OAuth 2.0. OAuth 2.0 introduced concepts that would enable authorised access to resource information, via an API, on behalf of whatever entity was using the application (typically a User). <\/p>\n\n\n\n<p>Many folks are under the impression that OAuth 2.0 replaces SAML, the use of a UserID\/Password, or any other authentication mechanism for that matter. It doesn&#8217;t. In fact, it complements it: an OAuth 2.0 <strong>Authorization Server<\/strong> \u2014 the thing that mints an <strong>Access Token<\/strong>, a.k.a. <strong>Bearer Token<\/strong> \u2014 leverages whatever authentication protocol is available to establish a secure and authenticated context in which the token can be created for (delegated) authorisation use.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"access-bearer-tokens\">Access (Bearer) Tokens<\/h3>\n\n\n<p>At the heart of OAuth 2.0 lies the <strong>Access Token<\/strong>. An Access Token is a security artefact that essentially acts like an API Key, but one that&#8217;s dynamically generated in the context of the entity (typically a User) on behalf of whom an API is being accessed. <\/p>\n\n\n\n<p>Access Tokens have a specific lifetime and are typically managed by an OAuth 2.0 <strong>Authorization Server<\/strong> implementation. Lifetime is an important addition because, unlike with an API Key, an Access Token can expire and effectively become obsolete. In a related post on LinkedIn, <a href=\"https:\/\/www.linkedin.com\/in\/nikkisiapno\/\" title=\"\">Nikki Siapno<\/a> shares another excellent animated explanation of the use of an Access Token, and whilst it assumes use of a JWT, it&#8217;s applicable irrespective of the token format being used:<\/p>\n\n\n\n<div class=\"wp-block-group has-text-align-center has-global-padding is-layout-constrained wp-container-core-group-is-layout-7db9d80f wp-block-group-is-layout-constrained\" style=\"padding-right:0;padding-left:0\">\n<iframe loading=\"lazy\" src=\"https:\/\/www.linkedin.com\/embed\/feed\/update\/urn:li:share:7438125642166005760?collapsed=1\" height=\"670\" width=\"100%\" frameborder=\"0\" allowfullscreen=\"\" title=\"Embedded post\"><\/iframe>\n<\/div>\n\n\n\n<p>Third-party SaaS Authorization Servers like Auth0 express the Access Token in <span class=\"popup-trigger popmake-1899\" data-popup-id=\"1899\" data-do-default=\"0\">JWT<\/span> form, but the actual OAuth 2.0 standard does not prescribe any particular format. Consequently, this can create confusion when developers think about a &#8220;JWT&#8221; and when it should be used. I&#8217;ll talk more about that in the next section (<a href=\"#oidc\">below<\/a>).<\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-23172eb88d8ac3e9ec6c558d766098b1 is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>To add to the confusion, Auth0 also uses the <code>scope<\/code> claim in a <span class=\"popup-trigger popmake-1899\" data-popup-id=\"1899\" data-do-default=\"0\">JWT<\/span> to express the consent provided by a User together with the impact of any Role Based Access Control (RBAC). Whilst <code>scope<\/code> is defined as part of <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc9068\" target=\"_blank\" rel=\"noreferrer noopener\">RFC 9068<\/a> (the JWT Profile for OAuth 2.0 Access Tokens), arguably, its meaning differs between OAuth 2.0, OIDC, and how Auth0 treats it.<\/em><\/p>\n<\/div>\n\n\n\n<p>Minting an Access Token is handled by the Authorization Server, and typically involves a protocol &#8220;dance&#8221; similar to that illustrated below, known as <em><span class=\"popup-trigger popmake-3653\" data-popup-id=\"3653\" data-do-default=\"0\">Authorization Code Flow<\/span><\/em>. <\/p>\n\n\n\n<p>Explaining that dance, as well as some of the other available flows, is beyond the scope of this article, suffice it to say that once the Access Token is created, it&#8217;s used by the application as part of the call to the API; the token is typically supplied as the <code>Bearer<\/code> token in the API call:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"665\" src=\"https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/05120716\/Authorization-Code-Flow-With-PKCE-1024x665.png\" alt=\"\" class=\"wp-image-1404\" srcset=\"https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/05120716\/Authorization-Code-Flow-With-PKCE-1024x665.png 1024w, https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/05120716\/Authorization-Code-Flow-With-PKCE-300x195.png 300w, https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/05120716\/Authorization-Code-Flow-With-PKCE-768x499.png 768w, https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/05120716\/Authorization-Code-Flow-With-PKCE.png 1444w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Image courtesy of <a href=\"https:\/\/cloudentity.com\/developers\/basics\/oauth-grant-types\/authorization-code-flow\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudentity<\/a><\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-9fc5c2e0b62812512f86dd7a1115b370 is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>The diagram above illustrates Authorization Code Flow with <span class=\"popup-trigger popmake-1895\" data-popup-id=\"1895\" data-do-default=\"0\">PKCE<\/span>, a variation using the best-practice Proof Key for Code Exchange (PKCE) mechanism, mandatory for public clients and recommended generally to mitigate <span class=\"popup-trigger popmake-2365\" data-popup-id=\"2365\" data-do-default=\"0\">MITM<\/span> attacks.<\/em><\/p>\n<\/div>\n\n\n\n<p>An application will typically hold on to an Access Token for use in an API call, but it should never be tempted to look at its contents, irrespective of whether it&#8217;s in a JWT form or not. An OAuth2.0 Access Token should only ever be consumed by the API (<code>audience<\/code>) for which it was intended!<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"oidc\">OIDC<\/h2>\n\n\n<p>Having established that OAuth 2.0 is used for <em>Authorization<\/em> and is complementary to any <em>Authentication<\/em> mechanism, let&#8217;s turn our attention to Open ID Connect \u2014 a.k.a. <span class=\"popup-trigger popmake-407\" data-popup-id=\"407\" data-do-default=\"0\">OIDC<\/span>. <\/p>\n\n\n\n<p>OIDC is based on the OAuth 2.0 protocol and is designed as a modern authentication workflow, intended as a direct replacement for SAML (or anything else for that matter).<\/p>\n\n\n\n<p>Originally designed for Enterprise environments \u2014 as in authentication for applications used within a company or corporate organisation \u2014 SAML is quite a complicated protocol. It typically relies on established trust relationships and employs the use of an XML format security artefact structure, typically referred to as an <strong><a href=\"#assertion\">Assertion<\/a><\/strong>.<\/p>\n\n\n\n<p>Whilst SAML still has a very valid place in modern authentication architecture (and its introduction was an important milestone, particularly in the development of SSO) in the world of B2C and B2B SaaS, it&#8217;s too cumbersome to use in the various and numerous scenarios you typically find with those environments. <\/p>\n\n\n\n<p>For starters, XML is quite heavyweight when it comes to wire transfer, and processing it can be quite application-intensive, too. Add to the mix that establishing and maintaining explicit trust relationships between the various and disparate systems would be an absolute nightmare, and you can quickly see why SAML doesn&#8217;t fly.<\/p>\n\n\n\n<p>SAML, however, is better than its predecessors \u2014 e.g. explicit UserID\/Password credential validation or the use of LDAP \u2014 and its development pioneered important advances for authentication&#8230;just as the development of OAuth 2.0 did for (delegated) authorisation.<\/p>\n\n\n\n<p>Based on learnings from the development of OAuth 2.0, together with the pioneering advancements from SAML, OIDC was born. Introduced in 2014, the <a href=\"https:\/\/openid.net\/specs\/openid-connect-core-1_0-final.html\" target=\"_blank\" rel=\"noreferrer noopener\">OpenID Connect 1.0 Specification<\/a> \u2014 which remains the core working specification today \u2014 defines a simple identity layer on top of the OAuth 2.0 protocol specification to provide for modern application authentication.<\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-8bb391d86c6a8b457cb1495b1e9e42f3 is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>OIDC isn&#8217;t built on the OAuth 2.0 protocol per se \u2014 as in it doesn&#8217;t require an OAuth 2.0 implementation to work \u2014 rather, the architecture of its protocol is derived from that of OAuth 2.0; the <span class=\"popup-trigger popmake-3653 \" data-popup-id=\"3653\" data-do-default=\"0\">Authorization Code Flow <\/span>&#8220;dance&#8221; described above, at least from a Browser perspective, is pretty much identical.<\/em><\/p>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"id-tokens\">ID Tokens<\/h3>\n\n\n<p>In a similar fashion to OAuth 2.0, at the heart of OIDC lies a security artefact known as the <strong>ID Token<\/strong>. An ID Token is explicitly defined to be a secure <span class=\"popup-trigger popmake-1899\" data-popup-id=\"1899\" data-do-default=\"0\">JWT<\/span> artefact, containing a number of well-defined standard attributes, also known as <strong>claims<\/strong>. The ID Token takes the place of the Assertion used in SAML and provides an application with an indication of a user&#8217;s authenticated state.<\/p>\n\n\n\n<p>Unlike an OAuth 2.0 <em>Access Token<\/em>, an OIDC ID Token is absolutely intended for application consumption, with the secured claims it contains easily providing the information required to inform the user interface\/user experience. <\/p>\n\n\n\n<p>Whilst an ID Token should always be expressed in JWT format, it should never be used to call an API \u2014 even if that API can process JWT format tokens as per <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc9068\" target=\"_blank\" rel=\"noreferrer noopener\">RFC 9068<\/a>. Whilst similarly named, many of the claims contained in an ID Token serve a subtly different purpose from the ones in an Access Token.<\/p>\n\n\n\n<p>As with SAML, all of the vulnerabilities associated with credential handling and management are handled by what is typically referred to as the <strong>Identity Provider<\/strong> (or <span class=\"popup-trigger popmake-415\" data-popup-id=\"415\" data-do-default=\"0\">IdP<\/span> for short) \u2014 and via the incorporation of aspects from OAuth 2.0, the OIDC architecture can provide profile information about a User that can also be obtained in an interoperable and REST-like manner.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"saml\">SAML<\/h2>\n\n\n<p>I&#8217;m not going to go into too much detail regarding Security Assertion Markup Language (i.e. <span class=\"popup-trigger popmake-470\" data-popup-id=\"470\" data-do-default=\"0\">SAML<\/span> for short) in this article; suffice to say that SAML is arguably the father of modern Identity and Access Management. I&#8217;ve already highlighted some aspects of SAML and how they have helped to influence the development of both OIDC and OAuth 2.0, and the diagram below shows how SAML flow helped influence the aforementioned &#8220;dance&#8221; that&#8217;s part of OIDC and OAuth 2.0, as well as highlighting some notable differences:  <\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"785\" height=\"534\" src=\"https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/22170329\/image-60-e1771780282215.png\" alt=\"\" class=\"wp-image-5307\" style=\"width:835px;height:auto\" srcset=\"https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/22170329\/image-60-e1771780282215.png 785w, https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/22170329\/image-60-e1771780282215-300x204.png 300w, https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/22170329\/image-60-e1771780282215-768x522.png 768w\" sizes=\"auto, (max-width: 785px) 100vw, 785px\" \/><figcaption class=\"wp-element-caption\">Image courtesy of <a href=\"https:\/\/docs.secureauth.com\/ciam\/en\/saml-single-sign-on--sso--flow.html\" title=\"\">SecureAuth<\/a><\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-1754bb72196dee0fcb635cb647973ed0 is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>On the face of it, the SAML protocol workflow seems far simpler than with OIDC (which is based on OAuth 2.0). However, SAML requires a certificate-based trust relationship as a prerequisite, making use in <span class=\"popup-trigger popmake-523\" data-popup-id=\"523\" data-do-default=\"0\">Social<\/span> scenarios and the like practically impossible. <\/em><\/p>\n<\/div>\n\n\n\n<p>SAML and OIDC are essentially mutually exclusive, as in an application will typically make use of one or the other but not both at the same time. However, both are mutually inclusive when it comes to OAuth 2.0; no matter which one of SAML or OIDC an application uses, OAuth 2.0 is always a valid complement when it comes to accessing APIs.<\/p>\n\n\n\n<p>One thing I will say is that the use of OIDC in Enterprise environments is becoming more prolific, partly driven by the increasing boom in the B2B SaaS market. It&#8217;s not replacing SAML exactly, but it does mean that when it comes to things like SSO, the need to cater for interop \u2014 where there are multiple applications, each using either SAML or OIDC \u2014 makes the notion of building your own solution that much more difficult. For more on that, see my article entitled<\/p>\n\n\n\n<div class=\"wp-block-group is-content-justification-center is-nowrap is-layout-flex wp-container-core-group-is-layout-23441af8 wp-block-group-is-layout-flex\">\n<figure class=\"wp-block-embed aligncenter is-type-wp-embed is-provider-discover-ciam wp-block-embed-discover-ciam\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"PmqbJ3lUlw\"><a href=\"https:\/\/discovery.cevolution.co.uk\/ciam\/2025\/02\/22\/diy-or-buy\/\">Build, Buy or DIY your CIAM Solution?<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Build, Buy or DIY your CIAM Solution?&#8221; &#8212; Discover CIAM\" src=\"https:\/\/discovery.cevolution.co.uk\/ciam\/2025\/02\/22\/diy-or-buy\/embed\/#?secret=Ni3fd1TIQw#?secret=PmqbJ3lUlw\" data-secret=\"PmqbJ3lUlw\" width=\"500\" height=\"282\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"assertion\">Assertion<\/h3>\n\n\n<p>I will spend a moment on the topic of the SAML Assertion, really to highlight how validating a security artefact replaces validating credentials, and how this fundamentally changes what an application needs to do when it comes to authentication in a modern environment. <\/p>\n\n\n\n<p>The introduction of SAML redefined the workflow for authentication and opened up the ability for secure application interop, at least from an identity perspective. The SAML Assertion was a fundamental part of that, by defining a way for something representative of an authentication state to be shared and exchanged without the need for exposing credentials.<\/p>\n\n\n\n<p>With an Assertion, as with an ID Token and even an Access Token, the consumer \u2014 i.e. the Application or the API \u2014 becomes responsible for validating and subsequently consuming a security artefact, blissfully ignorant of whatever credentials were used to validate the creation of the artefact or, indeed, the supplemental mechanisms (such as <span class=\"popup-trigger popmake-428 \" data-popup-id=\"428\" data-do-default=\"0\">MFA<\/span>) that were employed as part of its creation.  <\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-accent-4-background-color has-text-color has-background has-link-color wp-elements-e76f729229abb4745da0b4d485c7b84d is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:20px\">\n<p class=\"has-text-align-center\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\"><em>Unlike with an ID Token, a SAML Assertion is more difficult to handle, as an XML document is more heavyweight than its lighter-weight <span class=\"popup-trigger popmake-1899 \" data-popup-id=\"1899\" data-do-default=\"0\">JWT <\/span>counterpart. <\/em><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Many developers have encountered the terms OIDC, SAML and OAuth 2.0. However, hearing about them and knowing what they are \u2014 as well as when to use them \u2014 are very different things. Read more about these modern CIAM protocols and why you should consider using them.<\/p>\n","protected":false},"author":1,"featured_media":1483,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"authenticate":"","authentication":"","authenticatedMethod":"","authenticatedMember":"","authorizedPermissions":[],"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_links_to":"","_links_to_target":""},"categories":[7],"tags":[20,18,19],"class_list":["post-212","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-integration","tag-oauth2","tag-oidc","tag-saml"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/discovery-bucket-ha60ib.s3.eu-west-2.amazonaws.com\/wp-content\/uploads\/sites\/22\/2025\/03\/07150511\/create-a-featured-image-for-an-article-discussing-the-oidc-2.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/posts\/212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/comments?post=212"}],"version-history":[{"count":46,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/posts\/212\/revisions"}],"predecessor-version":[{"id":5481,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/posts\/212\/revisions\/5481"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/media\/1483"}],"wp:attachment":[{"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/media?parent=212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/categories?post=212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/discovery.cevolution.co.uk\/ciam\/wp-json\/wp\/v2\/tags?post=212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}