What’s the differences between public & confidential clients?
This article reveals the differences between public and confidential clients in OAuth, with Logto applications as example.
When using Logto to create an application, you will notice that there are several different application types to choose from, including Single Page Application (SPA), Native App, and Traditional Web App. Intuitively, from the name, it is clear that a Native App runs on operating systems commonly found on devices like phones. However, what exactly are SPA and Traditional Web App? Why do we need to distinguish between these different types of apps? This article will reveal the answers to these questions.
Before we begin, we need to provide a brief introduction to some concept.
What is OAuth?
OAuth is an open standard for access delegation, which is typically used as a way for internet users to grant websites or applications access to their information on other websites without providing their passwords.
In the recent decade, it has gradually become the standard authorization process and were widely accepted by most companies such as Google, Meta, Microsoft and so on. The currently used version is OAuth 2.0.
In the context of OAuth, the application we mentioned earlier is referred to as Client. They can make requests for protected resources, given that they have obtained the authorization of the resource owner (usually end-users).
Public clients and confidential clients
OAuth defines two client types, based on their ability to maintain the confidentiality of the client credentials.
Confidential client
A client that is capable of maintaining the confidentiality of its credentials (for example, a client implemented on a secure server with restricted access to the client credentials) or one that is capable of secure client authentication through other means.
Public client
A client that is unable to maintain the confidentiality of its credentials (for example, a client running on the resource owner's device, such as a native app or a web-based app) and is also unable to securely authenticate as a client through any other means.
SPA, native application and traditional web application
With the aforementioned background knowledge, let's take a look at what SPA, Native App, and traditional web app mean in the context of Logto, as well as whether they are considered public clients or confidential clients.
SPA
The client-side code of an SPA is downloaded from a web server and executed in the user agent (such as a web browser) of the resource owner on their device. The protocol data and credentials are easily accessible (and often visible) to the resource owner.
Native app
A native app is installed and executed on the device of the resource owner. The protocol data and credentials are accessible to the resource owner. It is generally assumed that any client authentication credentials contained within the application can be extracted.
Traditional web app
A traditional web app is a client that runs on a web server. The resource owner accesses the client through a HTML user interface presented in the user agent on their device. The client credentials as well as any access tokens issued to the client are stored on the web server and are not exposed or accessible to the resource owner.
So, we can clearly see that SPA and native app are public clients, while traditional web app is a confidential client.
You may find that when creating an SPA or native app in Logto, there is no App secret, while a traditional web app has both an App ID and an App secret. This is because the secret of a public client cannot be guaranteed to be secure.
How a client works in the OAuth authorization flow?
When developing OAuth applications, the first step is to register the client with the OAuth service provider. Client registration involves providing details about the application, such as its name and Redirect URI. Then, the OAuth service provider generates a client ID and client secret, which are considered the credentials of the application.
The client ID is considered public information and is shared with the user during the OAuth process. It is typically included in the authorization URL and visible to end-users.
On the other hand, the client secret serves as the password for the application and must be kept secret. It is used in the OAuth process to exchange the authorization code (assuming it is authorization code flow) to obtain the access token. The existence of client secrets ensures that only registered applications can complete the exchange of access tokens.
Introducing Proof Key for Code Exchange (PKCE)
As previously mentioned, the client secrets of public clients cannot be guaranteed to be secure, and attackers can obtain client credentials and impersonate clients to access protected resources, which is unacceptable in any situation.
PKCE (Proof Key for Code Exchange) solves this problem by temporarily generating a code verifier at the beginning of each authorization flow, which is stored locally and hashed to generate a code challenge that is sent to the authorization server. The code verifier is sent again to the authorization server when exchanging the access token. The authorization server verifies that the code verifier and code challenge match, which ensures that the public client has not been impersonated.
The code verifier in PKCE actually functions as a dynamic client secret. Its security is ensured by the irreversibility of the hash algorithm.
Recap
In this article, we discussed the concepts of confidential clients and public clients in OAuth. We learned that confidential clients have the ability to keep secrets and securely store sensitive information, while public clients lack this ability. We examined examples of the two types of clients, including traditional web apps, SPA, and native apps, in the context of Logto's product practices.
We also discussed the client registration process in OAuth and the roles of client ID and client secret.
Furthermore, we found that public clients face limitations in securely storing client secrets. To overcome this limitation, we introduced PKCE (Proof Key for Code Exchange), an OAuth extension that allows public clients to securely exchange authorization codes without the need for a client secret.
Our product, Logto, is a comprehensive CIAM solution that follows the best practices of the OAuth and OIDC protocols to ensure security at every stage, including the adoption of using PKCE to protect the security of public clients.