TL;DR: We rewrote parts of OpenFGA in pure Postgres to make it easier to keep our authorization system up-to-date with our main database. Everything is available on GitHub.
In software engineering, ‘auth’ is a bit of a loaded term. It’s generally used to describe the process of both authenticating users (determining who a user is) and authorizing users (determining what they’re allowed to do).
Authentication (often referred to as ‘authn’) is pretty much a solved problem when you’re writing a user-facing application. There are cookie-cutter solutions that you can usually just drop into your code and get going - think OAuth, passkeys, magic links, etc.. Even if you’re doing the hip thing and rolling your own auth, you’ll pretty much always be following one of these patterns. They’re what users have come to expect, and doing differently is more likely to single you out as an annoyance than win you any UX awards.
Authorization (‘authz’), on the other hand, is a lot more tricky. How you check whether a user is or isn’t allowed to do something will depend heavily on your application and the audience you’re intending to serve. On top of that, authz checks aren’t something your users are likely to be interacting with directly all that often - they usually happen silently in the background - so there’s a lot more flexibility.
In the wild, you’ll usually run into the following systems:
RBAC - role-based access control. Each user has a number of roles, each of which has permissions that allow users to do things. The manager role might have the approve_expenses permission, while the employee role only has submit_expenses . This method is simple and scalable for a lot of use cases, but can become quite complex if your app has a lot of moving parts.
PBAC - policy-based access control. This is what governs most of AWS, and, personally, my least favourite of the bunch. Access is governed by policies - usally in JSON or YAML - that describe the actions a user is or isn’t allowed to take, and under what conditions they’re allowed to take them. For example, users who have the AWSCodeCommitReadOnly policy will have read access to AWS CodeCommit repos, but won’t be able to push.
ABAC - attribute-based access control. This one is a little less common, but is interesting nonetheless. Essentially, access is granted based on “attributes” (usually key-value pairs) on the users, resources and the environment. A user may only be able to access documents in a folder if their department attribute matches that of the folder. ABAC is incredibly fine-grained, but that can make it complex to manage and scale.
ReBAC - relationship-based access control. This is what you’ll see with apps like Google Drive. Alice is an owner of a folder and can therefore read and write any documents that belong to it. Bob is a viewer of a specific document in that folder, but he can’t see any of the others, and can’t edit anything. ReBAC is a nice fit when you’re using a relational database, because it fits with your existing mental model of your data.
So, what about Rover?
... continue reading