Authentication and Authorization Boundaries

Authentication (AuthN) establishes who a caller is, while authorization (AuthZ) determines whether that identity may perform a requested action on a resource. Keeping these concerns separate makes REST APIs easier to secure, test, and reason about.

Authentication verifies an identity using credentials or an authentication mechanism such as a session cookie, API key, or bearer token. The result is typically an authenticated principal, such as a user ID and associated claims.

Authorization happens after authentication and evaluates whether that principal is allowed to perform a particular operation. A typical REST API decision depends on the principal, HTTP method, target resource, ownership, roles, scopes, or other policy attributes.

The boundary matters because successfully proving identity does not imply permission. For example, an authenticated user may be allowed to read their own account but forbidden from reading another user's private data. Authorization should therefore be enforced at the resource or operation boundary rather than treating authentication as sufficient protection.

In a Python backend, it is useful to make authentication produce a consistent principal object and pass that identity into authorization logic. This keeps route handlers focused on application behavior while making permission checks explicit and reusable.

A secure design also avoids trusting identity or permission information supplied directly by the client. Credentials and tokens must be validated before their claims are used, and authorization decisions should be based on trusted server-side context.

Key points

Interview questions

What is the difference between authentication and authorization in a REST API?

Authentication determines which principal is making the request, using credentials such as a session or token. Authorization determines whether that authenticated principal may perform the requested operation. For example, a user can authenticate successfully but still be denied access to another user's private document. The two checks should therefore be treated as separate security decisions.

Why should authorization checks consider the resource being accessed?

Permissions are often contextual rather than global. A user might be allowed to update their own profile but not another user's profile, even though both requests come from the same authenticated principal. The authorization decision therefore needs enough context to evaluate both the requested action and the target resource. This is commonly implemented with ownership checks, roles, scopes, or policy rules.

What is the difference between HTTP 401 and 403 for a protected API endpoint?

A 401 response is appropriate when the request lacks acceptable authentication credentials, such as when a bearer token is missing or invalid. A 403 response is appropriate when the caller is authenticated but is not permitted to perform the requested operation. The distinction helps clients understand whether authentication needs to be established or whether the requested action is disallowed. Exact response details should still avoid exposing sensitive authorization information.

How would you structure authentication and authorization in a Python web service?

I would use middleware or dependency-style components to validate credentials and construct a trusted principal. Route or service code would then invoke authorization logic with that principal, the intended action, and the target resource. Centralizing authentication avoids repeating token validation, while reusable authorization policies keep access rules consistent. I would also test authentication failures and authorization failures independently.

What security problem occurs if an API trusts a user ID supplied by the client?

A client-controlled user ID is not proof of the caller's identity or authority. An attacker could change an identifier and attempt to access another user's resource, producing an insecure direct object reference or similar authorization flaw. The server should derive the authenticated principal from validated credentials and independently authorize access to the requested resource. Resource identifiers can still come from the request, but permission must be checked against trusted identity and policy context.