logo

Choosing the Right Client Type: Client Credentials vs. PKCE

When configuring a client in Entrypage, you have three options:

This article covers the following topics:

  • How to choose
  • Common application architectures

Choosing a client-type

Web applications can be either monolithic or composed of multiple components (such as a frontend, backend, and API). We refer to each of these components as an artifact.

Entrypage is designed with the principle that each artifact should have its own client configuration. Whether your application consists of a single artifact or multiple, each part that interacts with Entrypage must be registered as a separate client.

Each artifact operates in its own context and may require different levels of trust and access. For example, a Single-Page Application runs in the browser, on an untrusted client device. Its access should be limited accordingly. That same product might also include a backend API, running in a secure server environment. Because of its trusted context, the API may require broader permissions and must be configured as such.

To determine the correct client type for your application, follow these steps:

  • Create a diagram that clearly outlines all application artifacts.
  • For each artifact, use the flowchart below to identify the appropriate client type:
Choosing a client-type

Machine-to-Machine vs. Human-to-Machine Communication

The PKCE and Client Credentials flows serve distinct purposes in OAuth-based systems. The Client Credentials flow is primarily used for machine-to-machine communication, while the PKCE flow is designed for scenarios involving human users interacting with an application.

Machine-to-machine communication typically includes:

  • API-to-API interactions
  • Background services or daemons communicating with APIs

In contrast to the Client Credentials flow, the PKCE flow is intended for scenarios where a human user needs to authenticate. PKCE involves redirecting the user to a login interface where they actively sign in. The Client Credentials flow does not involve user interaction or any user interface. It is used exclusively for authentication between trusted services or systems.

Human-to-machine communication typically includes:

  • Signing into a website
  • Signing into an application

Due to the distinct purposes of the Client Credentials and PKCE flows, the initial consideration is whether the artifact involves human interaction. In most cases, if the artifact does not interact with users, the Client Credentials flow is appropriate.

To use a client_secret or not

The next question to consider is whether it is appropriate to use a client_secret.

A client_secret helps ensure that tokens are issued only to trusted machines. The key consideration is: can the machine running the artifact be trusted to securely store secrets?

By "trusted," we mean whether it is safe to store sensitive information on the machine. Situations that are generally considered unsafe include:

  • Machines you do not own or control
  • Shared or multi-tenant environments
  • Other environments where secret storage cannot be guaranteed

Machines that commonly are trusted with client_secrets include:

  • Dedicated web servers
  • Cloud-hosted Docker containers
  • Other managed environments under your control

Typical Use-Cases

OAuth is an abstract protocol. This can make it difficult to translate it into concrete implementations. Whether an implementation is correct or not heavily depends on the context.

However, to give you a general idea on how to approach choosing the correct client-type, this article includes a number of typical architectures:

Choosing The Correct Client-Type For A SPA with SSR

Many modern websites use Server-Side Rendering (SSR) to deliver an initial HTML page that hosts a Single-Page Application (SPA). Once loaded, the SPA takes over and handles client-side interactions. The SPA typically communicates with a dedicated backend API to perform its operations.

This architecture is illustrated in the following diagram:

Architectural diagram of a SSR-hosted SPA

This diagram depicts the following artifacts:

  1. An authorization-server (e.g. Entrypage, KeyCloak, Entra ID, or similar.)
  2. A Single-Page Application (e.g. Angular, React, Vue, etc.)
  3. SSR (Angular, Next.js, ASP.NET Core, Laravel, Wordpress, etc.)
  4. A app-facing API (typically a REST-api)
  5. A downstream API (e.g. internal back-office system, or a SaaS-api)
  6. Another downstream API

All of these services need to be configured differently. However, how it's configured depends heavily on a number of choices that are made. Assume all artifacts use token-based authentication and authorization, then the situation would be the following:

  1. The SPA uses PKCE without client_secret. It interacts with the user and asks the user to authenticate. Furthermore, it runs on an untrusted device, being the browser on the end-user's computer. Hence, client credentials isn't appropriate here, and using a client_secret isn't either.
  2. The SSR uses a confidential client flow with a client_secret. It is recommended to use a confidential client flow with a client_secret and with PKCE. Assuming users sign in to the server-side application, it is a separate client that can be entrusted with a client_secret. It runs in an environment that is typically managed by the company that runs the site.
  3. The consumer-facing API uses client_credentials. It does not interact with users. Instead, the SPA interacts with the API on behalf of the users. To be able to process this authentication, the API does not need to be a client. However, the API communicates with upstream APIs and those require authorization. This is machine-to-machine communication, and this does require the API to be a client.
  4. The upstream APIs are not clients. They are receiving token-based HTTP requests from the consumer-facing API. To process these, they need access to public endpoints of the authorization-server to validate the authenticity of the requests.

Choosing the Correct Client Type for a BFF

Another common approach to authentication is the backend-for-frontend architecture, as depicted in the following diagram:

A backend-for-frontend architecture

In this situation, there is a website that hosts static content (e.g. articles), pages that host Single-Page Applications (SPA), and API endpoints.

In this scenario, users authenticate to the BFF. The SPA itself remains stateless. As such, this is configured in Entrypage as follows:

  1. The SPA is not a client. End-users do not authenticate to it.
  2. The BFF uses a confidential client flow with a client_secret. It is recommended to use a confidential client flow with both a client_secret and PKCE. Users sign in to the server-side application, which is a separate client that can be entrusted with a client_secret. It runs in an environment typically managed by the company that operates the site.
  3. The upstream APIs are not clients. They receive token-based HTTP requests from the consumer-facing API. To process these, they need access to the authorization server's public endpoints to validate the authenticity of the requests.

Choosing the Correct Client Type for a Console App

Clients are not always web applications. Another common use case is a background worker or console application that interacts with an API, as shown in this diagram:

A console app interacting with an API

This architecture is quite straightforward:

  1. The worker process uses the Client Credentials flow. Since it does not act on behalf of a user but runs as a background process, this is considered machine-to-machine communication.
  2. The API is not a client. It receives the token and validates it, but does not act on behalf of any user or client.

Conclusion

Choosing the appropriate client type depends on the nature of the application and its communication patterns. Each client type is designed for a specific scenario. To make the right choice, consider how your components interact, whether the communication is initiated by a user, a machine, or a service.

* Disclaimer: This text describes typical cases and is intended as general guidance. Your specific environment may differ. We cannot accept responsibility for any misconfiguration resulting from this guidance. For certainty, please consult a professional

Albert Starreveld

Written by: Albert Starreveld

IAM Architect / Cloud Architect / Founder @ Entrypage.io

Published on: 26-05-2025