{"id":27741538,"url":"https://github.com/curiosum-dev/permit","last_synced_at":"2025-04-28T16:20:58.668Z","repository":{"id":60937822,"uuid":"507663245","full_name":"curiosum-dev/permit","owner":"curiosum-dev","description":"An uniform authorization library for Elixir. Supports Plug and Phoenix LiveView, aims for much more.","archived":false,"fork":false,"pushed_at":"2025-04-24T18:41:27.000Z","size":288,"stargazers_count":115,"open_issues_count":7,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-24T19:40:34.138Z","etag":null,"topics":["authorization","elixir","elixir-lang"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/curiosum-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-06-26T19:15:03.000Z","updated_at":"2025-04-24T18:41:31.000Z","dependencies_parsed_at":"2024-07-18T02:10:42.561Z","dependency_job_id":"c4635fac-ef1d-4722-9f5b-a5fae64fc2dd","html_url":"https://github.com/curiosum-dev/permit","commit_stats":{"total_commits":114,"total_committers":3,"mean_commits":38.0,"dds":"0.20175438596491224","last_synced_commit":"71466417fe9708068277f2fdf5b69d84fe17998b"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curiosum-dev%2Fpermit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curiosum-dev%2Fpermit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curiosum-dev%2Fpermit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curiosum-dev%2Fpermit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/curiosum-dev","download_url":"https://codeload.github.com/curiosum-dev/permit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251158370,"owners_count":21544950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authorization","elixir","elixir-lang"],"created_at":"2025-04-28T16:20:58.149Z","updated_at":"2025-04-28T16:20:58.656Z","avatar_url":"https://github.com/curiosum-dev.png","language":"Elixir","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/f0352656-397d-4d90-999a-d3adbae1095f\"\u003e\n\n  \u003ch1\u003ePermit\u003c/h1\u003e\n  \u003cp\u003e\u003cstrong\u003ePlain-Elixir, DSL-less, extensible authorization library for Elixir.\n\n\u003c/strong\u003e\u003c/p\u003e\n\n  [![Contact Us](https://img.shields.io/badge/Contact%20Us-%23F36D2E?style=for-the-badge\u0026logo=maildotru\u0026logoColor=white\u0026labelColor=F36D2E)](https://curiosum.com/contact)\n  [![Visit Curiosum](https://img.shields.io/badge/Visit%20Curiosum-%236819E6?style=for-the-badge\u0026logo=elixir\u0026logoColor=white\u0026labelColor=6819E6)](https://curiosum.com/services/elixir-software-development)\n  [![License: MIT](https://img.shields.io/badge/License-MIT-1D0642?style=for-the-badge\u0026logo=open-source-initiative\u0026logoColor=white\u0026labelColor=1D0642)]()\n\u003c/div\u003e\n\n\n\u003cbr/\u003e\n\n## Purpose and usage\n\nProvide a single source of truth of action permissions throughout your codebase, making use of Ecto to have your Phoenix Controllers and LiveViews authorize access to resources without having to repeat yourself.\n\nIf you join the [monorepo bandwagon](https://blog.devgenius.io/embrace-the-mono-repo-3efcd09a38f8), you should be able to nicely drop your authorization into whatever's driven by Plug (Phoenix controllers) as well as into Phoenix LiveView, and perhaps even more - because it's very likely that your codebase will use multiple frameworks to process data that requires authorization.\n\n[![Hex version badge](https://img.shields.io/hexpm/v/permit.svg)](https://hex.pm/packages/permit)\n[![Actions Status](https://github.com/curiosum-dev/permit/actions/workflows/elixir.yml/badge.svg)](https://github.com/curiosum-dev/permit/actions)\n[![Code coverage badge](https://img.shields.io/codecov/c/github/curiosum-dev/permit/master.svg)](https://codecov.io/gh/curiosum-dev/permit/branch/master)\n[![License badge](https://img.shields.io/hexpm/l/permit.svg)](https://github.com/curiosum-dev/permit/blob/master/LICENSE.md)\n\n### Configure \u0026 define your permissions\n```elixir\ndefmodule MyApp.Authorization do\n  use Permit, permissions_module: MyApp.Permissions\nend\n\ndefmodule MyApp.Permissions do\n  use Permit.Permissions, actions_module: Permit.Phoenix.Actions\n\n  def can(%{role: :admin} = user) do\n    permit()\n    |\u003e all(MyApp.Blog.Article)\n  end\n\n  def can(%{id: user_id} = user) do\n    permit()\n    |\u003e all(MyApp.Blog.Article, id: user_id)\n    |\u003e read(MyApp.Blog.Article) # allows :index and :show\n  end\n\n  def can(user), do: permit()\nend\n```\n\n### Set up your controller\n\n```elixir\ndefmodule MyAppWeb.Blog.ArticleController do\n  use MyAppWeb, :controller\n\n  use Permit.Phoenix.Controller,\n    authorization_module: MyApp.Authorization,\n    resource_module: MyApp.Blog.Article\n\n  # assumption: current user is in assigns[:current_user] - this is configurable\n\n  def show(conn, _params) do\n    # At this point, the Article has already been preloaded by Ecto and checked for authorization\n    # based on action name (:show).\n    # It's available as the @loaded_resource assign.\n\n    render(conn, \"show.html\")\n  end\n\n  def show(conn, _params) do\n    # The list of Articles accessible by current user has been preloaded by Ecto\n    # into the @loaded_resources assign.\n\n    render(conn, \"index.html\")\n  end\n\n  # Optionally, implement the handle_unauthorized/1 callback to deal with authorization denial.\nend\n```\n\n### Set up your LiveView\n```elixir\ndefmodule MyAppWeb.Router do\n  use Phoenix.Router\n  import Phoenix.LiveView.Router\n\n  live_session :authenticated, on_mount: Permit.Phoenix.LiveView.AuthorizeHook do\n    live(\"/articles\", MyAppWeb.Blog.ArticlesLive, :index)\n    live(\"/articles/:id\", MyAppWeb.Blog.ArticlesLive, :show)\n  end\nend\n\ndefmodule MyAppWeb.Blog.ArticleLive do\n  use Phoenix.LiveView\n\n  use Permit.Phoenix.LiveView,\n    authorization_module: MyAppWeb.Authorization,\n    resource_module: MyApp.Blog.Article\n\n  @impl true\n  def fetch_subject(session), do: # load current user\n\n  # Both in the mount/3 callback and in a hook attached to the handle_params event,\n  # authorization will be performed based on assigns[:live_action].\n\n  # Optionally, implement the handle_unauthorized/1 callback to deal with authorization denial.\nend\n```\n\nThe library idea was originally briefed and announced in Michal Buszkiewicz's [Curiosum](https://curiosum.com) [Elixir Meetup #5 in 2022](https://youtu.be/AvUPX6cAjzk?t=3997).\n\n\n## Roadmap\n\nAn outline of our development goals for both the \"MVP\" and further releases.\n\n### Milestone 1\n\n* Rule definition syntax\n  - [x] Defining rules for **C**reate, **R**ead, **U**pdate and **D**elete actions\n  - [x] Defining rules for arbitrarily named actions\n- [x] Authorization resolution\n  - [x] Authorizing a subject to perform a specific action on a resource type (i.e. struct module, Ecto schema)\n  - [x] Authorizing a subject to perform a specific action on a specific resource (i.e. struct, loaded Ecto record)\n* [x] Ecto integration\n  - [x] Loading and authorizing a record based on a set of params (e.g. ID) and subject\n  - [x] Building Ecto queries scoping accessible records based on subject and resource type\n* [x] Phoenix Framework integration\n  - Authorizing singular resource actions (e.g. `show`, `update`)\n    - [x] Plug / Controller\n    - [x] LiveView\n  - Preloading record (based on params) in singular resource actions and authorizing the specific record\n    - [x] Plug/Controller\n    - [x] LiveView\n  - Authorizing non-singular resource actions (e.g. `index`)\n    - [x] Plug/Controller\n    - [x] LiveView\n  - Preloading accessible records in non-singular resource actions (e.g. `index`)\n    - [x] Plug/Controller\n    - [x] LiveView\n* [x] Documentation\n  - [x] Examples of vanilla usage, Plug and Phoenix Framework integrations\n  - [x] Thorough documentation of the entire public API\n* [ ] Dependency management\n  - [x] Introduce `permit_ecto` and `permit_phoenix` libraries providing the possibility of using the library without unneeded dependencies\n\n### Further ideas\n\n* [ ] Framework adapters\n  - [x] Refactor resolver to provide a clear and straightforward way to develop library adapters\n  - [ ] Research (and possibly PoC) of mapping or extending the paradigm to support Absinthe\n  - [ ] Research on ideas of adapting to other frameworks\n* [ ] New features and improvements\n  - [ ] Explore possibilities to use compile time to improve performance (e.g. #23, #24)\n  - [ ] Better support for DBMS other than Postgres (e.g. #10)\n* [ ] Documentation\n  - [ ] Improvement of private API documentation for library developers\n  - [ ] Instructions and examples of integration with other frameworks\n\n## Installation\n\nIf [available in Hex](https://hex.pm/docs/publish), the package can be installed\nby adding `permit` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:permit, \"~\u003e 0.2.1\"}\n  ]\nend\n```\n\nDocumentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)\nand published on [HexDocs](https://hexdocs.pm). Once published, the docs can\nbe found at \u003chttps://hexdocs.pm/permit\u003e.\n\n## Contact\n\n[Curiosum](https://curiosum.com)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcuriosum-dev%2Fpermit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcuriosum-dev%2Fpermit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcuriosum-dev%2Fpermit/lists"}