# OAuth? SAML? Single Sign On?

By Hassib Ashouri · 2026-09-27

A high-level guide to SSO, SAML, OAuth, OpenID Connect, and the authorization flows behind signing in with Google or Apple.

I started digging into this when I was building the authentication layer for an app. I wanted users to sign in with their existing Google or Apple accounts. I started researching terms like “single sign-on” and was overwhelmed by the amount of junk in the search results.

Then I remembered that I can use my work email—which has a custom domain managed through Google Workspace—to sign in to other SaaS apps. I can also use my personal Gmail account to do the same thing.

All of a sudden, I became more interested in the foundational concepts and standards underlying single sign-on. This post is the distillation of what I learned. I like learning things at a high level and digging into their history a bit.

While I don't cover the history here, it is worth looking up the history of the same-origin policy and how web and mobile apps worked in the early days of the web. That context helps explain the existence of the Implicit Grant, which you will read about later.

> **TL;DR:** To authenticate users with Google, Apple, or another identity provider, use the Authorization Code Grant with OpenID Connect (OIDC). Add PKCE for public clients such as browser-based single-page apps and native mobile apps; it is also recommended for confidential clients. Depending on what you are building, you may need an OAuth client on the frontend, the backend, or both.

## Basics

- **Authentication (AuthN):** Answers, “Who are you?”
- **Authorization (AuthZ):** Answers, “Are you allowed to perform this action?”
- **Single sign-on (SSO):** A user experience, not a standard.
- **Security Assertion Markup Language (SAML):** An open standard for exchanging authentication and authorization data. SAML 1.0 was released in 2002 and SAML 2.0 in 2005.
- **Open Authorization (OAuth):** A standard for delegated access. In other words, a user can allow an application to access a resource on their behalf. OAuth 1.0 was released in 2007 and OAuth 2.0 in 2012.
- **OpenID Connect (OIDC):** An identity layer built on top of OAuth 2.0 to provide authentication. The OIDC standard was released in 2014.
- **Confidential client:** A client with a backend that can protect credentials such as a client secret.
- **Public client:** A client that can't keep credentials secret, such as a browser-based single-page app or native mobile app.

## SAML and SSO

SAML is a mechanism that can allow employees of a company to access software their employer bought—for example, an employee signing in to Slack or Salesforce. It is built around identity federation. It is not built to let a user share access to a resource with another app. If you want App X to access your work calendar, SAML isn't built for that use case.

The entities involved are:

- **Identity Provider (IdP):** The system that authenticates the user, such as Microsoft Entra ID or Google Workspace.
- **Service Provider (SP):** The application the user is trying to access, such as a SaaS product.
- **SAML assertion:** A message from the IdP containing statements about the user, often including attributes. In a common browser SSO flow, the browser sends it to the SP through an HTTP POST.

SAML is one standard that can be used to achieve SSO. SAML 2.0 has been around for some time, and it continues to be maintained.

## OAuth

OAuth was built to handle delegated access, which is a form of authorization. Simply put, **you** approve an app to perform an action on your behalf—for example, to read or update your calendar. OAuth can also serve as the foundation for authentication when it is paired with OIDC, as we will see later.

### Some Technical Background

When I mention OAuth here, I am mostly referring to OAuth 2.0. It is a framework for *delegated authorization*, which means letting *someone else* take actions on your behalf. In this case, *someone else* is another application.

The main actors are:

- **Resource Owner (RO):** The person who owns the data.
- **Client:** The application requesting authorization. It may have public components, confidential components, or both.
- **Authorization Server:** The service that authenticates the person, obtains their authorization, and issues access tokens. If the user authorizes access through Google, Google operates the Authorization Server.
- **Resource Server:** The service that hosts the protected data. If a user authorizes a client such as Superhuman to access Gmail, Google operates the Authorization Server and the Gmail API is the Resource Server. Both happen to live under the same roof in this example.

Artifacts you may encounter in an OAuth flow include:

- Authorization code
- Access token
- Refresh token

OAuth supports multiple grants and flows for different environments:

1. **Authorization Code Grant:** The most common grant for clients that can use a browser redirect. A simplified version of the flow looks like this:
   1. The client redirects the Resource Owner to the Authorization Server to request authorization.
   2. The Authorization Server redirects the browser back to the client's redirect URI with an authorization code.
   3. The client redeems the authorization code at the Authorization Server's token endpoint. A confidential client can authenticate itself during this request. The Authorization Server returns an access token and, depending on the request and server, may also return a refresh token.
   4. The client uses the access token to call the Resource Server within the access the Resource Owner approved.
2. **Client Credentials Grant:** A machine-to-machine grant in which the client acts on its own behalf rather than on behalf of a user.
3. **Implicit Grant:** An older flow that returns an access token directly through the browser redirect instead of issuing an authorization code. It was designed for public clients at a time when browser apps faced more limitations making cross-origin requests. It exposed tokens in the browser redirect and came with token leakage and replay risks, so current guidance favors the Authorization Code Grant with PKCE instead.
4. **Device Authorization Grant:** A flow meant for input-constrained devices, such as smart TVs, and for tools such as CLIs. The user authorizes the request on a separate device.
5. **Authorization Code Grant with PKCE (*Proof Key for Code Exchange*):** PKCE was developed to protect the Authorization Code Grant for public clients. The client creates a secret random `code_verifier` and derives a `code_challenge` from it. It sends the challenge in the authorization request, then sends the verifier when redeeming the authorization code. The Authorization Server checks that they match, helping ensure that a stolen authorization code cannot be redeemed without the verifier. See [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636) and the guidance for native apps in [RFC 8252](https://www.rfc-editor.org/info/rfc8252/).

For the best diagram I've found for this flow, read [From the Implicit flow to PKCE: A look at OAuth 2.0 in SPAs](https://pragmaticwebsecurity.com/articles/oauthoidc/from-implicit-to-pkce).

## OIDC

OpenID Connect (OIDC) builds on top of OAuth 2.0 to support authentication. A client needs a standard way to learn who the user is—for example, their identifier, email address, or name.

OIDC adds the `openid` scope to the authorization request, which tells the Authorization Server that this is an authentication request. Other scopes, such as `email` and `address`, request related sets of claims. Claims are pieces of information about the user.

In the Authorization Code Flow, the client exchanges the authorization code for an ID Token and an access token. The ID Token is a JWT containing claims about the authentication event and the user. The access token is used to access a protected resource such as the OIDC UserInfo endpoint. The client must validate the ID Token rather than treating it as trusted simply because it is a JWT.

The [OpenID Connect Core specification](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps) describes the complete Authorization Code Flow.

## References

- [The Beer Drinker’s Guide to SAML](https://duo.com/blog/the-beer-drinkers-guide-to-saml)
- [From the Implicit flow to PKCE: A look at OAuth 2.0 in SPAs](https://pragmaticwebsecurity.com/articles/oauthoidc/from-implicit-to-pkce)
- [RFC 8252: OAuth 2.0 for Native Apps](https://www.rfc-editor.org/info/rfc8252/)
- [RFC 7636: Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/html/rfc7636)
- [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/info/rfc6749)
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps)
