Back to guides

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.

By The Testing AcademyPublished July 9, 2026Updated July 9, 202616 min read

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

CredentialTypical useExpiryMain risks to test
API keyService or project accessLong-livedLeakage, rotation, over-broad access
Session cookieBrowser-based APIsSession/TTLFixation, CSRF, insecure flags
Bearer access tokenUser/client API accessShort-livedReplay, leakage, missing expiry checks
JWT access tokenStateless bearer tokenShort-livedalg issues, claim trust, kid injection
Refresh tokenGet new access tokensLonger-livedReplay, theft, missing rotation
mTLS client certHigh trust service authCert lifecycleWeak 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:

CaseRequest setupExpected result
Missing credentialsNo Authorization / key header401
Malformed credentialsBearer abc.def garbage401
Wrong schemeBasic where Bearer required, or reverse401
Expired tokenValid shape, exp in past401
Valid token, wrong audience/resourceToken for another API401 or 403 per design
Valid token, insufficient scope/roleViewer token on write route403
Valid token, wrong tenant resourceCross-tenant id403 or 404
Revoked token or logged out sessionPreviously valid credential401
Valid credentialCorrect token and scope2xx 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

  1. Presence enforcement: protected routes reject missing keys.
  2. Invalid key: random keys fail consistently.
  3. Revoked or rotated key: old key fails after rotation.
  4. Scope of key: read-only key cannot write.
  5. Environment isolation: staging key fails on production host.
  6. Transport: key over HTTP is rejected when HTTPS is required.
  7. Leakage surfaces: keys not returned in response bodies or logs UI.
  8. 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

QuestionAPI keysBearer tokens
Represent a user session?RarelyOften
Easy fine-grained expiry?HarderNatural fit
Good for delegated user access?PoorStrong with OAuth
Rotation operational burdenHigh if widely distributedManageable with short TTL
Best test focusLeakage, breadth, rotationExpiry, 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 time
  • nbf: not before
  • iat: issued at
  • iss: issuer
  • aud: audience
  • sub: subject
  • scope or permissions
  • 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:

  1. Obtain a short-lived access token in test config (for example 60 seconds).
  2. Call a protected endpoint successfully.
  3. Wait for expiry or advance test clocks if the harness allows it.
  4. Confirm protected endpoint now returns 401.
  5. 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 alg set to none if 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

GrantTypical useTester focus
Authorization Code (+ PKCE)Web/mobile user loginRedirect URI, code reuse, PKCE enforcement
Client CredentialsService to serviceClient secret handling, scopes
Refresh TokenRenew accessRotation, replay, revocation
Device CodeInput-limited devicesPolling, expiry, authorization binding

Legacy implicit grant should be treated as deprecated in modern designs. If present, raise risk questions.

Authorization Code flow checks

  1. Unregistered redirect URI is rejected.
  2. Open redirect style tricks do not mint codes to attacker-controlled destinations.
  3. Authorization code is single use.
  4. Code expires quickly.
  5. PKCE code_verifier is required when claimed by the client type.
  6. State parameter is validated by the client app under test when applicable.
  7. Token endpoint authenticates confidential clients.

Client Credentials checks

  1. Valid client id/secret returns access token with expected scopes.
  2. Invalid secret fails.
  3. Requested scopes cannot escalate beyond client allow list.
  4. 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

  1. Access token expires.
  2. Client posts valid refresh token.
  3. New access token works.
  4. Old access token remains invalid if already expired.

Negative and abuse paths

CaseExpected
Refresh token missing400/401 per design
Refresh token invalidfail
Refresh token expiredfail
Refresh token reused after rotationfail and preferably revoke family
Refresh after user logout/revocationfail
Refresh with different client idfail
Refresh grants broader scopes than originalfail

Token family revocation after reuse detection is a strong pattern. If your product claims it, test it.

Not every API is pure Bearer tokens. Browser session APIs need:

  • Secure, HttpOnly, SameSite attributes 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.

  1. Protected route accessible without credentials.
  2. Authentication endpoints lack rate limiting.
  3. Password login accepts extremely weak passwords when policy says otherwise.
  4. Default credentials work on admin APIs.
  5. JWT with invalid signature accepted.
  6. Expired JWT accepted.
  7. Algorithm none accepted.
  8. Access token used after logout still works.
  9. Refresh token never expires and never rotates.
  10. Password reset tokens are guessable or reusable.
  11. Account enumeration through distinct auth error messages, if policy forbids it.
  12. Credential stuffing succeeds without secondary controls.
  13. Tokens returned in URL query parameters.
  14. Tokens logged in plaintext response headers displayed to support tools.
  15. 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

  1. Identify auth mechanisms: key, session, OAuth, JWT, mTLS.
  2. Document issuance, refresh, revocation, and expiry rules.
  3. Build role and tenant fixtures.
  4. Apply the baseline missing/malformed/expired/valid matrix.
  5. Add scope and resource authorization cases.
  6. Add refresh and logout cases if applicable.
  7. Add abuse cases: rate limits, replay, algorithm misuse where in scope.
  8. Automate stable checks in CI.
  9. Redact secrets in logs and artifacts.
  10. 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:

  1. Decode a newly issued token and verify iss, aud, and exp policy.
  2. Hit one protected endpoint in each critical environment after deploy.
  3. Confirm old environment tokens fail in the new environment.
  4. 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:

  1. User in Tenant A requests Tenant B resource by id.
  2. User with membership in two tenants calls an endpoint without tenant context.
  3. API key for Tenant A is used with Tenant B identifiers in the body.
  4. Search and list endpoints never return cross-tenant hits.
  5. Webhooks and exports are scoped to the correct tenant.
  6. 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.