Authentication and authorization is one of the top interview topics for QA engineers. Every company with an API asks these questions. Here are the most frequently asked questions with answers that will impress the interviewer.
Q: What is the difference between authentication and authorization?
A: Authentication verifies WHO you are — your identity. Authorization verifies WHAT you can do — your permissions. Authentication happens first. You cannot authorize someone whose identity is unknown. In APIs, failed authentication returns 401 Unauthorized. Failed authorization returns 403 Forbidden. A hotel analogy: checking in at the front desk is authentication. Your key card opening only your room is authorization.
Q: How do you test APIs secured with JWT tokens?
A: I follow this approach: (1) Send a POST to /auth/login with valid credentials and extract the JWT token from the response. (2) Use the token in the Authorization header as "Bearer <token>" for subsequent requests. (3) Positive tests: verify valid token gets 200, verify token claims match the user. (4) Negative tests: no token (401), expired token (401), malformed token (401), tampered token (401), wrong role (403). (5) I use a BaseTest class that logs in once in @BeforeSuite and provides helper methods like asAdmin() and asUser() to avoid redundant login calls.
Q: What is OAuth 2.0? How is it different from basic authentication?
A: OAuth 2.0 is a delegation protocol — it lets apps access user data without knowing the user's password. The user authenticates directly with the provider (Google, GitHub), and the app gets a limited-access token. Basic Auth sends username and password (Base64-encoded) with every request. OAuth sends a token that expires and has scopes limiting what it can do. OAuth is more secure because: credentials are never shared with third-party apps, tokens expire automatically, and scopes limit permissions. Basic Auth is simpler but sends credentials repeatedly, increasing risk.
Q: What security tests do you perform on APIs?
A: I test for: (1) IDOR — accessing other users' data by changing resource IDs in the URL. (2) Broken Function Level Authorization — regular users calling admin endpoints. (3) Mass Assignment — sending unauthorized fields like "role: admin" in update requests. (4) Broken Authentication — expired/invalid/missing tokens, SQL injection in login. (5) Information Leakage — error responses revealing stack traces, database names, or internal paths. (6) Token Security — passwords not returned in responses, tokens not logged. I use the OWASP API Security Top 10 as my checklist.
Q: How do you handle token management in your test automation framework?
A: I use a centralized BaseTest approach. In @BeforeSuite, I call the login endpoint once per role (admin, user, viewer) and store tokens as static class variables. I provide convenience methods like asAdmin(), asUser(), and asGuest() that return pre-configured RequestSpecifications with the token already set. For long-running suites, I track token expiry and automatically refresh before the token expires — with a 60-second buffer. This way, every test method is clean — it just calls asAdmin().get("/endpoint") without worrying about auth plumbing.
Q: What is IDOR? Have you found any IDOR bugs?
A: IDOR stands for Insecure Direct Object Reference. It occurs when an API trusts user-supplied resource IDs without verifying ownership. For example, if GET /orders/123 returns order data regardless of which user is making the request, any authenticated user can read any order by guessing IDs. To test it: login as User A, note their resource IDs, login as User B, try accessing User A's resources with User B's token. If it returns 200 instead of 403 — that is a critical IDOR vulnerability. I test every GET, PUT, and DELETE endpoint that takes an ID parameter. I have found IDOR bugs in profile endpoints, order history, and document download APIs.
Q: What is the difference between API key and Bearer token authentication?
A: API key is a static string that identifies the application (not the user). It does not expire until manually revoked. It is sent as a header or query parameter. Bearer token (usually JWT) identifies a specific user, is generated after login, has an expiry time, and carries user claims like role and permissions. API keys are used for server-to-server calls (like accessing Google Maps API). Bearer tokens are used for user-facing apps (like a mobile banking app). In testing, API keys are simpler — you set it once. Bearer tokens require a login flow, token extraction, and expiry management.
Q: How do you handle authentication in Postman vs REST Assured?
A: In Postman: I set Bearer Token auth at the collection level using an environment variable {{authToken}}. I add a collection-level pre-request script that checks token expiry and auto-refreshes by calling the login endpoint. All requests inherit auth from the collection. For negative tests, I set individual request auth to "No Auth." In REST Assured: I create a BaseTest class with @BeforeSuite that logs in and stores tokens. Helper methods asAdmin() and asUser() provide pre-configured RequestSpecifications. Token refresh is handled by checking expiry before each request. Both approaches follow the same principle — login once, reuse everywhere.
In interviews, always explain your answer with the what, why, and how. "What" is the concept. "Why" is why it matters in testing. "How" is how you implement it. Interviewers want to know you can APPLY the knowledge, not just recite it.
Key Point: Know the difference between 401 and 403. Explain JWT structure. Describe your token management strategy. Talk about IDOR confidently. Mention OWASP API Top 10.
Answer all 5 questions, then submit to see your score.
1. A user sends a valid JWT token but tries to access an admin-only endpoint. What HTTP status code should the server return?
2. What are the three parts of a JWT token?
3. Which OAuth 2.0 grant type is best suited for server-to-server communication with no user involved?
4. What is IDOR (Insecure Direct Object Reference)?
5. In REST Assured, what does auth().preemptive().basic("user", "pass") do differently from auth().basic("user", "pass")?