heathen

heathen

Attribute-based Access Control (ABAC) and a DDD application

Hello!

I’m trying to figure out how to implement a complicated authorization scheme and allow to change the rules at run-time (without altering code base). Currently I evaluating this for a DDD (CQRS\ES) application I’am planning but it is more general question I think.

So let’s imagine we have the next set of authorization rules in the specs:

Pic with a table

It is possible to hard-code this rules but obviously I think it’s a dirty practice to put authorization code into the core domain for the one hand, and it will be non-trivial to support and extend this rules, especially when new domains, entities and\or attributes come to the scene.

So I think about ABAC with some kind of XACML implementation. In this case it would be possible to make policies like:

Policy name: List awaiting documents orders
Effect: Allow
Union: All
Rule 1: CommandOrQuery == ListOrders
Rule 2: Subject.Role == “Branch operator”
Rule 3: Object.Creator.Branch == Subject.Branch
Rule 4: Object.Status == “Documents required”

In case of commands Object-related rules become conditions, I believe.

Then it will be necessary to send the whole object and subject (user in our case) to the Application level authorization service like:

defmodule MyApp.Orders.Queries.ListOrders do
  alias MyApp.Orders.Projections.{User, Order}

  def execute(params, %User{} = user) do
    case MyApp.SecurityDomain.can?(__MODULE__, Order, user) do
      :not_authorized -> {:error, :not_authorized}
      conditions -> params
                    |> Map.merge(conditions)
                    |> buildQuery()
                    |> runQuery()
    end
  end

end

defmodule MyApp.SecurityDomain do
  def can?(MyApp.Orders.Queries.ListOrders, object, subject) do
    ...
  end
end

Sure, there will be a lot of difficulties beginning from query builder, especially with rules\conditions like in my example (Order aggregation and projection must have a Creator structure (even sub-aggregate probably) with Branch field) and so on, Order domain must follow User events and update appropriate local user aggregates etc etc.

But this will be let the security officers to create very flexible rules right at the run-time without developers intervention and downtime.

Of course I may over-complicate things and the same can be done much more easily. If so please let me know where can I read best practice and realization (especially in Elixir). Haven’t seen any examples of the more or less complete authorization system, all applications\articles I found have very simple auth part.

What do you think?

Most Liked

StefanHoutzager

StefanHoutzager

A couple of messages around this subject appeared in different threads on this forum. The XACML standard XACML - Wikipedia was named. As I built a (start of) a rules engine in the past, as part of a BPMS (start of also, haha), I wonder if it would be interesting to use the broader DMN standard for this, for which open source modelers, interpreters (execution engines I mean) and validators are available. At least from Camunda. Here some thoughts / questions about the position of XACML, modelers and execution engines (search for keyword XACML), note: the book is almost 10 yrs old: Sustainable IT Architecture: The Progressive Way of Overhauling Information ... - Pierre Bonnet, Jean-Michel Detavernier, Dominique Vauquier, Jerome Boyer, Erik Steinholz - Google Books

karmajunkie

karmajunkie

I think you’re on the right track. A couple of suggestions:

  • If you’re using Commanded as your CQRS framework, which is the most commonly used in Elixir, you can use a middleware around command dispatch for authorization, which would be a good place to put your check.
  • There are a few libraries for authorization already on the scene; it might be worth looking at them.
  • If you’re going to roll your own (which is perfectly acceptable in my mind) you might look at using a protocol and providing implementations in different contexts that have different business rules around when a command can be dispatched.
MilosMosovsky

MilosMosovsky

Hey @heathen, it’s funny as I went to same scenario as you :slight_smile: (actually not that funny as it is common use case in real world app). I was struggling with hard coded rules as you but recently I created the library

I think it can cover many cases (if not all) in your described chart. Could you give a look to it? Thanks! I would love to see problems and cover any possible scenario needed and your complex table looks as good start :slight_smile:

Where Next?

Popular in Questions Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
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
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
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

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43657 311
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36432 110
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

We're in Beta

About us Mission Statement