Q8 of 37 · API testing
What is the difference between authentication and authorisation?
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:readbut notreports: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:
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.
Token tampering — modify the token signature and confirm 401.
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).
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);
});