OAuth authorization and scopes
Design delegated access with authorization code flow, PKCE, exact redirect checks and purpose specific scopes.
On this page
Before you start
- Registered client configuration
- A trusted authorization server
- A scope and consent model
Authorization code flow with PKCE
The browser carries the authorization code. The client proves possession of the original verifier at the token endpoint.
Scroll across the diagram to see all four systems.
Start authorization
Create state and a fresh verifier, then derive an S256 challenge.
Authorize + challenge
Use the registered redirect URI and request only the needed scopes.
Return code + state
Redirect with a short lived authorization code after the authorization decision.
Validate state
Bind the return to the request that this client initiated.
Code + verifier
Exchange the code through the token endpoint and verify the original challenge.
Access token
Call the intended resource using the granted scope and audience.
Keep authorization separate from resource access
The authorization server authenticates the user and issues an authorization grant under its policy. The client receives authority to act within a defined scope. The resource server validates the resulting access token and still checks the requested action and object.
OAuth is an authorization framework. An access token is not a generic proof of a person’s identity for every application. When the client needs authentication claims, use an appropriate identity protocol and validate its audience and issuer rather than repurposing an arbitrary access token.
Bind the code to the initiating client
Generate a fresh high entropy code verifier for each authorization request. With S256, the challenge is the unpadded base64url encoding of the SHA 256 digest of the ASCII verifier. Store the verifier in a context bound to that request and send it only during the token exchange.
RFC 9700 requires public clients to use PKCE and recommends it for confidential clients. Exact redirect matching is required except for the specified native localhost port exception. Avoid wildcard redirects and open redirectors that could forward an authorization response to an attacker.
GET /authorize?response_type=code
&client_id=marketing_portal
&redirect_uri=https%3A%2F%2Fclient.example.test%2Foauth%2Fcallback
&scope=contacts.read%20contacts.write
&state=<request_bound_random_value>
&code_challenge=<base64url_sha256_of_verifier>
&code_challenge_method=S256Name the action that authority permits
Prefer scopes that describe a resource and action, such as contacts.read, contacts.write or campaigns.publish. Separate a permission to inspect a campaign from a permission to activate it. A broad administrative scope makes a background synchronization job harder to review and revoke safely.
Scopes limit a class of actions; tenant membership and object authorization narrow the actual target. A token containing contacts.write does not authorize a write to every tenant’s contacts. Record the effective granted scope because it can differ from the requested scope.
| Control | Question it answers | Enforcement point |
|---|---|---|
| Issuer | Who issued this credential? | Token validation. |
| Audience | Which resource may accept it? | Resource API boundary. |
| Scope | Which classes of action are permitted? | Endpoint and operation policy. |
| Tenant membership | Which organizational boundary applies? | Trusted identity and membership policy. |
| Object authorization | May this principal act on this record? | Every object read or mutation. |
Rotate and revoke without creating parallel token races
Store refresh credentials in the appropriate protected client context. Coordinate refresh so concurrent workers do not unknowingly reuse a rotated credential. Detect revoked access as an authorization state requiring a new grant, not as a transient network failure.
Do not put bearer tokens in URLs, analytics events or application logs. Browser clients cannot safely retain a shared client secret. Choose a deployment pattern that fits the client type and threat model rather than disguising a public client as confidential.
Exercise the failure boundaries
Verify a changed redirect URI, mismatched state, wrong verifier, reused code, expired code, wrong audience and missing scope. Ensure a declined authorization returns the user to a useful state without silently requesting wider access.
Trace grant identity and revocation separately from customer records. A connector should expose which organization authorized it, which scopes were granted and when access must be renewed, without displaying the credential itself.
Inspect an authorization exchange
Evaluate how redirect binding, PKCE verification, code lifetime and requested scope determine an authorization exchange.
/oauth/tokenExpected outcome
Access grant issued
The code is unused, the redirect matches and the verifier proves the original challenge.
Decision path
- Bind the code to the registered client
- Compare the redirect URI
- Verify PKCE
- Consume the code atomically
- Issue the scoped grant
Input schema 4 fields
| Field | Type | Meaning |
|---|---|---|
redirect_matchesRequired | boolean | Exact registered redirect comparison result. |
verifier_matchesRequired | boolean | PKCE verification result computed by the authorization server. |
code_usedRequired | boolean | Whether the authorization code has already been consumed. |
requested_scopeRequired | array | Scopes requested by the client. |
Standards and documentation
Explore the protocol specifications and platform guidance for this topic.
Bring the contract into your operating environment.
Discuss an implementation