type1fool

type1fool

Arbiter - Role Based Authorization

Backstory

Before I became a full-time developer on a PHP team in 2018, I had been studying role based authorization (RBA) for an Elixir application I was developing part-time. Ever since, I have missed working in Elixir.

To sharpen my Elixir skills, I want to create an RBA library. There are a few existing libraries, but they seem to be intended for single-tenant applications. I think there is room for a multi-tenant library for B2B applications that serve multiple businesses.

Arbiter :building_construction:

Arbiter on GitHub

So far, I have written about the intent and preliminary design in the readme. I have also created the modules I expect to need, and started writing tests for the Organization module. I’m hoping to TDD this project to discover the optimal abstractions and to satisfy potential security requirements. :crossed_fingers:

As I get started on the design, I want to hear from potential users to test my ideas. It’s worth noting is that this is my first open source project. I have been working on internal PHP applications and a custom framework, but nothing public-facing. I’ve learned the importance of hearing from users before spending hours/weeks on implementation.

Question Time

  • Have you used one of the existing libraries or built custom RBA tools?
    • What were the benefits and pain points?
  • Do I need a Policy module?
  • What are some possible hard requirements for adoption?
  • Could the library accept (potentially decorate) a User struct from other auth libraries/modules?
    • How?
  • If Ecto is a dependency, should it default to ETS, SQLite, or Postgres?
    • Could/should the library avoid persistence entirely, leaving that to the user?
  • Would telemetry be useful in this kind of library?
  • Do you have any other suggestions?

Most Liked Responses

thojanssens1

thojanssens1

Personally I think what’s missing is the API you eventually want to provide for the library users.

I came to the conclusion that authentication and authorization is way too application-specific to make a library out of it. Authorization is actually vague as it can mean many different systems.
But change my mind :sweat_smile:

To elaborate this thought, take for example authentication and Pow. Pow requires you to inject code (use) in many layers of your application (controllers, views, routes, etc.) for it to work. Even though many devs like and use it, it makes more sense for me to use a scaffolding tool like phx.gen.auth that provides a codebase from which you can customize to your application needs. The fact that Pow must inject code application-wide is for me a clear sign that this should be application-specific code.

A lot of the topics and questions you raise concern business logic (user, team, organization, etc.) and I suspect the library might impose a minimum of conventions to follow in one’s business logic for it to work, but that is something I’ll never want to compromise. The library should work over the existing business logic without a change.

In my case, I work on calendars and a huge part of the authorization is sharing calendars between users with permissions. I have a CalendarSharingPermission Ecto schema that holds those permissions. Would I want to replace this calendar sharing table by a more general authorization solution? I think not, as it’s actually quite complex and specific, and I would also lose in terms of semantics and readability, and customization and flexibility.

I’m not sure what is the library’s goal (as I said, missing a demo API/usage), but you might consider the alternative of creating a blog post with your knowledge about authorization systems and provide sample code that someone can copy over and customize (similar to scaffolding).

al2o3cr

al2o3cr

General advice: for the first pass at the idea, MAKE DECISIONS. Yes, eventually you might need to support primary keys of various types or totally different persistence - but trying to force everything to be too generic too early is a recipe for over-abstraction (see also… most of the last 30 years of OOP).


As @thojanssens1 mentioned, the hard part of RBAC is the interface the rest of the system uses: how does application code tell Arbiter what an “action” is? How will Arbiter answer questions like “show me the most recent 20 Widget records that this user can see”?

A good way to learn the answers to these questions (and have a nice demo to show people) is to build your abstractions inside a demo application and only then try to abstract them into a library.


On the organizations branch, it feels like the documentation is already suggesting a limitation of the interface. In this commit this example is added:

Clerks may start an order, add items, remove items, place an order on hold, accept payment method(s), and complete the order.

    permissions: [
      {:order, [:create, :update]},
    ],

Managers would likely include the same permissions as clerks, but would also be able to cancel orders, process refunds, and view reports.

    permissions: [
      {:order, [:create, :read, :update, :delete]},
      {:report, [:read]},
    ],

The words used to describe the permissions (“clerks can place an order on hold”) are much more specific than the actions used to represent the permissions (order: [:create, :update]).

For instance, can a clerk update an order that’s already been shipped? Can a clerk EVER update the address on an order? “update” is very wide…

Some of this may be a matter of picking a better data model - for instance, only giving managers the “process refund” permission is tricky if it’s viewed as an “order update”, but easier if it’s a “refund create”.

harmon25

harmon25

I have been considering using Bodyguard — Bodyguard v2.4.1 (hexdocs.pm) to handle relatively simple authorization requirements.

Elixir/Erlangs pattern matching capabilities lends itself quite well for this type of code, which is one of the reasons I like Bodyguard.

On the more complex end - think AWS/GCP policies. Take a look at Zanzibar: Google’s Consistent, Global Authorization System

And ORY Keto which is “the first and only open source implementation of Zanzibar”

Open Policy Agent is also worth looking into for inspiration. Maybe building on top of something like that would make sense. (OPA is what earlier versions of Keto were built on)

Where Next?

Popular in Discussions Top

vans163
So useless benchmarks aside, Its possible to write a webserver that can serve 300k requests per second (perhaps more with optimizations)....
New
PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
chuck
Let me start by stating an assumption: Phoenix is a great approach to building REST APIs. There are many reasons for this, but I will ass...
New
AstonJ
If a newbie asked you about Phoenix Contexts, how would you explain the basics to them? Feel free to be as concise or in-depth as you li...
New
ejpcmac
I have discovered Nix last month and I am currently on my way to migrating to it—both on macOS at home and the full NixOS distrubution at...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31142 143
New
wmnnd
The Go vs Elixir thread got me thinking: Would it be too hard to implement a simple mechanism for creating Go-style static app binaries f...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement