# Introducing support for public PKCE OAuth for native and client-side apps Security has always been foundational to OAuth integrations. As more developers build native mobile apps, JavaScript single-page applications (SPAs), and SDK-based integrations, one architectural challenge consistently arises: these applications cannot securely store a client secret. To address this, Zoom now supports the public Proof Key for Code Exchange (PKCE) OAuth flow. Public PKCE enables applications that cannot protect a client secret to securely obtain OAuth access tokens—without embedding sensitive credentials in client-side code. If you’re building a mobile app, a desktop native integration, or a browser-based experience, this update provides a secure, standards-based way to authenticate. ## Why public PKCE matters Traditional OAuth implementations assume a confidential client—an application with a secure backend capable of storing a client secret. During token exchange, the backend authenticates using that secret. However, public applications operate differently: - Native and mobile apps run on user devices - SPAs execute entirely in the browser In these environments, storing a client secret would expose it to end users. That creates a security risk and violates OAuth best practices. Public PKCE solves this by removing the requirement for a client secret and instead relying on: - A dynamically generated `code_challenge` - A securely stored `code_verifier` - Explicit user authorization No embedded secrets. No hidden credentials. ## How public PKCE works in Zoom When you enable the "public client" option in the Zoom App Marketplace, Zoom generates an additional public client ID for your app. This public client ID: - Does not have an associated client secret - Does not require an authorization header during token exchange - Is intended for client-side or native implementations The flow still uses the OAuth Authorization Code grant with PKCE. The difference lies in how the token exchange is secured. Instead of authenticating with `client_secret`, the application proves legitimacy using the PKCE `code_verifier`. ## Public PKCE vs. confidential PKCE: what’s the difference? Zoom now supports both confidential and public PKCE configurations, allowing you to choose based on your application architecture. Both use the Authorization Code flow with PKCE. The distinction is whether your application has a backend server or can securely store and send a client secret. ### Confidential client (PKCE with client secret) This model is designed for applications that can securely store and send a client secret, or that have a secure backend server. ![Example confidential client with a backend server diagram.](/img/blog/dontesmall/public-pkce-blog/confidential-client.png) > 📘 > This flow uses a confidential client with a backend server. The server handles the authorization request, securely stores the `code_verifier`, and performs the token exchange using both the `client_secret` and `code_verifier`. The client secret is never exposed to the user environment. During token exchange: - The backend includes an Authorization: Basic base64(`client_id:client_secret`) header - The request includes: - `client_id` - `client_secret` - `code_verifier` This approach is ideal for: - Server-side web applications - Enterprise integrations - Centralized backend systems The client secret remains securely stored on the server and is never exposed. ### Public client (public PKCE) This model is designed for applications that cannot securely store and send a client secret, or that do not have a secure backend server. ![Example public client with no backend or client secret diagram.](/img/blog/dontesmall/public-pkce-blog/public-client.png) > 📘 > This flow uses a public client with no backend or client secret. The client generates the `code_verifier` and performs the token exchange directly using the `client_id` and `code_verifier`. Security relies on PKCE and user authorization, with no embedded credentials. When enabled: - Zoom generates a development and production public client ID - No client secret is required - No authorization header is required during token exchange The token request includes: - `client_id` - `code_verifier` Security is enforced through PKCE and explicit user authorization. This configuration is ideal for: - Native and mobile applications - JavaScript SPAs - SDK-based integrations Because no secret exists, there is nothing to protect within client-side code. ## OAuth flow comparison at a glance The table below summarizes the differences across supported OAuth configurations: | Feature | Traditional OAuth | PKCE (confidential) | Public PKCE | | ----------------------- | -------------------- | -------------------------------------- | ------------------------------------------------------ | | Client type | Confidential | Confidential | Public | | Client secret required | Yes | Yes | No | | Backend required | Yes | Yes | No | | Authorization header | Required | Required | Not used | | Uses `code_verifier` | No | Yes | Yes | | Token exchange location | Server | Server | Client | | Best for | Server-side web apps | Apps with a backend for added security | Mobile, native, and SPA applications without a backend | This flexibility allows a single Marketplace app to support both backend-driven and fully client-side implementations. ## Enabling public PKCE in the Zoom App Marketplace All OAuth apps receive a development and production client ID and client secret by default. When you enable the Public client option: - Zoom generates an additional development and production public client ID - No secret is issued for this ID - You can use it exclusively for public PKCE flows This allows you to support both confidential and public architectures within a single app configuration. ## SDK support for native integrations For mobile and native SDK integrations, Zoom introduced the publicAppKey property on ZoomSDKAuthContext. When building a public application: - A signed JWT is not required - Use the Public Client ID as the publicAppKey This enables secure SDK authentication without embedding a client secret. ## Build securely for modern application architectures Public PKCE support reflects the evolution of modern application design. As more integrations move toward client-side and distributed environments, secure OAuth flows must adapt. With support for both confidential and public PKCE clients, Zoom provides the flexibility to build securely—whether your application runs on a server, in a browser, or on a user’s device. If you're developing a mobile app, SPA, Zoom App, or SDK integration, public PKCE helps you authenticate securely without compromising credentials.