GUIDE / api
API Authentication Testing: OAuth, JWT, and API Keys
Learn API authentication testing for OAuth 2.0, JWT expiry and refresh flows, API keys vs bearer tokens, and broken authentication test cases.
API authentication testing is where many high-severity defects hide in plain sight. Teams often verify that a valid token returns 200 and stop there. Real attackers and real production incidents exploit everything around that happy path: missing auth on one admin route, JWT expiry that is never enforced, refresh tokens that live forever, API keys that grant god mode, and OAuth redirect rules that are almost correct.
This guide is a practical OAuth 2.0 API testing companion for QA engineers. You will learn how to test API keys vs bearer tokens, JWT expiry and refresh, authentication vs authorization, broken authentication test cases inspired by OWASP thinking, status code expectations, automation patterns, and common mistakes.
Authentication vs Authorization in API Testing
Keep the vocabulary sharp.
- Authentication (AuthN): Is the caller identity established and valid?
- Authorization (AuthZ): Is that identity allowed to do this action on this resource?
Examples:
- No token on
/admin/users-> authentication failure (usually 401). - Valid viewer token on
DELETE /admin/users/1-> authorization failure (usually 403). - Valid org A token on org B’s invoice -> authorization or tenancy failure (403 or 404 by design).
If your suite only checks that login returns a token, you are not done. Identity without permission checks is half a security story.
Core Credentials You Will Meet
| Credential | Typical use | Expiry | Main risks to test |
|---|---|---|---|
| API key | Service or project access | Long-lived | Leakage, rotation, over-broad access |
| Session cookie | Browser-based APIs | Session/TTL | Fixation, CSRF, insecure flags |
| Bearer access token | User/client API access | Short-lived | Replay, leakage, missing expiry checks |
| JWT access token | Stateless bearer token | Short-lived | alg issues, claim trust, kid injection |
| Refresh token | Get new access tokens | Longer-lived | Replay, theft, missing rotation |
| mTLS client cert | High trust service auth | Cert lifecycle | Weak validation, environment mixups |
Most modern product APIs use some combination of OAuth/JWT bearer tokens and API keys for server-to-server access.
How to Test API Authentication: A Baseline Matrix
For every protected endpoint family, run this baseline:
| Case | Request setup | Expected result |
|---|---|---|
| Missing credentials | No Authorization / key header | 401 |
| Malformed credentials | Bearer abc.def garbage | 401 |
| Wrong scheme | Basic where Bearer required, or reverse | 401 |
| Expired token | Valid shape, exp in past | 401 |
| Valid token, wrong audience/resource | Token for another API | 401 or 403 per design |
| Valid token, insufficient scope/role | Viewer token on write route | 403 |
| Valid token, wrong tenant resource | Cross-tenant id | 403 or 404 |
| Revoked token or logged out session | Previously valid credential | 401 |
| Valid credential | Correct token and scope | 2xx and correct body |
Add status and body assertions together. Review REST API status codes so 401 and 403 stay semantically correct in your expectations.
API Keys: Simple, Easy to Get Wrong
API keys often look like:
GET /v1/reports
X-API-Key: sk_live_123
or
GET /v1/reports?api_key=sk_live_123
What to test
- Presence enforcement: protected routes reject missing keys.
- Invalid key: random keys fail consistently.
- Revoked or rotated key: old key fails after rotation.
- Scope of key: read-only key cannot write.
- Environment isolation: staging key fails on production host.
- Transport: key over HTTP is rejected when HTTPS is required.
- Leakage surfaces: keys not returned in response bodies or logs UI.
- Rate limits: brute force of keys is throttled.
Query string keys are special hazards
Keys in query strings leak into logs, browser history, and proxies. If the product supports query string keys, test whether safer header-based usage is documented and whether logs redact secrets.
API keys vs bearer tokens
| Question | API keys | Bearer tokens |
|---|---|---|
| Represent a user session? | Rarely | Often |
| Easy fine-grained expiry? | Harder | Natural fit |
| Good for delegated user access? | Poor | Strong with OAuth |
| Rotation operational burden | High if widely distributed | Manageable with short TTL |
| Best test focus | Leakage, breadth, rotation | Expiry, scopes, refresh, replay |
JWT Testing for QA Engineers
JSON Web Tokens are common bearer tokens with three base64url segments: header, payload, signature.
Claims worth validating in tests
exp: expiration timenbf: not beforeiat: issued atiss: issueraud: audiencesub: subjectscopeorpermissions- custom tenant claims
Important rule: decoding a JWT is not verifying it. Testers should still inspect claims in test environments to design cases, while the system under test must cryptographically verify signatures.
JWT expiry and clock skew
Test plan:
- Obtain a short-lived access token in test config (for example 60 seconds).
- Call a protected endpoint successfully.
- Wait for expiry or advance test clocks if the harness allows it.
- Confirm protected endpoint now returns 401.
- Confirm error body is safe and consistent.
Also test near-boundary behavior around configured clock skew. Tokens far in the future or far in the past should not succeed.
Signature and algorithm abuse cases
Where security testing is in scope, include:
- token with altered payload and original signature -> reject
- token with
algset tononeif library might accept it -> reject - token signed with a different key -> reject
- stripped signature -> reject
- kid header pointing to unexpected key material -> reject
These are classic broken authentication cases. Even if deep crypto tests belong to security engineers, QA should confirm the obvious rejects and escalate suspicious accepts.
Never trust roles only from client-side claim edits
A frequent student mistake is to edit a JWT payload in a debugger, change "role": "admin", and expect the server to honor it without a valid signature. A correct server rejects the modified token. Your test should prove that.
OAuth 2.0 API Testing Guide
OAuth 2.0 is an authorization framework. In API testing, you usually care about how clients obtain tokens and how resource servers validate them.
Common grant types
| Grant | Typical use | Tester focus |
|---|---|---|
| Authorization Code (+ PKCE) | Web/mobile user login | Redirect URI, code reuse, PKCE enforcement |
| Client Credentials | Service to service | Client secret handling, scopes |
| Refresh Token | Renew access | Rotation, replay, revocation |
| Device Code | Input-limited devices | Polling, expiry, authorization binding |
Legacy implicit grant should be treated as deprecated in modern designs. If present, raise risk questions.
Authorization Code flow checks
- Unregistered redirect URI is rejected.
- Open redirect style tricks do not mint codes to attacker-controlled destinations.
- Authorization code is single use.
- Code expires quickly.
- PKCE
code_verifieris required when claimed by the client type. - State parameter is validated by the client app under test when applicable.
- Token endpoint authenticates confidential clients.
Client Credentials checks
- Valid client id/secret returns access token with expected scopes.
- Invalid secret fails.
- Requested scopes cannot escalate beyond client allow list.
- Token works only on intended resource server/audience.
Resource server checks
Once a token is issued:
- resource server validates signature, issuer, audience, expiry
- insufficient scope fails on protected operations
- token from another environment fails
Refresh Token Testing
Refresh flows are where many implementations get sloppy.
Positive path
- Access token expires.
- Client posts valid refresh token.
- New access token works.
- Old access token remains invalid if already expired.
Negative and abuse paths
| Case | Expected |
|---|---|
| Refresh token missing | 400/401 per design |
| Refresh token invalid | fail |
| Refresh token expired | fail |
| Refresh token reused after rotation | fail and preferably revoke family |
| Refresh after user logout/revocation | fail |
| Refresh with different client id | fail |
| Refresh grants broader scopes than original | fail |
Token family revocation after reuse detection is a strong pattern. If your product claims it, test it.
Session Cookie APIs
Not every API is pure Bearer tokens. Browser session APIs need:
Secure,HttpOnly,SameSiteattributes as designed- login session invalidation on logout
- password change invalidates old sessions if required
- CSRF defenses for cookie-authenticated state changes
- no session fixation on login
Even when a team calls it an API, cookie semantics still apply.
Broken Authentication Test Cases (OWASP-Aligned)
Use this catalog as a planning backlog.
- Protected route accessible without credentials.
- Authentication endpoints lack rate limiting.
- Password login accepts extremely weak passwords when policy says otherwise.
- Default credentials work on admin APIs.
- JWT with invalid signature accepted.
- Expired JWT accepted.
- Algorithm none accepted.
- Access token used after logout still works.
- Refresh token never expires and never rotates.
- Password reset tokens are guessable or reusable.
- Account enumeration through distinct auth error messages, if policy forbids it.
- Credential stuffing succeeds without secondary controls.
- Tokens returned in URL query parameters.
- Tokens logged in plaintext response headers displayed to support tools.
- CORS misconfiguration allows credentialed cross-origin token theft patterns for browser clients.
You do not need to run every advanced case on every sprint. Prioritize by exposure: public internet APIs first.
Designing Auth Test Data and Environments
Good auth testing needs controlled identity fixtures:
- users for each major role
- locked and disabled accounts
- users in multiple tenants if multi-tenant
- clients with different OAuth scopes
- revoked API keys
- short-lived token configuration in non-prod
Never use production secrets in QA notes, screenshots, or repositories. If a test dump captures Authorization headers, redact them in artifacts.
Automation Patterns
Setup helper
async function getAccessToken({ clientId, clientSecret, scope }) {
const res = await api.post("/oauth/token", {
form: {
grant_type: "client_credentials",
client_id: clientId,
client_secret: clientSecret,
scope,
},
});
expect(res.status).toBe(200);
expect(res.data.access_token).toBeTruthy();
return res.data.access_token;
}
Protected route checks
test("orders require auth", async () => {
const res = await api.get("/orders");
expect(res.status).toBe(401);
});
test("viewer cannot create order", async () => {
const token = await loginAs("viewer@example.com");
const res = await api.post("/orders", {
headers: { Authorization: `Bearer ${token}` },
body: { sku: "A", quantity: 1 },
});
expect(res.status).toBe(403);
});
Expiry test sketch
test("expired access token is rejected", async () => {
const token = await getShortLivedToken(); // ttl ~30s in test env
await sleep(35_000);
const res = await api.get("/me", {
headers: { Authorization: `Bearer ${token}` },
});
expect(res.status).toBe(401);
});
If waiting is too slow for unit-like pipelines, use a test-only token minting endpoint that can issue already-expired tokens in non-prod.
GraphQL and Auth
GraphQL needs the same authentication baseline plus field-level authorization cases. A valid token that can query user { id } might still be forbidden from user { ssn }.
See how to test GraphQL APIs for operation and field strategies, then apply this article’s token lifecycle tests to the GraphQL endpoint.
Contract Testing and Auth Expectations
Consumers often depend on 401 responses and WWW-Authenticate or error shapes. Include those interactions carefully in consumer contracts without hard-coding live secrets. Contract testing with Pact covers provider states and request filters for auth headers.
Observability and Incident Clues
Auth defects show up in metrics:
- sudden 401 spikes after deploy -> token validation bug or wrong issuer/audience config
- sudden 403 spikes -> role mapping bug
- refresh endpoint 5xx -> identity dependency issue
- token endpoint latency -> login and API client failures cascade
Include smoke authentication checks in release pipelines and post-deploy probes.
Common Mistakes in API Authentication Testing
Mistake 1: Happy-Path Token Only
A single “login works” test is not authentication coverage.
Mistake 2: Collapsing 401 and 403
These codes teach clients different recovery paths. Test them separately.
Mistake 3: No Expiry Coverage
If tokens never expire in test environments, you will not find missing exp checks.
Mistake 4: Ignoring Refresh and Logout
Session termination bugs keep access alive after the user believes they are done.
Mistake 5: Over-Broad Test Keys in CI
A single admin key used for every test hides authorization bugs and is operationally dangerous if leaked.
Mistake 6: Putting Secrets in Repos
Hard-coded tokens in Postman exports and test code are recurring incidents. Use secret stores and environment injection.
Mistake 7: Testing AuthZ Without Multi-Tenant Data
Same-role cross-tenant access is one of the most expensive bug classes.
Mistake 8: Assuming Gateway Auth Means Service Auth
A microservice behind a gateway may still be reachable internally without auth. Test defense in depth where architecture requires it.
Practical Workflow for a New Protected API
- Identify auth mechanisms: key, session, OAuth, JWT, mTLS.
- Document issuance, refresh, revocation, and expiry rules.
- Build role and tenant fixtures.
- Apply the baseline missing/malformed/expired/valid matrix.
- Add scope and resource authorization cases.
- Add refresh and logout cases if applicable.
- Add abuse cases: rate limits, replay, algorithm misuse where in scope.
- Automate stable checks in CI.
- Redact secrets in logs and artifacts.
- Re-test after identity provider or gateway config changes.
For broader API technique coverage, use the API testing tutorial as your foundation and treat this guide as the auth specialization.
Release Checklist
- All external protected routes deny missing credentials.
- Expired and revoked credentials fail.
- Role and scope restrictions hold for write and admin operations.
- Cross-tenant access is blocked.
- OAuth redirect URIs and client auth are enforced.
- Refresh token reuse policy works as designed.
- Error responses do not leak secrets or stack traces.
- Tokens are not issued or accepted over insecure channels.
- CI secrets are injected, not committed.
- Monitoring alerts on abnormal auth failure rates.
Environment Drift and Auth Config Bugs
A large share of auth incidents are configuration defects, not code defects:
- wrong issuer URL in a new region
- audience value mismatch after API gateway migration
- clock skew between services validating JWTs
- staging keys deployed to production by mistake
- CORS origins updated for the web app but not the admin app
Add config-level checks to release plans:
- Decode a newly issued token and verify
iss,aud, andexppolicy. - Hit one protected endpoint in each critical environment after deploy.
- Confirm old environment tokens fail in the new environment.
- Verify JWKS or public key endpoints are reachable and cache correctly.
Treat auth config as testable product behavior, not invisible infrastructure.
Token Storage Guidance for Client Teams
QA often reviews mobile and web clients as well as APIs. Auth quality includes how clients store credentials.
Review questions:
- Are refresh tokens stored in secure platform storage, not logs or screenshots?
- Do SPAs avoid localStorage for long-lived secrets when a better pattern exists?
- Are tokens redacted in client-side error reporting tools?
- Does the client clear credentials on logout and account switch?
- Are deep links prevented from embedding access tokens in URLs?
Even a perfect API can be undermined by careless client storage. Include at least a lightweight client auth hygiene checklist in release reviews.
Multi-Tenant Authorization Scenarios
Authentication bugs are serious. Multi-tenant authorization bugs are often worse because valid users receive other customers’ data.
Minimum tenant cases:
- User in Tenant A requests Tenant B resource by id.
- User with membership in two tenants calls an endpoint without tenant context.
- API key for Tenant A is used with Tenant B identifiers in the body.
- Search and list endpoints never return cross-tenant hits.
- Webhooks and exports are scoped to the correct tenant.
- Support admin break-glass access is audited if it exists.
Decide whether cross-tenant probes return 403 or 404, document the choice, and test it consistently. Inconsistent responses can themselves aid enumeration.
Service-to-Service Auth and Internal Routes
Modern systems often have:
- public API auth for customers
- internal service auth for mesh or gateway traffic
- admin debug routes that should never be public
Tester questions:
- Can the public hostname reach internal-only routes?
- Do internal tokens work on external gateways unintentionally?
- Are mTLS or internal JWT issuers validated in every environment?
- Do “temporary” auth bypass headers exist outside local dev?
Defense in depth matters. A gateway check is not always the same as a service check.
Password and Recovery Flows Adjacent to APIs
Even API-first products often expose auth lifecycle endpoints:
- register
- login
- refresh
- logout
- password reset request
- password reset confirm
- MFA challenge and verify
Test them as a system:
- reset tokens expire and are single use
- reset does not confirm whether an email exists if that is the policy
- MFA cannot be skipped by calling a later endpoint directly
- logout invalidates refresh tokens
- concurrent login limits behave as designed
These flows are classic broken authentication territory because they combine usability pressure with security controls.
Evidence Standards for Auth Defects
When you file an auth defect, include:
- exact endpoint and method
- credential class used (none, expired JWT, wrong role, other tenant)
- expected status and policy basis
- actual status and body
- whether data leaked, not only whether status was wrong
- reproduction reliability
- impact statement (account takeover, data exposure, privilege escalation)
A report that only says “auth is broken” is hard to prioritize. A report that says “viewer token can DELETE /admin/users/{id} and the user is removed” gets action.
Final Takeaways
API authentication testing is more than proving that a valid bearer token returns data. It is a disciplined exploration of identity lifecycle, failure modes, and permission boundaries. The highest value defects are often negative-path defects: the request that should have been rejected but was not.
Build a reusable matrix for keys, JWTs, and OAuth grants. Separate authentication failures from authorization failures. Add multi-tenant and internal-route cases deliberately. Automate the stable checks, and keep a short exploratory charter for every identity change.
If you want structured practice on API scenarios that include auth judgment calls, join QABattle or jump into an API challenge from the battle arena and force yourself to predict 401 vs 403 before you send the request.
FAQ
Questions testers ask
How do you test API authentication?
Test API authentication by verifying protected endpoints reject missing, malformed, expired, and wrong-type credentials, while valid credentials grant only the intended access. Cover token issuance, storage assumptions, refresh flows, logout or revocation, role and scope enforcement, and error responses that do not leak sensitive details.
How do you test JWT token expiry and refresh?
Capture a JWT, decode claims without trusting them blindly, wait for or manipulate expiry in a test environment, and confirm protected calls return 401 after expiry. Then exercise the refresh token flow: valid refresh succeeds, reused or revoked refresh fails, and new access tokens do not inherit excessive privileges.
What is the difference between authentication and authorization testing?
Authentication testing checks whether the system correctly establishes identity: login, tokens, keys, sessions. Authorization testing checks whether that identity is allowed to perform an action or access a resource. A user can authenticate successfully and still be denied by authorization rules such as roles, scopes, or tenancy.
How do you test OAuth 2.0 APIs?
Map the grant type your product uses, then test authorize and token endpoints, redirect URI validation, client authentication, scope grants, consent where applicable, token use on resource servers, refresh, and revocation. Negative tests for open redirects, scope escalation, and token substitution are essential.
What is the difference between API keys and bearer tokens?
API keys are usually long-lived static secrets identifying a client or project. Bearer tokens, often OAuth access tokens or JWTs, are typically short-lived credentials representing a user or client session with scopes and expiry. Keys are simple but harder to rotate per user action. Tokens are better for least privilege and expiry.
What are common broken authentication test cases?
Common cases include missing auth on protected routes, weak password or token rules, JWT alg confusion or unsigned tokens accepted, refresh token replay, session fixation, credential stuffing without rate limits, insecure token storage guidance, and predictable reset flows. Align cases with OWASP Authentication failures guidance.
RELATED GUIDES
Continue the route
REST API Status Codes: The Complete Reference for Testers
Master REST API status codes with a complete tester cheat sheet for 2xx, 4xx, and 5xx responses, error validation, and practical test design.
API Testing Tutorial: A Beginner's Complete Guide
API testing tutorial for beginners: learn REST API checks, CRUD test cases, tools, status codes, and a practical checklist for reliable API quality.
How to Test GraphQL APIs
Learn how to test GraphQL APIs: queries, mutations, schema validation, error handling, Postman tips, subscriptions, and introspection risks.
Contract Testing with Pact: Consumer-Driven Contracts
Learn contract testing with Pact, consumer-driven contracts, provider verification, Pact Broker flow, and how it differs from Postman and integration tests.