Updates to Permit, Permit.Ecto, Permit.Phoenix and Permit.Absinthe: Igniter setup and plural actions


Here's what changed in Permit 0.4.0, Permit.Ecto 0.3.0, Permit.Phoenix 0.5.0 and Permit.Absinthe 0.3.0.
Overview
The Permit authorization framework continues to evolve with a fresh round of updates across all packages. The main themes of this release are zero config project setup powered by Igniter, better handling of plural vs. singular route actions in Phoenix, and a handful of bug fixes and quality of life improvements.
Igniter powered setup across the ecosystem
The biggest addition in this release is Igniter support across all four packages. Igniter is a project patching and code generation framework for Elixir that allows libraries to ship installer tasks that automatically setup the boilerplate fo you.
To get started with Permit in a new project, add igniter to your dependencies and run:
mix permit.install
With no flags, this scaffolds a base authorization setup. If you're using Phoenix, pass --phoenix to also wire up the Phoenix integration:
mix permit.install --phoenix
For Absinthe GraphQL projects, use --absinthe:
mix permit.install --absinthe
Each sub-package also ships its own installer task:
mix permit_ecto.install # Creates Authorization and Permissions modules
mix permit_phoenix.install # Patches your web module's live_view/0 macro
mix permit_absinthe.install # Patches your Absinthe schema module
The installers auto detects your Ecto repo, app module prefix and web module, so in most Phoenix projects the defaults are good enough. All options can be overridden via flags, for example:
mix permit_ecto.install \
--authorization-module MyApp.Auth \
--repo MyApp.RepoPatching existing controllers and LiveViews
Beyond initial setup, Permit.Phoenix 0.5.0 ships two additional patch tasks for progressively adopting authorization in existing projects:
mix permit.patch.controller MyAppWeb.ArticleController MyApp.Article
mix permit.patch.live_view MyAppWeb.ArticleLive.Index MyApp.Article
These tasks add use Permit.Phoenix.Controller or use Permit.Phoenix.LiveView to the target module, insert a resource_module/0 callback returning the given schema, and annotate handle_event/3 clauses with @permit_action for recognized event names like "delete", "update" and "create".
Permit.Phoenix 0.5.0: plural actions and route fixes
Fixed: :index route misclassification
Permit.Phoenix 0.4.0 introduced automatic inference of singular vs. plural actions based on route path parameters. This promoted any route whose last path segment was a parameter to singular which turned out to be wrong for :index like actions scoped by non id parameters.
For example, a path like /reports/:year/:month routed under the :index name would previously be misclassified as singular, causing Permit to load a single resource instead of a collection. In 0.5.0, :index is always treated as plural by convention, regardless of route shape.
Added: plural_actions/0 callback
For custom collection actions beyond :index, such as :feed, :search, or :list, you can now declare them explicitly via the new plural_actions/0 callback:
defmodule MyApp.Authorization.Actions do
use Permit.Phoenix.Actions, router: MyAppWeb.Router
@impl true
def plural_actions, do: [:feed, :search]
end
The callback is also available at the controller and LiveView level if you need to override it for a specific module. The same plural_actions/0 callback has been added to the core Permit.Actions behaviour, so custom integrations can take advantage of it too.
Fixed: :create action authorization
Previously, authorization for :create actions was checked against whatever record happened to be in scope, which could cause conditioned permission rules to pass unconditionally. Authorization is now always checked against a blank struct for :create (and any custom actions that group under :create), giving consistent and correct behaviour.
Added: LiveView stream options
The stream_options/0 callback, introduced in 0.3.0, can now be used to pass custom options to LiveView streams when Permit populates :loaded_resources:
@impl true
def stream_options, do: [reset: true]What's next
A few areas we're actively thinking about:
- Ash Framework integration: we have explored a bit into what it would take to use Permit as a single source of truth for codebases that include Ash and non-Ash code.
- Postgres Row-Level Security bridge: polyglot ecosystems could benefit from performing authorization at the database level, and we have considered Permit-first or Postgres-first approaches to supporting Postgres RLS in Permit. This is a complex topic that requires reasoning about ruleset versioning, Permit → Postgres ruleset propagation, and bootstrapping Permit Elixir ruleset code using Postgres RLS introspection.
- Changeset-level authorization: will help authorize creates and updates more appropriately, verifying the mutations of records through changesets.
- Phoenix LiveView + PubSub authorization: currently a gap in the usual Phoenix LiveView usage, and this would be addressed by hooking Permit into
handle_infojust like we now do withhandle_eventandhandle_paramsand introduce a standarized payload format for broadcasts, all with ease of configuration in mind.
As always, feedback, bug reports, and pull requests are welcome:
We encourage community contributions! To discuss your ideas for Permit’s development with us, you can chat with us on Elixir Slack or use GitHub Discussions to help us ideate the ecosystem’s development.
Want to power your product with Elixir? We’ve got you covered.
Related posts
Dive deeper into this topic with these related posts
You might also like
Discover more content from this category
This follow-up to our recent Permit update, analyzes the future of Elixir authorization with a look at upcoming features, optimizations, and experimental ideas that will shape how Permit evolves.
At Elixir Meetup #1, Michał Buszkiewicz shared his extensive knowledge on debugging Elixir applications.
Scaling applications can be challenging, especially when only specific parts of your app are compute-intensive.