Standalone Ash Framework extension for Zanzibar / ReBAC authorization backed by Licet (embedded Postgres/Ecto), SpiceDB / Authzed (HTTP via Req), or AshAuthzed.Adapters.Memory (in-memory Licet engine).

Usage

defmodule MyApp.Accounts.User do
  use Ash.Resource,
    domain: MyApp.Accounts,
    data_layer: AshPostgres.DataLayer,
    authorizers: [Ash.Policy.Authorizer],
    extensions: [AshAuthzed]

  authzed do
    object_type "user_profile"
    adapter :licet
    adapter_opts [instance: MyApp.Licet]

    relation :owner, subject_type: "user", subject_id: :id
    relation :platform, static_subject: "platform:main"
    external_role :role, target: "platform:main", subject_type: "user", subject_id: :id

    conditional_wildcard :is_protected_admin,
      subject_type: "user",
      attribute: :role,
      in: [:admin, :super_admin]
  end

  policies do
    policy action(:read) do
      authorize_if rebac_can(:view)
    end

    policy action(:update_profile) do
      authorize_if rebac_can(:edit)
    end
  end
end

authzed

Configures Zanzibar / Authzed ReBAC tuple synchronization and policy checks.

Nested DSLs

Options

NameTypeDefaultDocs
object_typeString.tThe Zanzibar definition name for this Ash resource (e.g. "user_profile").
actor_typeString.t"user"The Zanzibar definition name for actors (defaults to "user").
id_attributeatom:idThe primary key attribute on the resource used for object IDs.
adapteratom:licetThe ReBAC adapter to use (:licet, :spicedb_http, :memory, or a custom module).
adapter_optskeyword[]Options forwarded to the configured adapter (e.g. [instance: MyApp.Licet]).
schema_pathString.tPath to the .zed or .yaml validation file used for compile-time schema drift verification.
from_zedString.t | booleanfalsePath to the .zed schema (or true to use schema_path) to derive relations and policies directly from the Zed definition. Note: from_zed auto-derives single-subject relations (:<relation>_id); union or subject-set relations (user | group#member) should be explicitly overridden in the authzed DSL block.
definitionString.tThe definition name in the .zed schema to derive from (defaults to object_type).
derive_relationsbooleantrueWhether to automatically derive AshAuthzed relations from the Zed definition.
derive_policiesboolean | keyword | mapfalseWhether to automatically derive Ash policies from Zed permissions. Can be true (standard mappings) or a custom keyword/map mapping (e.g. [view: :read, edit: :update]).

authzed.relation

relation name

Declares a direct relationship tuple synced on create, update, and destroy.

Arguments

NameTypeDefaultDocs
nameatomThe Zanzibar relation name on this object type.

Options

NameTypeDefaultDocs
subject_typeString.tThe subject type (e.g. "user").
subject_idatomThe resource attribute holding the subject ID (e.g. :id or :owner_id).
static_subjectString.tA static subject reference ("type:id"), such as "platform:main".

Introspection

Target: AshAuthzed.Relation

authzed.external_role

external_role attribute

Syncs a resource attribute as a relation on the resource itself (:self) or an external target object.

Arguments

NameTypeDefaultDocs
attributeatomThe attribute on the resource holding the role or capability name.

Options

NameTypeDefaultDocs
targetString.t | :self:selfThe target object ("type:id") on which the role relation is written, or :self (default) to target the resource instance itself ("<object_type>:<id>").
subject_typeString.t"user"The subject type.
subject_idatom:idThe attribute holding the subject ID.
role_mappingmap%{}Optional map translating attribute values to schema relation names (e.g. %{user: "member"}).

Introspection

Target: AshAuthzed.ExternalRole

authzed.conditional_wildcard

conditional_wildcard name

Syncs a wildcard tuple (object:id#relation@subject_type:*) when an attribute value matches.

Arguments

NameTypeDefaultDocs
nameatomThe relation name on this object type.

Options

NameTypeDefaultDocs
attributeatomThe attribute to inspect on the record.
inlist(any)List of attribute values for which the wildcard tuple should exist.
subject_typeString.t"user"The wildcard subject type ("user" -> "user:*").

Introspection

Target: AshAuthzed.ConditionalWildcard

rebac

Alias section for authzed.

Nested DSLs

Options

NameTypeDefaultDocs
object_typeString.tThe Zanzibar definition name for this Ash resource (e.g. "user_profile").
actor_typeString.t"user"The Zanzibar definition name for actors (defaults to "user").
id_attributeatom:idThe primary key attribute on the resource used for object IDs.
adapteratom:licetThe ReBAC adapter to use (:licet, :spicedb_http, :memory, or a custom module).
adapter_optskeyword[]Options forwarded to the configured adapter (e.g. [instance: MyApp.Licet]).
schema_pathString.tPath to the .zed or .yaml validation file used for compile-time schema drift verification.
from_zedString.t | booleanfalsePath to the .zed schema (or true to use schema_path) to derive relations and policies directly from the Zed definition. Note: from_zed auto-derives single-subject relations (:<relation>_id); union or subject-set relations (user | group#member) should be explicitly overridden in the authzed DSL block.
definitionString.tThe definition name in the .zed schema to derive from (defaults to object_type).
derive_relationsbooleantrueWhether to automatically derive AshAuthzed relations from the Zed definition.
derive_policiesboolean | keyword | mapfalseWhether to automatically derive Ash policies from Zed permissions. Can be true (standard mappings) or a custom keyword/map mapping (e.g. [view: :read, edit: :update]).

rebac.relation

relation name

Declares a direct relationship tuple synced on create, update, and destroy.

Arguments

NameTypeDefaultDocs
nameatomThe Zanzibar relation name on this object type.

Options

NameTypeDefaultDocs
subject_typeString.tThe subject type (e.g. "user").
subject_idatomThe resource attribute holding the subject ID (e.g. :id or :owner_id).
static_subjectString.tA static subject reference ("type:id"), such as "platform:main".

Introspection

Target: AshAuthzed.Relation

rebac.external_role

external_role attribute

Syncs a resource attribute as a relation on the resource itself (:self) or an external target object.

Arguments

NameTypeDefaultDocs
attributeatomThe attribute on the resource holding the role or capability name.

Options

NameTypeDefaultDocs
targetString.t | :self:selfThe target object ("type:id") on which the role relation is written, or :self (default) to target the resource instance itself ("<object_type>:<id>").
subject_typeString.t"user"The subject type.
subject_idatom:idThe attribute holding the subject ID.
role_mappingmap%{}Optional map translating attribute values to schema relation names (e.g. %{user: "member"}).

Introspection

Target: AshAuthzed.ExternalRole

rebac.conditional_wildcard

conditional_wildcard name

Syncs a wildcard tuple (object:id#relation@subject_type:*) when an attribute value matches.

Arguments

NameTypeDefaultDocs
nameatomThe relation name on this object type.

Options

NameTypeDefaultDocs
attributeatomThe attribute to inspect on the record.
inlist(any)List of attribute values for which the wildcard tuple should exist.
subject_typeString.t"user"The wildcard subject type ("user" -> "user:*").

Introspection

Target: AshAuthzed.ConditionalWildcard