Browse documentation

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.

Authorization code flow with PKCEStep 1: Client application to Browser. Start authorization. Step 2: Browser to Authorization server. Authorize + challenge. Step 3: Authorization server to Browser. Return code + state. Step 4: Browser to Client application. Validate state. Step 5: Client application to Authorization server. Code + verifier. Step 6: Client application to Resource API. Access token.BrowserClient applicationAuthorization serverResource APIStart authorization1Authorize + challenge2Return code + state3Validate state4Code + verifier5Access token6

Scroll across the diagram to see all four systems.

Inspect each exchange

Start authorization

Create state and a fresh verifier, then derive an S256 challenge.

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.

Authorization request parametershttp
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=S256

Name 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.

ControlQuestion it answersEnforcement point
IssuerWho issued this credential?Token validation.
AudienceWhich resource may accept it?Resource API boundary.
ScopeWhich classes of action are permitted?Endpoint and operation policy.
Tenant membershipWhich organizational boundary applies?Trusted identity and membership policy.
Object authorizationMay 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.

POST/oauth/token

Contract inputs

Includes request values and the server validation context defined below.

Expected outcome

HTTP 200

Access grant issued

The code is unused, the redirect matches and the verifier proves the original challenge.

{
  "token_type": "Bearer",
  "scope": "contacts.read",
  "access_token": "<access_token>",
  "expires_in": 3600
}

Decision path

  1. Bind the code to the registered client
  2. Compare the redirect URI
  3. Verify PKCE
  4. Consume the code atomically
  5. Issue the scoped grant
Input schema 4 fields
FieldTypeMeaning
redirect_matchesRequiredbooleanExact registered redirect comparison result.
verifier_matchesRequiredbooleanPKCE verification result computed by the authorization server.
code_usedRequiredbooleanWhether the authorization code has already been consumed.
requested_scopeRequiredarrayScopes requested by the client.
Download JSON Schema

Standards and documentation

Explore the protocol specifications and platform guidance for this topic.

Bring the contract into your operating environment.

Discuss an implementation

Image preview