insights by infactory in-factory GmbH REST - Access Control with HATEOAS

Many web applications nowadays are composed of a JavaScript frontend (Angular, React, Svelte etc.) and a separate backend. One of the most popular backend choices are REST APIs. Most of the web applications that we develop for one of our clients also utilize REST APIs at the backend. One of the key benefits that we found in REST APIs is the ability to shift the heavy lifting of Access Control to the backend side. This is done with the help of the HATEOAS (Hypermedia As the Engine of Application State) constraint, that is part of the Uniform Interface constraint of REST APIs.

HATEOAS and Access Control

As REST is actually the underlying architecture of the World Wide Web, an example for HATEOAS can be seen on virtually every website that can be accessed through a standard web browser. When accessing a website, the only way to change or drive the state is by clicking on the embedded hyperlinks. It is possible to visualize all transitions of the website with a state machine. This is true for static websites as well as dynamically generated websites. For dynamically generated websites the state machines might be different for each user accessing the page. This is where Access Control usually plays a role, since normally not every user will have the same access to all resources on a web application.

To illustrate this we can take a simple blogging website. There are two kinds of users: The owner of the blog and visitors that want to read the blog entries. While the blog owner should have the ability to create, delete or update entries on this page, visitors should only be able to read the entries. Assuming authentication and authorization are already implemented correctly, the two state machines for users are as follows:

HATEOAS - State Machine - REST

Two state machines for website users

Each node of the state machine represents a state that is returned by the server upon page visit. The outgoing edges of each node show what a user can do based on his current state. Each of these edges is technically represented by a link. If an edge/ link is missing in the state machine, this means the user is not allowed to follow down the same path that another user might be allowed to. As the state machine suggests, a guest cannot modify any resource, while the owner is allowed all operations.

Traditional websites will respond with a HTML payload which browsers can already render. Thus, a button that is not included in the HTML response will not be shown on the screen. This could be due to the decision of the backend that a user does not have sufficient rights. However, REST APIs usually respond with some kind of JSON payload. When applying HATEOAS, this payload will have in some form a list of links that tells the client what he is allowed to do next. In this case the frontend has to implement some logic to get the same dynamic rendering of the User Interface. In the next section, we will show an abbreviated example of how we achieve Frontend-side Access Control in Svelte.

Example in Svelte

Assume that following response object is returned by a REST API after requesting a single example resource (links are implemented using a proprietary reserved property):

   const response = {
	“xxx”: “data XXX”,
	“yyy”: “data YYY”,
	“_links”: {
		“self”: “”,
		“next”: “”,
		“create”: ””,
		“delete”: “”,
		“update”: ””

Based on this response, in Svelte we can conditionally render the parts that are responsible for creating, deleting or update a resource like so:

  {#if response._links.hasOwnProperty(“create”) }.
  {#if response._links.hasOwnProperty(“delete”) }
  {#if response._links.hasOwnProperty(“update”) }

As can be seen, the conditions on the frontend are very simple and work solely on the links given by the backend. This means that the potentially heavy logic for Access Control lies completely on the backend side, thus greatly unburdening the client-side and reducing complexity.


This article shows how Access Control can be, at least visually, achieved through HATEOAS. Obviously, not showing UI elements does not prevent otherwise malicious clients from accessing protected API endpoints. Thus, all endpoints that need restricted access have to be additionally secured on the backend.

Author: Long Bui


Write us. We are looking forward to your message!