PermitEx can protect JSON APIs through Plug.
Scope Setup
Your authentication plug should assign a scope before PermitEx guards run:
def call(conn, _opts) do
user = load_user_from_token(conn)
scope = PermitEx.Scope.for_user(user)
assign(conn, :current_scope, scope)
endFor scoped SaaS APIs:
workspace = load_workspace(conn)
scope = PermitEx.Scope.for_user(user, workspace)
assign(conn, :current_scope, scope)Router Usage
pipeline :api_auth do
plug MyAppWeb.ApiAuth
end
pipeline :orders_write do
plug PermitEx.Plug.RequirePermission, "orders:manage"
end
scope "/api", MyAppWeb do
pipe_through [:api_auth, :orders_write]
post "/orders", OrderController, :create
endJSON Errors
By default, unauthorized API requests return:
{"error":"forbidden"}with status 403.
Customize the response:
plug PermitEx.Plug.RequireAuthorization,
permission: "orders:manage",
status: 403,
body: ~s({"code":"forbidden","message":"Missing permission"}),
content_type: "application/json"Role Checks
plug PermitEx.Plug.RequireRole, "admin"Multiple Checks
Require all permissions:
plug PermitEx.Plug.RequireAuthorization,
all_permissions: ["orders:view", "orders:manage"]Require any permission:
plug PermitEx.Plug.RequireAuthorization,
any_permissions: ["orders:manage", "settings:manage"]Combine roles and permissions:
plug PermitEx.Plug.RequireAuthorization,
role: "admin",
permission: "orders:manage"Resource Policies
RBAC checks whether the scope has a permission. If an endpoint also needs
resource-level authorization, use PermitEx.allowed?/4 with a policy:
defmodule MyApp.OrderPolicy do
@behaviour PermitEx.Policy
def authorize(scope, order, _opts) do
scope.context_id == order.workspace_id
end
end
PermitEx.allowed?(scope, "orders:manage", order, policy: MyApp.OrderPolicy)