Controlling access to API endpoints

After defining the endpoints for referring to resources, the next logical step is to implement a mechanism for enforcing access control. For instance, while /orders/123 and orders/789 are both valid resource paths, they might belong to different users; obviously, we would expect that each user should only be able to access their own orders.

In a different scenario, a user might be able to list the users that belong to a particular security group by performing a GET request to /security-groups/123/users, but only an administrator would be allowed to add or remove users from that group (for example, by performing POST and DELETE requests to the same endpoint). A fairly common pattern for achieving this kind of granular access to resources is Role-Based Access Control (RBAC).

To apply this pattern, we need to define a list of roles (for example, normal user, administrator, and so on) and associate each role with a set of access permissions. Each user of the system is assigned to one or more roles that the system consults when considering whether it should grant access to a particular resource or not.

Before we can go ahead and implement RBAC, we need to establish a mechanism for authenticating users prior to them attempting to access non-public API endpoints.

A lot of people tend to conflate the terms authentication and authorization when, in fact, they cannot be used interchangeably.

To avoid any confusion, let's spend a bit of time properly defining the two terms:

In the following two sections, we will be examining two popular approaches to handling authentication, namely, basic HTTP authentication over TLS and authorization to an external service provider via OAuth2.