Q8 of 37 · API testing

What is the difference between authentication and authorisation?

API testingJuniorapiauthsecurityfundamentals

Short answer

Short answer: Authentication (authn) is proving who you are — login, tokens, certificates. Authorisation (authz) is what you're allowed to do once identified — roles, permissions, scopes. 401 means authn failed; 403 means authz failed.

Detail

These two are constantly mixed up — even by APIs in their own status codes. Knowing the difference matters for both writing and testing security tests.

Authentication (authn)who are you? The system verifies your identity via:

  • Username + password.
  • API tokens / API keys.
  • Bearer tokens (JWT, opaque session tokens).
  • mTLS certificates.
  • OAuth 2.0 access tokens.

If you can't be identified, the API responds 401 Unauthorised. Misnamed historically — "Unauthenticated" would be more accurate.

Authorisation (authz)what can you do? Once identified, the system checks whether your principal is allowed to perform the requested action. Models:

  • RBAC (role-based access control) — "admins can delete; viewers cannot."
  • ABAC (attribute-based) — "users in tenant X can read data in tenant X."
  • Scopes (OAuth) — "this token has reports:read but not reports:write."
  • Resource ownership — "you can edit posts you created, not someone else's."

If authorisation fails, the API responds 403 Forbidden.

Concrete example: A logged-in non-admin user calls DELETE /users/42:

  • The token is valid → authn passes (no 401).
  • The role isn't admin → authz fails → 403 Forbidden.

Test patterns:

  1. Per-role smoke — for each role (admin, manager, viewer), exercise the endpoints they should and shouldn't have access to. Assert 200/201 for allowed; 403 for forbidden.

  2. Token tampering — modify the token signature and confirm 401.

  3. Cross-tenant data — log in as user in tenant A, request a tenant B resource by ID. Assert 403 (or 404 — depends on whether the API hides existence).

  4. Token expiry — wait for / force expiry, retry, assert 401.

The interview signal: clean definitions, the 401 vs 403 mapping, and concrete test patterns for each.

// EXAMPLE

// Test: viewer cannot delete users
test('viewer is forbidden from deleting users', async ({ request }) => {
  const viewerToken = await getToken('viewer');

  const res = await request.delete('/users/42', {
    headers: { Authorization: `Bearer ${viewerToken}` },
  });

  // Authentication passed (token valid) → no 401
  // Authorisation failed (role insufficient) → 403
  expect(res.status()).toBe(403);
});

// WHAT INTERVIEWERS LOOK FOR

Clear definitions, the 401 (authn) vs 403 (authz) mapping, and concrete test patterns — especially per-role and cross-tenant.

// COMMON PITFALL

Conflating the two and writing a test that asserts 403 when the API actually returns 401, or vice versa. The status code is part of the contract — always assert the documented one.