Why you probably do not need OAuth2 / OpenID Connect
Learn when you really need to integrate OAuth2 and OpenID Connect!


Founder & CTO
Learn when you really need to integrate OAuth2 and OpenID Connect!


Founder & CTO
You probably don't need OAuth2, nor OpenID Connect. This is a controversial opinion, even more so because my biggest professional achievements are the two most successful open source projects in the OAuth2 and OpenID Connect ecosystem:
Those two projects helped spawn a company building an open source ecosystem and managed auth service used by millions of users worldwide.

Before reading on please note that the views stated in this article are my professional opinion. My intention is to save you time developing the wrong things at the wrong time. It's in no way meant to discredit the technology and the brilliant people working on it.
While writing and maintaining Ory Hydra and Ory Fosite I've spent a good portion of my life working with a large developer community and understanding all the use cases and problems that users encounter when dealing with authentication and authorization. As a company, Ory also helps others audit and vet their auth systems. As such I often see OAuth 2 and OIDC used in the wrong context. This doesn't happen because people make mistakes or don't "get" security. It happens because the protocols are complex and often vague. When used in the wrong context it can lead to serious security vulnerabilities. So far we've identified over a dozen cases where incorrect implementation of OAuth2 and OpenID Connect was responsible for low-severity security issues - such as logout not properly invalidating sessions - as well as catastrophic vulnerabilities - such as account hijacking with full administrative privilege escalation. The scary part is that it can happen to any company of any size - regardless of how talented their developers are!
If the only tool you have is a hammer, you tend to see every problem as a nail. - "Maslow’s Hammer"
At Ory, we don't sell OAuth2 and OpenID Connect as the "holy grail" solution. While the two are very powerful protocols when used correctly, and have many advantages and use cases, the truth is that they aren't always necessary. In fact, you most likely don't need them.
Before we continue, I want to point out that there are two primary use cases where you are implementing OAuth2 or OpenID Connect and that this article only covers one of them:
Now that we've set the scene, let's look at the structure of this article. Similar to OAuth2 and OpenID Connect - and accompanying RFC8252, RFC6819, RFC7636, RFC8628, RFC 7523, OpenID Connect Discovery, OpenID Connect Session Management, OpenID Connect Front-/Backchannel Logout, ... - this article is long because OAuth2 and OpenID Connect span a variety of specifications and regularly spawn new, innovative specs.
Let's look at the main points covered in this article.
Before we dive deeper, I want to emphasize:
Let's agree that it's generally an excellent idea to use an existing piece of software to solve login, registration, user management, password, reset, account recovery, 2FA, and all topics related to user authentication and permission management (authorization). Today most technologies rely on OAuth2 as the primary interaction protocol. And as we will learn in this article, it's most often too complex with too many edge cases.
But that doesn't mean that there isn't a better way to solve these problems! Ory's attempt at building a better identity authentication de-facto open standard is the Ory Kratos Open Source project!
A generic decision tree to help you decide whether you need OAuth2 or not can be summarized as follows: https://miro.com/app/board/uXjVOYIT_dA=/
Since you're reading this on the Ory website and we believe in the products we build, you will find those prominently in the above graph. For comparable products we've collected the following open source ones:
OAuth2 states its primary use case in the first section (abstract) of its RFC:
The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
OAuth 2 was invented to address a need in the era of Web 2.0. Platforms such as Google and Facebook have massive troves of data and they wanted to open this data up to third parties. This was sometimes used benevolently - for example Facebook Games - and sometimes abused - for example Cambridge Analytica Scandal.
Furthermore in 2012, "Social Login" was all the craze. (And still is!)
OAuth2 and OpenID Connect were born to solve these two fundamental use cases:
If you are new to OAuth2, it might be confusing why you need OpenID Connect. The two are interlinked yet different. The main distinguishing factor is the audience of the resulting tokens:
OAuth2 isn't Authentication. Access tokens aren't sessions.
OpenID Connect was invented, or added on top of, OAuth2 because OAuth2's tokens are opaque - not transparent - to the third party clients who receive them. They serve no purpose except for presenting them to the first-party server such as GitHub and expecting a response such as the user's private repositories.
OAuth2 isn't an authentication (login) protocol! The purpose of OAuth2 Tokens is to authorize requests at a first party server (or API). If the third party uses the OAuth2 Access Token as proof of authentication, an attacker could easily impersonate a legitimate user.
https://myphotobook.com/login?access_token=<facebook_token>.https://myphotobook.com/login?access_token=<alices_myevilapp_facebook_token>.Standard OAuth2 mechanisms can be used to prevent this attack. One effective mitigation is ensuring that the access token was initiated by "myphotobook." However, this approach requires an in-depth understanding of the involved protocols and relies on implicit behavior. In security, we don't like implicit.
OpenID Connect addresses this by introducing a new type of token, along with additional configuration parameters, which can then be used by the third party to reliably and securely authenticate users. That's why OpenID Connect ID Tokens are transparent - usable - to the third party clients; it's because they are JSON Web Tokens that can be decoded. Additionally, ID Tokens contain the audience - in this case the third party, not the first party. That way, "myphotobook" can check whether the audience is "myphotobook" and not "myevilapp":
// Example ID Token Payload
{
"iss": "https://myphotobook.com",
"sub": "alice",
// OK:
"aud": ["myphotobook"],
// NOT OK:
"aud": ["myevilapp"],
"exp": 1516239022,
"iat": 1516239022
}
By now you've read "third party" quite often. And that's the catch! These protocols are targeted at third party integration. Meaning that someone else is trying to access your user's data. And someone else is trying to authenticate their users using your data!
Your first point of decision is exactly this. Are you building a system that interacts with third parties, such as partner networks and platform APIs? Or are you yourself becoming the next "Sign in with ..."? If so, OAuth2 and OpenID Connect are the best-in-class protocols to address your use case!
Regardless of whether you are building a mobile app, single page app, web app, native app, an API system, or you need Bearer Tokens or JSON Web Tokens. You most likely don't need the complexity of OAuth2 and OpenID Connect right now. What you most likely need is a system that offers a variety of methods to authenticate users (password, passwordless, FIDO2, biometrics, SMS, ...), has profile management, account recovery, password reset, email and phone number verification, and more.
You can always add OAuth2 and OpenID Connect on top of your existing authentication infrastructure using tools such as Ory Hydra.
Of course exceptions to the rule exist. In some cases it makes sense to start with OAuth2 and OpenID Connect right away. This can be the case for huge businesses such as Apple or Amazon that have hundreds of thousands of employees across hundreds of teams, organizations and offices. In these cases, office A (Google Mail) might not trust office B (Google Earth) to access data without user consent. Large organizations can afford the extra cost of training, implementation, testing, and maintenance of complex systems. But even then - sign in to your Google profile and you won't find OAuth2 or OpenID Connect but instead a regular login flow: Post the HTML form to a server, receive a cookie!

Google doesn't use OAuth2 or OpenID Connect in their login process
A counterexample to this is Amazon which uses OpenID Connect to sign you into their Amazon store.

Amazon uses OAuth2 / OpenID Connect in their login process
Another exception is if you plan interaction with a lot of different client types. This in particular applies to clients that don't have a traditional user interface (think Fire TV Stick, Chromecast, anything that doesn't feature a keyboard/USB port or browser). In this case you can benefit from the work done by the IETF and OpenID Foundation who have defined interactions for these types of clients.
Some examples of niche clients could be:
Adding OAuth2 and OpenID Connect to your system, where you're not using it as the primary authentication system for your own services, is beneficial if you use other tools and services which should use the central identity platform to authenticate users.
Examples of these tools could be:
In these cases you have to weigh whether you want to use one authentication method for first parties and another one (OpenID Connect) for third parties, or whether you want to use OpenID Connect for both. This decision depends a lot on context but neither of the two options are more or less difficult to implement.
An exception to the rule is if you plan to add OAuth2 to your system to service third parties. In this case you might save some time and effort by using OpenID Connect and not having to implement two authentication mechanisms.
The decision here isn't clear-cut and depends a lot on context. It can be as difficult to implement two authentication mechanisms for first and third-party use as implementing only OAuth2 for first and third-party.
Making things hard to understand and implement never improves security. It makes systems less secure since there are more things that can - and will - go wrong. OAuth2 and accompanying specifications are plentiful, difficult to read and understand, and sometimes vague. When interacting with popular OAuth2 and OpenID Connect providers - such as Facebook, Google, Amazon, ...- you will observe that everyone solves things a little differently. GitHub doesn't offer OpenID Connect capabilities, Facebook has their own flavor of OpenID Connect, Apple had to receive an open letter from the OpenID Foundation to become compatible, and Auth0 has its own OAuth2 quirks... the list goes on and on!
OAuth2 and OpenID Connect have spawned an enormous and exciting amount of innovation. That said, if your team is small or you have a very clear use case such as an app, the amount of reading needed to properly interface and use the correct OAuth2 methodologies is vast - even if you are only interfacing with OAuth2 servers and using OAuth2 libraries! Let's take a look at the most popular OAuth2 extensions. The list is long, not (only) to make a point, but because there are so many variations and possibilities:
This list is long, but there is an even longer list of draft and active development RFCs and specifications. Alongside these more generic specs, there are also specs for financial institutions (FAPI), governments (iGov), EAP, MODRNA, and many more.
So the question remains: do you need all this? Or should we simply solve login and move on until we actually need to address a critical need?
If we haven't convinced you yet, let's take a look at some more arguments for avoiding OAuth2 and OpenID Connect. As stated earlier, this is a recommendation and doesn't apply to valid use cases. But before you go down the OAuth2 rabbit hole you should know exactly how far it goes.
User-facing OAuth2 and OpenID Connect flows require the user to interact with a website in a browser. If you are building native apps you can not circumvent this and you will need to open the iOS or Android browser. The only way around this would be to use the disgraced OAuth2 Resource Owner Password Credentials Grant. But this grant isn't available on all platforms, will raise red flags with security auditors, and is scheduled to be removed from the specification with OAuth 2.1.
For many first-party apps this is an absolute no-go, because your users will leave the app to open a browser and sign in, breaking the user experience. However, some platforms like iOS try to improve this with better UI. Still, many product owners shy away from this practice.
If you do want to use OAuth2 for native apps, have a look at our OAuth2 for Native Apps guide.
Neither OAuth2 nor OpenID Connect are designed to manage sessions. A few years ago when I was two weeks deep into implementing Auth0, I realized that Auth0 has three different session layers which all have their own logout mechanisms! That's not because Auth0 is bad. It's because they're using a third-party protocol to solve a first-party problem! Citing from their session layer documentation
- Application Session Layer: This layer is the session inside your application. Though your application uses Auth0 to authenticate users, your application also tracks that the user has logged in to your application; in a regular web application, for example, you achieve this by storing this information inside a cookie.
- Auth0 Session Layer: Auth0 also maintains a session on the Authorization Server for the user and stores their user information inside a cookie. This layer is used so that the next time a user is redirected to Auth0 for login the user's information will be remembered. This session layer makes the SSO experience possible for inbound SSO implementations.
- Identity Provider Session Layer: When users attempt to sign in using an identity provider such as Facebook or Google, and they already have a valid sign-in (with whichever provider they choose) they won't be prompted again to sign in though they may be asked to give permission to share their information with Auth0 and, in turn, your application.
Put in pseudo-code, you get something like this:
app.get("/oauth2/callback", (req, res) => {
const { access_token, id_token } = oauth2.exchange(req.query.code)
const session = {
user_id: id_token.sub,
access_token,
}
// We still use a cookie to create the session
writeSessionCookie(session)
})
app.get("/protected/api", (req, res) => {
// Notice: we don't care about the token here!
const session = readSessionCookie(req)
const user = getUser(session.user_id)
if (!user) {
res.redirect("/login")
return
}
})
app.get("/logout", (req, res) => {
const session = readSessionCookie(req)
const user = getUser(session.user_id)
if (!user) {
res.redirect("/login")
return
}
// This is the OAuth2 session layer.
oauth2.logout(user)
// This is the application session layer.
deleteSessionCookie(req)
res.redirect("/login")
})
You might know CircleCI, it's a continuous integration platform that runs tests on your code. CircleCI needs access to your GitHub or GitLab repositories which means it uses GitHub's / GitLab's OAuth2 capabilities.
The catch is if you signed in to CircleCI via GitHub, and you log out of GitHub. You will still be signed in to CircleCI! The same applies if you use an app using "Sign in with {anything really}". With OAuth2 it doesn't matter to the third party what your session status is at the first party!
At Ory, we get (and answer) this question on a regular basis: "I have implemented OAuth2 but how do I globally sign out my users?". There is a specification for that! But it could be so much easier.
To cite from Auth0's logout documentation, there are three separate logout mechanisms when delegation protocols (OAuth2 / OpenID Connect) are involved:
- Application Session Layer Logout: Logging users out of your applications typically results in their application session being cleared, and this should be handled by your application: for the Application Session Layer, there is nothing within your Auth0 tenant that you need to use to facilitate session termination. This will require you to use whatever application session stack you are using to clear out any session-related information. Note that some of the Auth0 SDKs do provide some support for application sessions; please check the documentation to see if there is any local SDK session removal that needs to be done.
- Auth0 Session Layer Logout: You can log users out of the Auth0 session layer by redirecting them to the Auth0 Logout endpoint so Auth0 can clear the SSO cookie.
- Identity Provider Session Layer Logout: it's not necessary to log the users out of this session layer, but you can use Auth0 to force the logout if required.
Browsers have three principal ways to persist data on the client:
httpOnly).document.cookie -
vulnerable to XSS).localStorage -
vulnerable to XSS).When receiving an Access, Refresh or ID Token the question is where do you store
these? The natural place would be in the browser's httpOnly cookie! But many
applications today are client-side and don't have direct access to a web server.
Storing it in a httpOnly cookie might be the most secure variant, but it's
also the most inconvenient one!
There are several opinions and considerations to be made. We've collected a few of the most interesting discussions for further reading:
OAuth2 has strict security measures in place to mitigate attack vectors. The most common are "Token Replay" mitigations, in particular for OAuth2 Refresh Tokens and OAuth2 Authorization Codes. Token Replay mitigation means that if you use the same Refresh Token, or Authorization Code twice, the request will fail and all associated access, refresh, and authorization codes will be invalidated. This means that your user has to redo the whole OAuth2 flow from the beginning!
And unfortunately this happens quite a lot. It can be a bug in your system, or it can be two services making a request at the same time with a token that needs to be refreshed. Preventing these types of race conditions is challenging in front end applications - you will need a good side effect solution such as Redux Saga to ensure that only one API call is refreshing the token at a time. In distributed systems this becomes even more difficult!
Of course there are solutions to this problem as well, such as having a grace period - for example a few seconds where the refresh token can be reused. Yet it adds another layer of complexity and potential flakiness to your system. What happens if your system is under heavy load? Will the racy refresh requests be fast enough? What happens if things time out? Or if you need to retry? Should you deactivate token reuse detection completely? But then you might fail the security audit!
There are no clear answers to this. It takes time, research, testing, and iteration to make the right decisions.
In development we always think about building scalable systems. Yet one of the most difficult aspects of scaling a software system is the human aspect. Google invented Golang, a novel programming language to address the problems of scaling the humans that write the software, because it's as difficult to scale from 10 to 20.000 developers as it's to build a search engine which replies to any query in less than 50 ms wherever you are on the planet.
I started Ory a few years back and have since scaled it from a one-man show to a company of almost 30 people (a comparatively small number). Throughout this, I've witnessed the community grow and struggle with OAuth2 and OpenID Connect terminology, complexity, and tooling. In hindsight, it's clear that scaling development (the human side) with complex protocols is challenging since there is a high barrier for entry and a steep learning curve. What's the difference between a resource server, a resource owner, a third party client, a relying party, an ID token, the refresh token and the PKCE verifier? All of this has to be taught and understood by any new team member touching these systems. Sure, there are tons of resources out there. But which one applies to your system?
A good question to ask yourself when deciding whether or not you need OAuth2 / OpenID Connect is whether you want users to see a screen similar to the following one:

If the answer is no, you don't need OAuth2 / OpenID Connect for user authentication.
OAuth2 tokens have a scope. The scope is usually something like read:user or
profile:write. The OAuth2 scope doesn't say what a user can and cannot do.
OAuth isn't suitable for user authorization. The fact that you have an access token that allows you to act on the user’s behalf doesn't mean that the user can perform an action. Source
An access token represents that the client application has been authorized by the user. It states what a user said (consent!) a third party application can do in their name. Let's take a quick look at the OAuth2 flow:
For example:
Let's make a counterexample:
If Alice would allow myphotoapp to act as an administrator of the system and delete the production database, it would not matter unless Alice is actually a system administrator. Similarly, Alice can not allow myphotoapp access to Bob's pictures, because she isn't Bob.
I have lost count of the number of times developers have gotten this wrong. And again, it's not because people aren't skilled. it's because complex protocols have steep learning curves and ain't nobody got time to learn everything. As said before complexity kills security.
Specifications are subject to change and deprecation as any other system. RFCs and specifications aren't timeless and don't protect against breaking changes, upgrading systems, changing configurations, or deprecating specific flows. Here are some examples of deprecated specifications:
There are of course more abandoned and deprecated specifications. However, those never made it past the draft status and I therefore didn't include them. For this reason we only accept finalized RFCs and specifications to Ory Fosite and Ory Hydra!
In this section we've collected questions and statements we've seen and read over the years. We hope that our answers can help you convince your peers to go one way or the other!
OAuth2 access tokens are a subcategory of tokens. An authorization token is just a string that's used to authorize a request. It can be anything from a JSON Web Token (so-called pass-by-value tokens) to a random identifier (so-called pass-by-reference tokens). You don't need OAuth2 to issue such a token!
In particular you will find terminologies such as "Personal Access Tokens" or "API Keys" in the wild. These types of tokens aren't the result of OAuth2 flows! They use systems like Kong's Key Authentication Plugin or a simple service.
You only need OAuth2 and OpenID Connect if you'd like your users to give consent - that is "I want to allow this app access to my personal data". You don't need OAuth2 to generate a JSON Web Token, a Personal Access Token, a Native Mobile App Session Token.
At Ory, you can use Ory Session Tokens if you want to interface your API with native apps and clients which don't have a browser. We're also planning to publish a new token service which will standardize API Keys and Personal Access Tokens so that your users will be able to easily create these types of tokens in a scalable and secure way!
In conclusion: OAuth2 issues tokens. But not every token must be issued by OAuth2 to be secure.
You can use JSON Web Tokens without OAuth2. These are two different standards which can be used independently! See the section above.
In some cases, this is a valid point. If you are facing a complex landscape with hundreds of different services and integrations, it may make sense to standardize everything using OAuth2 and OpenID Connect. This is especially true if you can build a dedicated team which is responsible for training, auditing, developing, and maintaining your OAuth2 and OpenID Connect services and integration tools.
Another valid case is if you are building a platform wherein third parties need access to your system. Here too it might make sense to start using OAuth2 and OpenID Connect immediately to maintain one standard method of authentication.
If you are a small team, a start-up, or a company with a single product you will not need it unless you fall under one of the exceptions listed in this article. And if you still decide to go this route, be prepared to spend a considerable amount of time and development resources to get it right.
This is something we hear a lot from consultants! At least OAuth2 and OpenID Connect are standardized and have integrations for most programming languages.
But wouldn't it be nicer if we actually had something that:
That's exactly why we're building Ory. We want to build the next generation of authentication and authorization services. While there is still a long way to go for Ory to become a new standard, we already have a solid foundation! While you're here, maybe one of our projects will spark your interest:
Of course not! OAuth2 and OpenID Connect are extremely powerful and well-designed protocols that can, if used in the correct context, greatly improve the interoperability of systems and thus reduce complexity (which increases security).
There are many examples of these two protocols being used securely and successfully. From FireTV sticks to integrating different services (Hubspot, Google, Discourse, ...) and offering powerful tools to provide third parties access to sensitive, private information.
But it's important to keep in mind what you want to build and in what sequence. For many of the use cases that end up in Ory's community, something like Ory Kratos and Ory Network are a much better fit than trying to implement OAuth2 and OpenID Connect both on the server and client side!
And the great news is, if the need for OAuth2 and OpenID Connect arises, you can use Ory again to add these on top!
Thank you for taking the time to read this article. It's a lot, I know! I hope you learned a thing or two and, more than anything, that you now have the knowledge to start building your system without spending restless nights on things you don't need yet, figuring out all the intricate details of OAuth2 and OpenID Connect!
Do you have a different opinion on this topic or did you just enjoy the read? Write me in the Ory Community or follow me on GitHub.
Thank you for reading and see you next time!