Hi ElixirForum,
I was looking for a library to help me implement authorization in a principled way, and looking around, I liked the simplicity of authorize, but I wanted to try out my own variation on the theme.
So yesterday I published auval_office
, a flexible AUthorization policy eVALuator.
What’s in the box?
When you define a policy module like this:
defmodule My.Policy
use AuvalOffice.Policy
rule ...
rule ...
rule ...
end
then auval_office
will augment your policy with an authorize
function:
case My.Policy.authorize(subject, object, action) do
{:ok, rule_id, parameters} -> # allowed
{:error, rule_id, parameters} -> # not allowed
end
What’s different from other authorization packages?
-
auval_office
is self-contained.It has no dependency on
phoenix
orecto
. It includes no plug for your web pipeline. You decide if authorization should be a domain responsiblity or a web layer responsibility, and where authorization-related data should be stored. -
auval_office
does not favor one access control model.It is flexible enough to implement lots of different access-control schemes, but favors none of them. I believe it offers enough flexibility to implement Role-Based Access Control (RBAC), Attribute-Based Access Control (ABAC) and Access Control Lists (ACLs), and combinations of those models.
-
auval_office
justifies its decisions.The return value of the
authorize
function includes the ID of therule
that made the decision, and you can return parameters from the rule to augment that information. This enables the user to build historical audit trails, answering questions like “Who changed that data, and why was that allowed at the time?” -
auval_office
can consider context.The
authorize
function has an optionalcontext
parameter, where you can provide a map of additional information items to consider when making an authorization decision:My.Policy.authorizer(subject, object, action, %{moon_in_house: :seventh})
auval_office
also includes afetch
er facility, that enables you to fetch necessary context values at authorization time. Just include afetch
in your policy:defmodule My.Policy do use AuvalOffice.Policy fetch :fetch_user_group_memberships, :groups, subject: %User{id: id} do groups = Accounts.get_groups_by_user_id(id) {:ok, groups} end rule ... end
Before evaluating the policy,
auval_office
will check if a:groups
item is present in the context, and if not, will call the fetcher you defined to add the:groups
to the context.