API Security Authentication vs Authorization
Two words dominate API security conversations: authentication and authorization. Many people use them interchangeably, but they mean completely different things. Confusing them — or implementing one without the other — causes serious vulnerabilities.
Authentication answers the question: "Who are you?" Authorization answers the question: "What are you allowed to do?" Both checks must pass before an API grants access to any sensitive operation.
The Hotel Key Card Analogy
A hotel key card system illustrates both concepts perfectly.
At Check-In (Authentication): Guest presents ID and booking confirmation. Hotel staff verify identity: "Yes, you are Vikram Nair, you have a reservation." Hotel issues a key card programmed for Room 412. At the Room Door (Authorization): Vikram swipes his card at Room 412. Door system checks: "Is this card authorized for Room 412? Yes." Door opens. If Vikram tries Room 208: Door system checks: "Is this card authorized for Room 208? No." Door stays locked. Authentication = Front desk verified WHO Vikram is. Authorization = Door system checked WHAT Vikram can access.
Both checks are essential. The hotel would be unsafe if it issued cards without verifying identity (broken authentication). It would also be unsafe if any valid card opened any room (broken authorization).
Authentication in APIs
When a client calls an API, authentication is the process of proving that the client is who it claims to be. The API must be able to answer: "Is this request coming from a real, known entity?"
What Clients Use to Prove Identity
Three categories of authentication evidence: Something You Know: - Passwords - PINs - Security question answers Risk: Can be guessed, phished, or leaked in data breaches Something You Have: - API keys - OAuth tokens - One-time passwords from an authenticator app - Hardware security keys (YubiKey) Risk: Can be stolen if stored insecurely Something You Are: - Biometric data (fingerprint, face recognition) Risk: Cannot be changed if compromised; privacy concerns
Strong authentication combines two or more categories — this is multi-factor authentication (MFA). An attacker who steals a password still cannot log in without the second factor.
Authentication Failure Examples
Example 1 – No Authentication: GET /api/admin/users → No token required. Anyone can call this endpoint. → All user records exposed to the world. Example 2 – Weak Authentication (HTTP Basic): Authorization: Basic dXNlcjpwYXNzd29yZA== → Base64-encoded "user:password" (not encrypted, just encoded) → Anyone intercepting traffic can decode it instantly. Example 3 – Expired Tokens Not Rejected: User logs out at 9 AM. Attacker stole the user's token at 8:59 AM. At 5 PM, attacker uses the same token. → API accepts it because tokens never expire.
Authorization in APIs
Once the API knows who is making a request, it must decide whether that identity is permitted to perform the requested action on the requested resource. This is authorization.
Three Levels of Authorization
Level 1 – Endpoint-Level Authorization
"Is this user role allowed to call this endpoint at all?"
Example:
/api/admin/delete-user → Only ADMIN role allowed
/api/reports/export → Only MANAGER or ADMIN role allowed
/api/profile/update → Any authenticated user allowed
Level 2 – Object-Level Authorization
"Is this specific user allowed to access this specific resource?"
Example:
User Meera (ID 201) requests GET /api/orders/5501
→ Is order 5501 owned by user 201?
→ Yes → Allow
→ No → Deny with 403 Forbidden
Level 3 – Field-Level Authorization
"Is this user allowed to see this specific field in the response?"
Example:
Regular user requests GET /api/users/201
→ Can see: name, email, phone
→ Cannot see: internal_credit_score, fraud_flags, admin_notes
→ Admin requests same endpoint
→ Can see all fields including internal ones
Authorization Failure Examples
Scenario: An e-commerce API for "ShopEasy"
User types: Regular customer
Admin types: Store manager, finance team
Broken Function Level Authorization:
Regular customer calls: DELETE /api/products/88
→ Server checks: "Is user authenticated?" Yes.
→ Server forgets to check: "Is user an admin?"
→ Product deleted by a regular customer.
Broken Object Level Authorization:
Customer Raj (user_id 301) calls: GET /api/orders/9901
→ Order 9901 belongs to customer Sunita (user_id 302)
→ Server checks authentication but not ownership
→ Raj sees Sunita's order details, address, and payment info.
Broken Field Level Authorization (GraphQL):
Regular user queries:
{ user(id: 301) { name salary ssn internal_rating } }
→ Server returns salary, SSN, and internal_rating
→ These fields should only be visible to HR or admin roles
The Combined Flow: Authentication Then Authorization
Every API request should pass through both gates in sequence.
API Request Processing Flow: Incoming Request ↓ Step 1: Authentication Check Q: "Does this request carry valid credentials?" Valid token/key → Continue No token or invalid → Return 401 Unauthorized ↓ Step 2: Identity Extraction "Who is this? User ID 301, Role: customer, Plan: premium" ↓ Step 3: Endpoint Authorization Q: "Is this role allowed to call this endpoint?" Allowed → Continue Not allowed → Return 403 Forbidden ↓ Step 4: Object Authorization Q: "Does this user own or have permission to access this resource?" Owns it → Continue Does not own it → Return 403 Forbidden ↓ Step 5: Execute Request Process the business logic. ↓ Step 6: Filter Response Remove fields this role cannot see. Return response.
Skipping or shortcutting any step in this flow creates a vulnerability.
HTTP Status Codes for Auth Failures
Correct status codes communicate the specific type of failure. Using the wrong code confuses clients and breaks security logic.
401 Unauthorized: Meaning: "I don't know who you are. Please authenticate." When to use: No token provided, token is expired, token is invalid. Note: Despite the name "Unauthorized", it actually means "Unauthenticated" 403 Forbidden: Meaning: "I know who you are, but you cannot do this." When to use: Valid token, but the user lacks permission for this action. Common mistake – returning 404 for auth failures: Some APIs return 404 Not Found instead of 403 Forbidden when a user tries to access a resource they do not own. This hides the existence of the resource from unauthorized users, which is sometimes intentional. However, consistent use of 403 is generally preferred for clarity.
Role-Based Access Control vs Attribute-Based Access Control
Two major models exist for implementing authorization. Understanding the difference helps you choose the right approach for your API.
Role-Based Access Control (RBAC)
Users are assigned roles. Roles have permissions. Simple, fast, and easy to understand.
RBAC Model for a Hospital API:
Roles: patient, nurse, doctor, admin, billing_staff
Permissions:
GET /api/records/{id}
→ patient (own records only), nurse, doctor, admin
POST /api/prescriptions
→ doctor only
GET /api/billing/{patient_id}
→ patient (own billing only), billing_staff, admin
DELETE /api/users/{id}
→ admin only
RBAC works well for systems with clear, stable roles. It struggles when permissions need to be context-dependent — for example, "Doctor can see records of patients assigned to their ward, but not patients in other wards."
Attribute-Based Access Control (ABAC)
Permissions are granted based on attributes of the user, the resource, the action, and the environment. More flexible but more complex.
ABAC Policy Example: ALLOW access to patient_record IF: user.role = "doctor" AND resource.assigned_doctor_id = user.id AND action = "read" AND environment.time = "business_hours" This expresses: "Doctors can read records of their own assigned patients during business hours." RBAC cannot express this level of specificity.
Common Authentication and Authorization Vulnerabilities
Vulnerability 1: JWT Algorithm Confusion
JWT token specifies "alg": "none" → No signature required
→ Attacker modifies JWT payload to change their role to "admin"
→ Server accepts it because no signature is verified
Vulnerability 2: Privilege Escalation via Profile Update
PATCH /api/users/301
{ "name": "Raj", "role": "admin" }
→ If server accepts the "role" field from clients, attacker promotes self
Vulnerability 3: Insecure Direct Object Reference
GET /api/documents/55
→ Document 55 belongs to another user
→ API checks auth token is valid but not that user owns document 55
Vulnerability 4: Missing Authorization on Sensitive Operations
POST /api/admin/reset-password (no auth required)
→ Anyone can reset anyone's password
→ Full account takeover without credentials
Vulnerability 5: Over-Permissive Tokens
API key issued to a mobile app has read AND write AND delete permissions
→ If key is stolen, attacker can delete all data
→ Should have been read-only for a mobile app
Best Practices for API Authentication and Authorization
Building authentication and authorization correctly from the start saves enormous remediation effort later.
Always authenticate every request, including internal API calls between your own services. Never assume that a request originating from inside your network is safe without verifying identity.
Implement object-level authorization checks in every endpoint that accesses a specific resource. This check must use the authenticated user's identity from the verified token — never from a user-supplied parameter like user_id=301 in the request body.
Apply the principle of least privilege to all tokens, API keys, and service accounts. Grant only the minimum permissions needed for each specific use case. A mobile app that only displays data should never hold a token with delete permissions.
Log every authentication failure and authorization failure. A pattern of 403 errors against sequential resource IDs is a strong indicator of a scanning attack and should trigger an alert.
Key Points
- Authentication asks "Who are you?" and must happen before authorization.
- Authorization asks "What are you allowed to do?" and must happen at three levels: endpoint, object, and field.
- A 401 status means unauthenticated (no valid identity). A 403 status means unauthorized (valid identity, insufficient permission).
- RBAC assigns permissions to roles. ABAC assigns permissions based on multiple attributes including context.
- The most common API vulnerabilities involve correct authentication but missing or incomplete authorization checks.
- Always check object ownership using server-side identity, never trust a user-supplied ID in the request body for authorization decisions.
