Arbiter - Role Based Authorization

Thank you for the thoughtful responses @thojanssens1 & @al2o3cr!

While it wouldn’t fit every use case, I do think there is a broadly useful API waiting to be discovered.

I have been thinking primarily in terms of using Phoenix routes as resources, and their public functions as actions. If the library is dealing with the typical actions :index, :show, :new, :create, :edit, :update, :delete, I can seed default permissions for each of these. Those atom tuples were a simplified version of what i have in mind.

This is still a very early stage project, so you may be right that the readme and some of the modules are a little over-prescribed. I wanted to get as much of the idea into markdown ASAP in part so I could get the kind of valuable feedback you guys have provided.

There would be an interface for managing permissions (and data for each of the modules), which should provide devs flexibility to follow a strict-ish CRUD design for resources; or they could add custom permissions to be used across roles and resources.

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…

In this example, the org might create different resources for different types of orders and for orders with various attributes. Maybe the Resource struct needs a where field to identify subsets of a resource type.

More Detailed Example

%Resource{
  name: "Pending Order",
  route: Routes.order_path(...), # just a thought
  where: [
    [:status, =, :pending] # 🤔
  ],
  ...
}
yesterday = DateTime.utc_now() |> DateTime.add(-86400)

%Resource{
  name: "Recently Shipped Order",
  route: Routes.order_path(...),
  where: [
    [:status, =, :shipped], # 🤔
    [:shipped_at, <, yesterday]
  ],
  ...
}
%Role{
  name: "Clerk",
  org_id: 1234,
  permissions: [
    %Permission{
      resource: %Resource{name: "Pending Order", ...},
      actions: [:index, :view, :edit, :update]
    },
    %Permission{
      resource: %Resource{name: "Recently Shipped Order", ...},
      actions: [:index, :view]
    },
  ],
}
%Role{
  name: "Manager",
  org_id: 1234,
  permissions: [
    %Permission{
      resource: %Resource{name: "Pending Order", ...},
      actions: [:index, :view, :new, :create, :edit, :update, :delete] # soft delete
    },
    %Permission{
      resource: %Resource{name: "Recently Shipped Order", ...},
      actions: [:index, :view, :edit, :update]
    },
  ],
}
1 Like