Permission introspection helpers for various use cases.
This module provides functions to query and inspect permissions at runtime, useful for:
- Admin UI: Display what permissions a user has
- Permission Management: List all available permissions for a resource
- Debugging: Check why access is allowed or denied
- API Responses: Return allowed actions to clients
Functions Overview
| Function | Use Case | Returns |
|---|---|---|
actor_permissions/3 | Admin UI | All permissions with status |
available_permissions/1 | Permission management | All possible permissions |
can?/4 | Debugging | :allow or :deny with details |
allowed_actions/3 | API response | List of allowed actions |
permissions_for/3 | Raw access | Permission strings from resolver |
Examples
# Admin UI: What can this user do?
Introspect.actor_permissions(Post, current_user)
# => [%{action: "read", allowed: true, scope: "always", field_groups: []}, ...]
# Permission management: What permissions exist?
Introspect.available_permissions(Post)
# => [%{permission_string: "post:*:read:always", action: "read", scope: "always", field_group: nil}, ...]
# Debugging: Can user do this?
Introspect.can?(Post, :update, user)
# => {:allow, %{scope: "own", instance_ids: nil, field_groups: []}}
# API: What actions are available?
Introspect.allowed_actions(Post, user)
# => [:read, :create, :update]
Summary
Functions
Returns all permissions for a resource with their status for a given actor.
Returns list of allowed actions for an actor.
Returns all available permissions for a resource.
Simple permission check returning :allow or :deny with details.
Returns raw permissions from the resolver for an actor.
Types
Functions
@spec actor_permissions(module(), term(), keyword()) :: [permission_status()]
Returns all permissions for a resource with their status for a given actor.
Useful for Admin UI to display what a user can or cannot do.
Options
:context- Additional context to pass to the resolver
Examples
iex> Introspect.actor_permissions(Post, %{role: :editor})
[
%{action: "read", allowed: true, scope: "always", denied: false, instance_ids: nil, field_groups: []},
%{action: "update", allowed: true, scope: "own", denied: false, instance_ids: nil, field_groups: []},
%{action: "destroy", allowed: false, scope: nil, denied: false, instance_ids: nil, field_groups: []}
]
Returns list of allowed actions for an actor.
Useful for API responses to tell clients what they can do.
Options
:context- Additional context to pass to the resolver:detailed- Whentrue, returns detailed info instead of just action names
Examples
iex> Introspect.allowed_actions(Post, %{role: :editor})
[:read, :create, :update]
iex> Introspect.allowed_actions(Post, %{role: :editor}, detailed: true)
[
%{action: :read, scope: "always", instance_ids: nil, field_groups: []},
%{action: :create, scope: "always", instance_ids: nil, field_groups: []},
%{action: :update, scope: "own", instance_ids: nil, field_groups: []}
]
@spec available_permissions(module()) :: [available_permission()]
Returns all available permissions for a resource.
Useful for permission management UI to show what permissions can be assigned.
Examples
iex> Introspect.available_permissions(Post)
[
%{permission_string: "post:*:read:always", action: "read", scope: "always", scope_description: nil, field_group: nil},
%{permission_string: "post:*:read:own", action: "read", scope: "own", scope_description: "...", field_group: nil},
...
]
Simple permission check returning :allow or :deny with details.
Useful for debugging authorization issues.
Options
:context- Additional context to pass to the resolver
Examples
iex> Introspect.can?(Post, :read, %{role: :editor})
{:allow, %{scope: "always", instance_ids: nil, field_groups: []}}
iex> Introspect.can?(Post, :destroy, %{role: :viewer})
{:deny, %{reason: :no_permission}}
iex> Introspect.can?(Post, :read, nil)
{:deny, %{reason: :no_actor}}
Returns raw permissions from the resolver for an actor.
Useful when you need direct access to permission strings.
Options
:context- Additional context to pass to the resolver
Examples
iex> Introspect.permissions_for(Post, %{role: :editor})
["post:*:read:always", "post:*:update:own", "post:*:create:always"]