Ash DataLayer for Apache AGE graph database.

Stores Ash resources as vertices in an AGE graph within PostgreSQL. Uses the existing Ecto.Repo connection pool — no new database driver. All dynamic values use parameterized queries for safety.

DSL

use Ash.Resource,
  data_layer: AshAge.DataLayer

age do
  graph :my_graph
  repo MyApp.Repo
  label :MyLabel     # optional, defaults to the module's short name
  skip [:computed]   # optional, attributes excluded from AGE properties
  sensitive [:ssn]   # optional, classified attributes (binary-storage or skipped)
  rls_guc "myapp.tenant_id"  # optional, :attribute-only DB-enforced RLS backstop
  # tenant_graph {MyApp.Graphs, :for_tenant, []}  # optional, :context graph-name override

  edge :related_to do
    label :RELATES_TO
    direction :outgoing
    destination MyApp.OtherResource
  end
end

Capabilities

Supports :read, :create, :update, :destroy, :bulk_create, :filter (eq/not_eq/gt/lt/gte/lte/in/is_nil, boolean and nested expressions), :sort, :limit, :offset, :transact, :multitenancy (:attribute and :context), :composite_primary_key, and :changeset_filter. Not supported: :upsert, aggregates, and lateral joins. One subtlety: binary-storage attributes are unsortable (can?({:sort, :binary}) is false) because the stored $age64$-tagged base64 form is not byte-order-preserving — sorting on one raises Ash.Error.Query.UnsortableField at query build.

age

Configuration for the AGE graph data layer

Nested DSLs

Options

NameTypeDefaultDocs
graphatomThe AGE graph name (must be a valid identifier)
repoatomThe Ecto.Repo module to use for database access
labelatom | String.tVertex label in the graph. Defaults to the resource's short module name.
skiplist(atom)[]List of attribute names to exclude from AGE vertex properties
sensitivelist(atom)[]Attribute names classified as sensitive. Fail-closed verifier check (AshAge.DataLayer.Verifiers.ValidateSensitive): each must be binary-storage-typed (app-side-encrypted bytes) or listed in skip. ash_age verifies the type SHAPE — encrypting is the host app's job. Verifier errors are compiler diagnostics; build with --warnings-as-errors to make them blocking.
tenant_graphmfaMFA applied as apply(m, f, [tenant | a]) returning the AGE graph name for a :context tenant. Defaults to a built-in collision-free encoder.
rls_gucString.tOpt into DB-enforced RLS: the PostgreSQL custom GUC (e.g. "ash_age.tenant_id") ash_age sets per read/write so RLS policies scope by tenant. :attribute only.

age.edge

edge name

Defines an edge mapping from this vertex to another

Arguments

NameTypeDefaultDocs
nameatomRelationship name (must match an Ash relationship)

Options

NameTypeDefaultDocs
labelatomEdge label in the graph (e.g., :RELATES_TO)
destinationatomDestination resource module
direction:outgoing | :incoming | :both:outgoingEdge direction
propertieslist(atom)[]Optional edge property keys, set from same-named action arguments.

Introspection

Target: AshAge.Edge