OAuth Grant Types

Introduction

OAuth 2.0 grant types, also called authorization flows, define how a client application obtains an access token from an authorization server. This is one of the most practical OAuth topics for API testers because the same high-level OAuth framework can behave very differently depending on the client architecture. A secure server-side web application, a mobile app, a browser-based single-page application, a backend batch job, a microservice, and a smart TV do not all have the same security properties. OAuth grant types exist because different client types need different ways to request tokens safely.

A server-side web application can usually protect a client secret because the secret stays on the backend server. A mobile app cannot safely keep a client secret because the app runs on a user's device and can be inspected or reverse engineered. A single-page application runs in the browser, which means secrets cannot be hidden from the user. A backend service may not involve a human user at all. A smart TV may not have a keyboard, so asking a user to type a long password on the device would create a poor experience. OAuth 2.0 handles these differences through separate grant types.

For testers, grant types are not just theory. If the wrong flow is used, tokens may be exposed, client secrets may be leaked, scopes may be too broad, or refresh behavior may become unsafe. A test strategy for OAuth must validate not only that an access token is returned, but also whether the selected grant type matches the application, whether the required parameters are enforced, whether invalid grant requests fail correctly, and whether tokens are limited by scope, expiry, client, user, and audience.

The most common grant types are Authorization Code, Authorization Code with PKCE, Client Credentials, Resource Owner Password Credentials, Implicit, and Device Authorization. Modern systems generally prefer Authorization Code with PKCE for public clients, Authorization Code for confidential server-side clients, and Client Credentials for machine-to-machine communication. Resource Owner Password Credentials and Implicit are legacy patterns that are discouraged for new applications. Understanding why these recommendations exist helps testers evaluate API security with more depth.

What Is an OAuth Grant Type?

An OAuth grant type is the method used by a client application to request and receive an access token from the authorization server. The grant type tells the authorization server what kind of flow is being used and what evidence the client is presenting. For example, a client may present an authorization code, a client ID and secret, a device code, or user credentials in a legacy flow. The authorization server validates the request and issues a token only when the flow, client, credentials, scope, and policy are acceptable.

In simple terms, an OAuth grant type defines how an application gets an access token. The token is then used to call protected APIs, usually as a bearer token in the HTTP `Authorization` header. The grant type is about token acquisition. The later API call is about token usage. This separation matters because testers may need to validate both sides: the token endpoint that issues tokens and the resource API that accepts tokens.

Grant types are needed because OAuth is used across many kinds of applications. A backend web application can store secrets securely. A native mobile application cannot. A machine-to-machine integration does not have a user sitting in front of it. A limited-input device needs the user to authenticate somewhere else. If one token flow were forced onto all clients, some applications would either become insecure or unusable. Grant types allow OAuth to adapt to the client type.

Common OAuth 2.0 Grant Types

The following table summarizes the major grant types that testers usually encounter. The exact support depends on the authorization server, identity provider, and organization policy, but the patterns are common across real API platforms.

Grant TypeUser LoginTypical Use CaseStatus
Authorization CodeYesServer-side web applicationsRecommended for confidential clients
Authorization Code with PKCEYesMobile apps, single-page apps, desktop appsRecommended for public clients
Client CredentialsNoServer-to-server communicationRecommended for machine access
Resource Owner Password CredentialsYesLegacy trusted applicationsLegacy and discouraged
ImplicitYesOlder browser-based appsDeprecated for new applications
Device AuthorizationYesSmart TVs, consoles, IoT devicesRecommended for limited-input devices

A good OAuth design starts by selecting the flow that fits the client. A web server that can protect secrets may use Authorization Code. A mobile app should use Authorization Code with PKCE because a client secret cannot be protected on the device. A backend service with no user should use Client Credentials. A smart TV can use Device Authorization so the user completes login on a phone or laptop. A legacy trusted application may still use Resource Owner Password Credentials, but new systems should avoid it. Implicit flow should generally be replaced by Authorization Code with PKCE.

Authorization Code Grant

The Authorization Code Grant is one of the most widely used OAuth flows for confidential clients. A confidential client is an application that can safely store a client secret, usually because part of the application runs on a secure backend server. Traditional server-side web applications are a common example. The user interacts with the browser, but the sensitive token exchange happens on the backend.

In this flow, the client first redirects the user to the authorization server. The user authenticates and approves the requested scopes if consent is required. The authorization server redirects the user back to the client with an authorization code. The client backend then exchanges the authorization code for an access token by calling the token endpoint. This exchange can include the client secret because the backend can protect it.

The flow has an important security advantage: the access token is not directly exposed in the browser redirect. The browser receives only a short-lived authorization code. The backend exchanges that code for tokens through a server-to-server call. This reduces token leakage risk and allows the authorization server to validate the client secret before issuing tokens.

Authorization Code Grant is commonly used in banking websites, employee portals, enterprise web applications, admin dashboards, and backend-driven web applications. Testers should validate that authorization codes are short-lived, can be used only once, are bound to the correct client and redirect URI, fail after expiry, and cannot be exchanged with an invalid client secret. They should also validate state parameter behavior if the flow uses state to protect against cross-site request forgery.

Authorization Code with PKCE

Authorization Code with PKCE extends the Authorization Code flow for public clients. PKCE stands for Proof Key for Code Exchange. Public clients are applications that cannot safely store a client secret, such as mobile apps, desktop apps, and single-page applications. If a secret is embedded in a mobile app or browser application, users and attackers may extract it. PKCE avoids depending on a static client secret.

PKCE uses a dynamically generated code verifier and code challenge. Before starting the authorization request, the client creates a random code verifier. It derives a code challenge from that verifier and sends the challenge to the authorization server. Later, when exchanging the authorization code for tokens, the client sends the original code verifier. The authorization server verifies that the code verifier matches the earlier challenge. This protects against authorization code interception because a stolen code is not enough without the verifier.

This flow is recommended for mobile apps, single-page applications, and desktop applications. It is widely supported by modern identity providers. It allows public clients to use the safer authorization code pattern without storing a secret. For browser-based apps, it is the modern replacement for the older Implicit flow.

API testers should validate PKCE behavior carefully. A valid code verifier should allow the token exchange. A missing verifier should fail. A wrong verifier should fail. A reused authorization code should fail. An expired code should fail. A code challenge generated with one method should be validated according to the configured method. These negative tests confirm that PKCE is actually enforced rather than merely documented.

Client Credentials Grant

The Client Credentials Grant is used when no human user is involved. The client application authenticates as itself using a client ID and client secret, certificate, or another client authentication method. The authorization server issues an access token representing the client application or service. The client then uses that token to call protected APIs.

This flow is common in backend services, microservices, scheduled jobs, batch processes, internal integrations, payment services, inventory services, reporting systems, and platform APIs. For example, a payment service may call an inventory service to reserve stock. A scheduled job may call a reporting API at midnight. A backend process may call a database access service. No end user is present, so user consent and user login do not apply.

A simple token request may include `grant_type=client_credentials` and client authentication. In some systems, the client ID and secret are sent using Basic Authentication. In others, they are sent in the request body or through a private key JWT or certificate. The exact method depends on the authorization server configuration.

Testing Client Credentials Grant requires validating correct client credentials, invalid client secret, missing client secret, disabled client, unauthorized scopes, token expiry, token audience, and access to service-level APIs. Because this flow represents machine access, testers should ensure tokens do not receive user-only permissions. A service token should have only the scopes required for that service.

Resource Owner Password Credentials

Resource Owner Password Credentials, often called ROPC, is a legacy OAuth flow where the client collects the user's username and password and sends them directly to the authorization server to obtain an access token. This flow is simple, but it weakens one of OAuth's main benefits: the client application should not need to handle the user's password.

ROPC may still appear in older enterprise systems, highly trusted first-party applications, migration scenarios, or legacy integrations. However, it is discouraged for new applications. Modern systems should prefer Authorization Code with PKCE for public clients and Authorization Code for server-side web applications. Those flows keep user authentication with the identity provider and avoid teaching users to type passwords into arbitrary clients.

The security concerns are significant. If a client collects the user's password, the client can misuse it, log it accidentally, leak it through memory dumps, or become a phishing target. ROPC may also struggle with modern authentication requirements such as multi-factor authentication, passwordless login, federated identity, conditional access, and consent screens.

When testers encounter ROPC, they should validate it carefully and understand why it exists. Tests should cover valid credentials, invalid credentials, locked users, disabled users, missing parameters, invalid scopes, token expiry, and secure transport. They should also verify that credentials are not logged. If ROPC is proposed for a new public app, testers can raise the security concern and recommend a modern flow.

Implicit Grant

The Implicit Grant was historically used by browser-based JavaScript applications. In this flow, the authorization server returned an access token directly through the browser redirect without a separate authorization code exchange. This made it convenient for early single-page applications, but it exposed tokens to browser-related risks.

Implicit flow is deprecated for most new applications. Access tokens can be exposed through URL fragments, browser history, browser extensions, scripts, logs, or referrer-related behavior. It also lacks some protections available in Authorization Code with PKCE. Modern single-page applications should generally use Authorization Code with PKCE instead.

For testers, the main point is to recognize Implicit flow as legacy. If an application still uses it, tests should verify token leakage risks, redirect URI validation, state handling, token expiry, and scope enforcement. If a new system is being designed, Implicit flow should not be the default recommendation. The safer modern pattern is Authorization Code with PKCE.

Device Authorization Grant

The Device Authorization Grant is designed for devices with limited input capabilities. Smart TVs, streaming devices, game consoles, IoT devices, and command-line tools may not provide a comfortable way for users to enter usernames, passwords, MFA codes, and consent details. Instead, the device displays a code and asks the user to visit a verification URL on another device such as a phone or laptop.

A typical flow starts when the device requests a device code from the authorization server. The device displays a user code and verification URL. The user opens the URL on a phone or computer, logs in, and enters the code. The device polls the authorization server until authorization is complete. Once the user approves, the device receives an access token.

YouTube on a smart TV is a familiar example. The TV displays a code. The user enters that code on a phone or browser where login is easier. After successful authorization, the TV gains access. This is safer and more usable than typing a long password with a remote control.

Testing Device Authorization Grant includes validating valid device codes, expired device codes, invalid user codes, polling intervals, slow-down responses, denied authorization, successful token issuance, and secure display of codes. The device should not poll too aggressively. Codes should expire. Tokens should not be issued until the user completes authorization.

Grant Type Comparison

Grant TypeUser InvolvedClient SecretRefresh TokenTypical Use
Authorization CodeYesYes for confidential clientsUsuallyServer-side web apps
Authorization Code with PKCEYesNo static secret requiredUsuallyMobile apps, SPAs, desktop apps
Client CredentialsNoYes or another client auth methodTypically noMachine-to-machine APIs
ROPCYesMay be usedOptionalLegacy trusted systems
ImplicitYesNoNoDeprecated browser apps
Device AuthorizationYesDepends on client typeUsuallyTVs, consoles, limited-input devices

A practical selection rule is to start with whether a user is involved. If no user is involved, Client Credentials is usually the right flow. If a user is involved and the application is a server-side confidential client, Authorization Code is appropriate. If a user is involved and the application is a mobile app, SPA, or desktop app, Authorization Code with PKCE is the recommended choice. If the device has limited input, Device Authorization fits. ROPC and Implicit should generally be treated as legacy exceptions.

Grant Selection in Real Projects

Grant selection should be based on architecture, not convenience. A web server can store a client secret, so it can use Authorization Code. A React or Angular single-page application cannot hide a client secret, so it should not depend on one. A mobile app is distributed to user devices, so any embedded secret should be considered exposed. A backend service has no user, so user consent is irrelevant. A smart TV cannot easily collect user credentials, so Device Authorization improves usability and security.

Testers can add value by asking whether the selected grant type matches the client. If a mobile app uses a static client secret, that secret is not truly secret. If a new SPA uses Implicit flow, the team should consider Authorization Code with PKCE. If a backend service uses user-password flow for machine communication, Client Credentials may be more appropriate. These questions are not only security theory; they affect how tests are built and what risks the product carries.

Grant selection also affects test data. Authorization Code tests need redirect URIs, authorization codes, state, client secrets, and user accounts. PKCE tests need code verifier and code challenge handling. Client Credentials tests need client IDs, client secrets, scopes, and service permissions. Device Authorization tests need user codes, device codes, polling, and expiry. A single generic OAuth test is not enough for all flows.

OAuth Grant Types in API Testing

Testing OAuth grant types begins at the token endpoint. The tester should validate that the authorization server accepts correct requests and rejects incorrect requests. A valid authorization code should produce an access token. An expired authorization code should fail. A reused authorization code should fail. A wrong redirect URI should fail. A wrong client secret should fail. A missing code verifier in PKCE should fail. An invalid client credential request should fail.

After token generation, testers must validate token usage at the resource server. A token generated through the correct flow should access only allowed APIs. A token with insufficient scope should be denied. A token issued for one audience should not access another resource server. A token for one tenant should not access another tenant's data. Token expiry should be enforced. Revoked tokens should fail according to the system's revocation design.

Error responses matter. OAuth token endpoint errors often include names such as `invalid_request`, `invalid_client`, `invalid_grant`, `unauthorized_client`, `unsupported_grant_type`, or `invalid_scope`. API testers should verify that errors are correct and do not expose sensitive details. For example, invalid client authentication should not leak the real client secret or internal lookup behavior.

Example Test Cases

ScenarioExpected ResultPurpose
Valid Authorization Code exchangeAccess token returnedConfirms normal confidential-client flow
Expired Authorization Codeinvalid_grant or documented errorConfirms code expiry
Reused Authorization Codeinvalid_grant or documented errorConfirms one-time code use
PKCE exchange with wrong verifierToken request rejectedConfirms PKCE enforcement
Client Credentials with invalid secret401 Unauthorized or invalid_clientConfirms client authentication
Unsupported grant typeunsupported_grant_typeConfirms token endpoint validation
Unauthorized scope requestinvalid_scope or access deniedConfirms least privilege
Device code expiredAuthorization failsConfirms limited-input flow expiry

These tests should be designed around the actual authorization server behavior. Some providers return HTTP `400 Bad Request` for token errors. Invalid client authentication may return `401 Unauthorized`. Scope failures may return `400`, `403`, or a specific OAuth error depending on the endpoint and flow. Testers should validate against the documented contract rather than forcing one universal expectation.

REST Assured Example

REST Assured can be used to obtain a token using the Client Credentials Grant. One common pattern sends client credentials with Basic Authentication and the grant type as a form parameter:

given()
  .auth()
  .preemptive()
  .basic(clientId, clientSecret)
  .formParam("grant_type", "client_credentials")
.when()
  .post("/oauth/token")
.then()
  .statusCode(200);

After receiving the token, the test can extract it and call the protected API:

String accessToken =
  response.jsonPath().getString("access_token");

given()
  .header("Authorization", "Bearer " + accessToken)
.when()
  .get("/employees")
.then()
  .statusCode(200);

In a production-grade automation framework, token generation should be reusable but not hidden beyond understanding. Tests should clearly show whether they use client credentials, an admin user token, a read-only token, or an invalid token. Client secrets should be loaded from secure configuration and never committed to the repository.

Postman Example

Postman supports OAuth 2.0 in the Authorization tab. A tester can select OAuth 2.0, choose the grant type, configure the token URL, authorization URL if needed, client ID, client secret, scope, redirect URL, and other provider-specific values. Postman can request an access token and automatically attach it as a bearer token to API requests.

Postman is useful for exploring flows manually. Testers can compare behavior between valid and invalid scopes, valid and invalid client secrets, expired tokens, and different users. Environment variables can store client ID, token URL, base URL, and tokens. However, exported environments and shared workspaces should be handled carefully because they may expose secrets.

For grant-type testing, Postman can help reproduce token endpoint failures. A tester can change `grant_type`, remove `redirect_uri`, modify `code_verifier`, request unauthorized scopes, or send invalid credentials. The response should match the authorization server's documented behavior.

Karate Example

Karate can request a token using form fields for Client Credentials:

Given form field grant_type = 'client_credentials'
And form field client_id = clientId
And form field client_secret = clientSecret
When method POST
Then status 200

After the token is returned, Karate can store it and use it in later requests:

* def accessToken = response.access_token
Given header Authorization = 'Bearer ' + accessToken
When method GET
Then status 200

Karate is useful when OAuth setup is part of test flow because it can express API calls concisely. Teams can create reusable setup features for different token types. As with other tools, secrets should come from secure configuration. Negative scenarios should intentionally remove or alter parameters rather than accidentally inheriting valid setup.

Real-World Examples

Google APIs commonly use Authorization Code and Authorization Code with PKCE. A web application may use Authorization Code to access Google Drive or Calendar on behalf of a user. A mobile app may use Authorization Code with PKCE because it cannot protect a client secret. Scopes control whether the app can read profile data, read calendar events, or access files.

Microsoft identity platforms support flows such as Authorization Code, Client Credentials, and Device Authorization. Microsoft Graph APIs may be called with delegated user tokens or application tokens. The selected flow changes the meaning of the token and the permissions that apply. A tester must know whether a token represents a user or an application.

GitHub supports authorization flows for web applications and device authorization for command-line or limited-input scenarios. Internal microservice platforms often use Client Credentials so services can call one another without user involvement. In each example, the grant type reflects the client type and security requirement.

Best Practices

Use Authorization Code for server-side web applications that can protect client secrets. Use Authorization Code with PKCE for mobile apps, desktop apps, and browser-based single-page applications. Use Client Credentials for server-to-server communication when no user is involved. Use Device Authorization for limited-input devices. Avoid Resource Owner Password Credentials for new applications. Do not use Implicit flow for new browser apps.

Use HTTPS for all OAuth communication. Protect client secrets, refresh tokens, authorization codes, and access tokens. Request only necessary scopes. Validate redirect URIs strictly. Use short-lived access tokens. Handle refresh tokens securely. Revoke compromised tokens. Do not log tokens or secrets. Apply least privilege to both users and clients.

For testing, build flow-specific coverage. Do not assume one OAuth test proves all grant types. Validate token endpoint inputs, invalid grant requests, unsupported grant types, invalid clients, invalid scopes, expired codes, PKCE verification, device-code expiry, token usage, scope enforcement, and resource access. Security defects often appear in edge cases and negative flows.

Common Mistakes

A common mistake is using the wrong grant type for the client. A mobile app should not rely on a static client secret. A new SPA should not use Implicit flow. A machine-to-machine service should not use a user-password flow when Client Credentials fits better. Grant type selection should follow architecture and risk.

Another mistake is exposing client secrets. Client secrets belong in confidential clients, not public clients. If a secret is placed in JavaScript, mobile code, desktop application files, or public repositories, it should be considered exposed. Testers should flag this because it undermines client authentication.

Requesting excessive scopes is also common. Applications often ask for broad permissions because it is easier during development. This violates least privilege. A token should have only the access the application needs. Testers should validate that high-risk endpoints require appropriate scopes and that low-scope tokens are denied.

Ignoring token expiration and refresh behavior creates unstable applications and weak security. Tokens should expire. Clients should refresh them through the correct flow. Revoked tokens should not continue working unexpectedly. Authorization codes should be short-lived and one-time use. PKCE should be enforced for public clients.

Interview Questions

A common interview question is: what is an OAuth grant type? A strong answer is that an OAuth grant type defines how a client application obtains an access token from the authorization server. Different grant types exist because different clients, such as server-side web apps, mobile apps, SPAs, services, and devices, have different security requirements.

Another question is which grant type is recommended for server-side web applications. The answer is Authorization Code Grant, often with a client secret because the backend server can protect it. For mobile apps and SPAs, Authorization Code with PKCE is recommended because these public clients cannot safely store secrets. For machine-to-machine communication, Client Credentials Grant is used because no user is involved.

Interviewers may ask which grant types are legacy or discouraged. Resource Owner Password Credentials is discouraged for new applications because the client handles the user's password directly. Implicit Grant is deprecated for most new applications because access tokens can be exposed in the browser. Modern browser and mobile clients should use Authorization Code with PKCE instead.

For testing questions, explain that testers should validate token generation, authorization code exchange, PKCE verifier behavior, client authentication, invalid client secrets, unsupported grant types, unauthorized scopes, token expiration, refresh-token flow, invalid grants, expired codes, reused codes, and permission checks on protected APIs.

Interview-Ready Explanation

OAuth grant types are the authorization flows defined by OAuth 2.0 that describe how a client application obtains an access token from the authorization server. Different grant types exist because different applications have different security requirements. A server-side web application can protect a client secret, a mobile app or SPA cannot, a backend service may not involve a user, and a smart TV may need a login flow that happens on another device.

The main grant types are Authorization Code, Authorization Code with PKCE, Client Credentials, Resource Owner Password Credentials, Implicit, and Device Authorization. Authorization Code is used for confidential server-side web applications. Authorization Code with PKCE is recommended for public clients such as mobile apps, SPAs, and desktop applications. Client Credentials is used for machine-to-machine communication. Device Authorization is used for limited-input devices such as smart TVs. ROPC and Implicit are legacy flows that should generally be avoided in new applications.

During API testing, testers should validate access token generation, authorization code exchange, PKCE enforcement, client authentication, scope validation, token expiration, refresh-token behavior, invalid grant requests, invalid client credentials, unsupported grant types, and authorization failures on protected APIs. A secure OAuth implementation must use the right grant type for the client and enforce the rules of that grant type consistently.

Key Takeaway

OAuth grant types define how applications obtain access tokens. They exist because a web server, mobile app, browser SPA, backend service, and smart TV have different security needs. Choosing the wrong grant type can expose tokens, leak secrets, weaken access control, or create poor user experience.

For API testers, the practical rule is to test the OAuth flow that the application actually uses. Validate the token endpoint, required parameters, client authentication, PKCE rules, scopes, token expiration, refresh behavior, and negative grant scenarios. Then validate that the issued token grants only the intended API access. OAuth security depends on both correct token issuance and correct token enforcement.