API authentication testing is most useful when it is repeatable, authorized, and separated from real credentials. This guide provides a practical checklist for validating JWTs, OAuth flows, API keys, authorization rules, expiry behavior, replay resistance, and common HTTP responses before an API release or during an access investigation.
Overview
Authentication answers “Who or what is making this request?” Authorization answers “What is that identity allowed to do?” A secure API test plan checks both questions across successful, failed, expired, malformed, and deliberately tampered requests.
Run these tests only against systems you own or are explicitly authorized to assess. Use a local environment, staging tenant, or dedicated test accounts whenever possible. Never paste production tokens into online developer tools, issue trackers, shell history, CI logs, chat messages, or support tickets. Redact credentials before saving request and response examples.
A useful test matrix records the endpoint, HTTP method, required credential, expected status, expected response shape, and security observation. For example, a request to read a user’s own profile may require a valid access token, while an administrative update should require both authentication and a matching role or scope. Testing the positive path alone does not establish that authorization boundaries work.
Keep protocol behavior separate from application policy. JWT signature verification and claim validation are implementation concerns; whether a user may modify a particular resource is an authorization decision. Both belong in the release checklist.
Checklist by scenario
JWT testing
- Confirm that the server rejects a missing, empty, malformed, or incorrectly formatted token.
- Verify the signature with the expected key source and ensure that an unsupported signing algorithm is rejected rather than selected from untrusted input.
- Check the issuer (
iss), audience (aud), expiration (exp), not-before (nbf), and issued-at (iat) claims according to the service’s policy. - Test an expired token, a token that is not yet valid, a token issued for another service, and a token signed by an untrusted key.
- Confirm that permissions are derived from the intended claims and that changing a role, scope, subject, or tenant value without resigning the token has no effect.
- If token identifiers are used for replay detection or revocation, test duplicate use and revoked-token behavior.
- Exercise key rotation in a non-production environment. Verify how the service handles a new key, an old but still valid key, an unknown key identifier, and a temporarily unavailable key endpoint.
OAuth testing
- Test the complete flow with a dedicated client and test user. Confirm that the redirect URI must match the registered value and that unexpected redirect targets are rejected.
- For authorization-code flows used by public clients, verify the code challenge and verifier relationship. A code issued to one client, redirect URI, or user should not be accepted in another context.
- Check that state is generated, bound to the initiating session, and rejected when missing, reused, or changed. Where an identity layer is involved, validate the nonce as well.
- Request a narrow scope and confirm that the access token grants only that scope. Test missing, excessive, and cross-tenant scopes.
- Check authorization-code reuse, expired codes, refresh-token reuse, refresh-token revocation, and logout behavior according to the selected flow.
- Confirm that client secrets are kept on the server side and are not shipped in browser code, mobile binaries, public repositories, or front-end configuration.
API-key testing
- Send requests with the key missing, blank, malformed, expired, revoked, duplicated, and associated with the wrong environment.
- Confirm that keys are accepted only in the documented transport location, preferably over TLS. Test whether placing a key in a query string creates avoidable exposure in logs, browser history, proxies, or analytics systems.
- Check whether keys identify an application, a user, or a service account. Verify that the resulting permissions match that identity and cannot be expanded by changing a label supplied by the caller.
- Test rotation and revocation with a dedicated key. Confirm that the old key stops working when policy requires immediate invalidation.
- Review redaction in application logs, tracing attributes, error messages, metrics labels, and CI output.
Authorization and object-level access
- For every protected endpoint, test an unauthenticated request, an authenticated request with insufficient permissions, and a permitted request.
- Use two test identities and two test tenants. Try to read, update, delete, or export identity A’s resource while authenticated as identity B.
- Test authorization on every relevant HTTP method, including less frequently used operations such as bulk updates, file downloads, export jobs, and asynchronous task status endpoints.
- Check that server-side decisions use trusted identity context rather than user IDs, roles, or tenant IDs supplied only in the request body or URL.
- Verify that authorization is applied consistently through direct API calls, background jobs, cached responses, and alternate API versions.
Safe request examples
Use placeholders and environment variables rather than literal credentials. This example keeps the token outside the command text:
export API_BASE="https://staging.example.test"
export ACCESS_TOKEN="replace-with-a-short-lived-test-token"
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Accept: application/json" \
"${API_BASE}/v1/profile"To test an expected authorization failure, use a deliberately limited test token and inspect the status without printing sensitive headers:
curl --silent --output response.json --write-out "%{http_code}\n" \
-H "Authorization: Bearer ${LIMITED_TEST_TOKEN}" \
"${API_BASE}/v1/admin/settings"Shell history, process listings, proxy logs, and CI diagnostics can still expose environment values indirectly. Use short-lived credentials and a controlled test runner for repeatable checks.
What to double-check
Status codes and response details
Document the intended distinction between authentication and authorization failures. In many APIs, 401 indicates that usable authentication is absent or invalid, while 403 indicates that the server understood the identity but will not permit the operation. Implementations may differ, so test and document the behavior your clients rely on.
Failure responses should not reveal signing keys, stack traces, token contents, internal permission names, database identifiers, or whether a sensitive account exists. At the same time, clients need a stable enough error shape to handle failures without guessing. Check status codes, response bodies, headers, correlation IDs, and cache directives together.
Transport, storage, and observability
- Confirm that credentials are sent only over the intended encrypted transport and that insecure redirects or alternate hostnames are not accepted.
- Check browser storage, mobile storage, server configuration, secret managers, and local development files for accidental persistence.
- Search logs and traces for
Authorizationheaders, cookies, API-key fields, JWTs, refresh tokens, and sensitive query parameters. - Ensure that monitoring can identify repeated authentication failures, unusual token use, and authorization denials without capturing the credential that caused the event.
- Verify rate limits and abuse controls for login, token issuance, refresh, key validation, and passwordless or recovery endpoints where applicable.
Test data and automation
Give each automated test a named, limited account or service identity. Make setup and cleanup explicit, and avoid tests that depend on another test’s token or mutable permissions. Store only references to secrets in CI configuration when possible, and make failed test output safe to publish to the build log.
For a broader DevSecOps workflow, connect these checks to the same delivery controls used for application and infrastructure changes. The CI/CD Pipeline Design Guide can help place security checks at appropriate points in a release pipeline, while the Online Developer Utilities Guide is useful for understanding local formatting and encoding utilities without treating decoded data as safe to share.
Common mistakes
- Testing only valid credentials: A green login test does not prove that expiry, revocation, scope, tenant isolation, or object-level authorization works.
- Decoding a JWT and treating it as verification: A JWT payload is readable by design in many deployments. Decoding does not validate its signature, issuer, audience, or time claims.
- Using production tokens during troubleshooting: Reproduce the issue with a short-lived, least-privileged test identity and revoke it afterward.
- Assuming a hidden endpoint is protected: Test every route and method, including internal-looking, legacy, bulk, download, and health-related endpoints that expose data.
- Checking roles only in the user interface: Authorization must be enforced by the API or service boundary, not just by hiding a button.
- Ignoring indirect disclosure: A credential may leak through a URL, redirect, referrer, error report, trace, screenshot, or copied curl command even when application logs are redacted.
- Relying on one tool: An API client, curl, integration tests, static analysis, and manual review expose different classes of failure. Choose tools that fit the risk and keep test inputs controlled.
When to revisit
Run this checklist before a new API or authentication release, after changing token claims or scopes, when adding roles or tenants, during penetration-test preparation, and after changing identity providers, SDKs, gateways, key storage, or secret-management workflows. Revisit it during seasonal planning cycles when teams review access, incident readiness, and production ownership.
Update the test matrix whenever an endpoint, client type, OAuth flow, signing key policy, API-key lifecycle, or authorization rule changes. Also review it after an incident, a suspected credential leak, an unexpected access denial, or a migration between API versions. Protocol guidance and library behavior can change, so confirm assumptions against the documentation for the components your system actually uses.
To make the process practical, assign an owner, keep a versioned checklist beside the API contract, attach automated tests to the release pipeline, and record exceptions with an expiry date. Before release, verify that test credentials are revoked or reset, captured evidence is redacted, and monitoring is ready to detect the failure modes the tests covered. This turns API authentication testing from a one-time exercise into a repeatable access-control control.