Public / confidential is permanent on an OAuth client.
Why this exists
OAuth distinguishes public clients (browsers, mobile apps, CLIs that cannot keep a secret) from confidential clients (server-side apps that can). The two have different security postures: confidential clients use a client secret; public clients use PKCE. A token issued to a confidential client carries different trust than one issued to a public client.
Letting an existing client flip from confidential → public would either silently strip its secret authentication (security regression) or leave the secret in place but not enforced (audit confusion). Letting it flip the other way would mint a fresh secret on a client that previously didn't need one — same problem in reverse.
What "rotate the secret" does NOT do
Rotating the secret on a confidential client invalidates the prior secret and issues a new one. It does not change the client's public/confidential setting. The rotation surface is for credential hygiene, not for changing client posture.
What to do instead
- Register a new client with the desired posture. Each client gets its own client_id; the new client is independent of the old one.
- Migrate your application to the new client_id (and, for confidential, the new secret).
- Revoke the old client once your application is deployed against the new one. Revocation is on the same Settings → OAuth clients page.
If you're building both a server backend and a mobile app, you typically want two clients: one confidential for the server, one public for the app. That's the canonical OAuth pattern.
Related codes
- E-client_is_public — fires when you try to rotate the secret on a public client (which has no secret to rotate). Same root cause: public clients are PKCE-only.