OAuth 2.0 Client Secrets Explained
OAuth 2.0 is the authorization framework behind "Sign in with Google," GitHub integrations, Stripe Connect, and thousands of other integrations. At the center of every OAuth integration is a pair of values: a client ID and, for server-side apps, a client secret. Understanding what each one is — and which one you must protect — prevents a category of credential leaks that are surprisingly common.
OAuth 2.0 in brief
OAuth 2.0 lets a user grant your application limited access to their account on another service without giving you their password. The flow involves three parties:
- Resource owner — the user who owns the data.
- Authorization server — the service that authenticates the user and issues tokens (e.g., Google, GitHub).
- Client — your application, which requests access on the user's behalf.
When you register your application with an authorization server, you receive a client ID and, depending on your application type, a client secret.
Client ID vs client secret
The client ID is a public identifier for your application. It appears in authorization URLs and is visible in browser address bars, front-end source code, and network logs. Treat it like a username — it identifies you but does not authenticate you.
The client secret is a credential that proves your application is who it claims to be. It is used during token exchange on your server. Treat it like a password — it must never appear in client-side code, mobile binaries, browser extensions, or public repositories.
Confidential vs public clients
OAuth 2.0 distinguishes between two client types based on whether they can keep a secret:
- Confidential clients — server-side web apps and backend services that can securely store a client secret. The secret stays on the server and is never exposed to users or browsers.
- Public clients — single-page apps, mobile apps, and desktop apps whose code is distributed to end users. These cannot keep a secret; any secret embedded in them can be extracted. Public clients use PKCE (Proof Key for Code Exchange) instead of a client secret to secure the authorization code flow.
Which flows use client secrets
Client secrets are required for the token exchange in the Authorization Code flow for confidential clients. When the authorization server redirects back to your server with an authorization code, your server exchanges that code for tokens by posting the code along with the client secret to the token endpoint. The secret is what proves the request came from your server, not someone who intercepted the code.
The Client Credentials flow — used for machine-to-machine API access where there is no user — also requires a client secret. Your service authenticates directly to the authorization server using its client ID and secret, and receives an access token.
The deprecated Implicit flow and the PKCE-based Authorization Code flow for public clients do not use client secrets.
Keeping the client secret safe
- Never put it in front-end code. JavaScript loaded by a browser is readable by anyone; React apps, SPAs, and browser extensions must not contain a client secret.
- Never commit it to source control. Use environment variables or a secret manager and add
.envto.gitignore. - Scope the secret. Configure OAuth scopes to request only the permissions your integration actually needs.
- Use PKCE for public clients. If you are building a mobile or single-page app, register it as a public client and implement PKCE instead of trying to hide a secret in the bundle.
- Rotate after exposure. If a secret is ever committed to a public repo, logged, or otherwise exposed, invalidate it immediately and generate a new one from the authorization server's dashboard.
Rotating client secrets
Most authorization servers let you generate a new client secret without changing the client ID. The rotation process is: generate a new secret, update your application's environment, deploy, then delete the old secret. Some platforms support a grace period where both old and new secrets are valid simultaneously, which allows zero-downtime rotation across multiple instances.
Build rotation into your runbook and treat any exposure — including a secret appearing in an error log — as a trigger for immediate rotation.
Need a strong client secret? Generate a cryptographically random secret in your browser — nothing leaves your machine.
Open the key generator