Choosing an OAuth App Type: Confidential vs. Public Apps and Client Secrets
Updated
by Helpdocs Admin
When registering an OAuth app, you choose whether it's confidential or public via the client authentication setting. This determines whether the app is required to provide a client secret when exchanging tokens.
Confidential vs. public
- Confidential apps are expected to hold a client secret securely — typically server-side applications where the secret never reaches an end user's browser or device.
- Public apps are apps that can't reliably keep a secret safe — for example, code running in a browser, where anyone could inspect it.
That said, whether a public app can actually skip the secret depends on more than just this one setting. Tokity's OAuth Global Settings control whether secret-less authentication is allowed at all, separately for three scenarios: system-wide, TECH portal (agents), and client portal (contacts). The rule is:
- If the relevant global setting allows secret-less auth, then an app's
isConfidentialsetting decides whether that specific app still requires a secret. - If the relevant global setting doesn't allow secret-less auth, a client secret is always required, regardless of what the app's own setting says.
In other words, marking an app as "public" only has an effect if the global setting for that scenario permits it. We cover the global setting itself in OAuth Global Settings.
Why confidential apps are generally recommended
Public apps exist mainly for historical and edge-case reasons, and the industry trend has been moving away from them — not just at Tokity. With OAuth 2.1 removing the implicit flow entirely, the expectation across the OAuth ecosystem is that integrations use the authorization code flow, with a server-side component responsible for holding secrets and refresh tokens securely.
In practice, this means:
- Your integration's backend/server should be the one exchanging authorization codes for tokens, storing refresh tokens, and holding the client secret (if confidential) or managing PKCE (if public).
- Your frontend (browser-based UI) shouldn't be doing this exchange directly, and shouldn't be using an OAuth access token as its own session mechanism. If your frontend needs to authenticate users, it should use its own session/cookie-based auth, separate from the OAuth tokens used to call Tokity's API.
Given this, confidential apps with a server-side component are the recommended approach for most integrations. Public apps remain available for cases where that's genuinely not possible, but they carry more inherent risk, and Tokity's direction — in line with the broader OAuth ecosystem — is to treat them as the exception rather than the default.
PKCE
Regardless of confidential or public, PKCE is required on every request — this isn't tied to the confidential/public setting at all. See Code Authorization Flow for how PKCE fits into the flow.
DPoP
DPoP (Demonstration of Proof-of-Possession) is an OAuth extension that binds a token to a specific cryptographic key held by the client, rather than treating it as a plain "bearer" credential. In practice, this means that even if a DPoP-bound access token were somehow intercepted, it can't be replayed by an attacker who doesn't also possess the matching private key. For the full technical definition, see RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP).
Each app registration also has a "Require DPoP" option. Unlike PKCE, this isn't a standard enforcement flag defined in OAuth discovery metadata — it's specific to Tokity.
In practice, most OAuth libraries and off-the-shelf integrations don't implement DPoP, so enabling this on an app effectively locks it down to callers that specifically support DPoP-bound tokens. This makes it most useful for internal integrations where you control both ends and know DPoP is implemented — rather than something you'd typically enable for a general third-party integration.
What a client secret protects
A client secret (or DPoP, if enabled) exists to prevent someone other than your application from using its identity to request or use tokens. If an app's client secret leaks — for example, through a compromised redirect URL that lets an attacker intercept traffic — that attacker can act as the application itself: accessing anything already granted to it, and potentially prompting users to grant it further access, since as far as Tokity can tell, it is the application making the request.
Personal secrets
Alongside app-level client secrets, Tokity also supports personal secrets — covered in detail in Personal Secrets Explained. A personal secret is still a client secret in how it's used, but it's scoped to a specific person's grant on a specific app — it isn't a general-purpose credential a person can reuse across apps; a new one is created per app, per person.
This narrower scope is a security advantage: if a personal secret leaks, the exposure is limited to that one person's access on that one app — not the application as a whole, and not any other user. That's a meaningfully smaller blast radius than an app-level secret leaking, which exposes everything the application itself has been granted, system-wide setups included.
What's next
See Personal Secrets Explained for how personal secrets work in more detail, and OAuth Global Settings for how the system-wide, TECH portal, and client portal secret-less settings are configured.