OAuth 2.0 Authorization Flows
OAuth 2.0 is not an authentication protocol. It’s an authorization protocol. That confusion is the root of most OAuth misuse.
What OAuth Actually Does#
OAuth lets a user grant a third-party application limited access to their account without sharing their password. The user sees a consent screen listing what the app wants to access. They approve. The app gets a token with exactly those permissions. Your password never leaves the authorization server.
The Authorization Code Flow#
The main flow for web apps: the user is redirected to the authorization server, authenticates there, and the server redirects back to your app with a short-lived authorization code. Your server exchanges that code for an access token by making a back-channel request (server to server, not through the browser). The token never appears in the URL or browser history.
PKCE (Proof Key for Code Exchange) extends this for mobile apps where there’s no client secret to protect. The app generates a random code verifier, hashes it, and sends the hash with the auth request. On exchange, it sends the original verifier. The server checks they match. This prevents code interception attacks.
Client Credentials Flow#
Service-to-service, no user involved. Service A authenticates with its client ID and secret, gets a token, calls Service B. No redirect, no consent screen, no browser. Just credentials for tokens.
At Salesforce#
Salesforce has a connected app ecosystem where third-party integrations use OAuth to access customer org data. Scope creep was a recurring issue. A connected app would request full access (every permission) because it was easier than specifying exact scopes. Customers approved it without understanding what they were granting.
When we audited integrations for a compliance review, a significant number had broader access than they needed. Narrowing scopes during re-authorization created support tickets because some integrations actually relied on permissions they shouldn’t have had. Principle of least privilege applied at the OAuth scope level matters.
What I’m Learning#
The implicit flow (where tokens came back directly in the URL fragment) is deprecated. If you’re reading old OAuth docs that recommend it, stop and use authorization code + PKCE instead.
Have you had to scope-down OAuth tokens on existing integrations without breaking them?