Sigra.Organizations.Query (Sigra v1.20.0)

Copy Markdown View Source

Tenant-scoping query helpers for organization-aware schemas.

for_org/2 is the primary enforcement layer against cross-tenant data leaks (Pitfall O-1). maybe_enforce_org_scope/4 provides defense-in-depth via the generated Repo's prepare_query/3 callback (D-14).

Summary

Functions

Scopes a queryable to a specific organization.

Defense-in-depth tenant enforcement for prepare_query/3 delegation.

Functions

for_org(queryable, org_id)

@spec for_org(Ecto.Queryable.t(), map() | binary()) :: Ecto.Query.t()

Scopes a queryable to a specific organization.

Accepts either a map with an active_organization key that has an id field (such as a %Scope{}), or a raw binary organization ID. Raises ArgumentError if the schema does not have an :organization_id field.

Examples

Sigra.Organizations.Query.for_org(Post, scope)
Sigra.Organizations.Query.for_org(Post, "org-uuid-here")

maybe_enforce_org_scope(operation, query, opts, config)

@spec maybe_enforce_org_scope(atom(), Ecto.Query.t(), keyword(), map()) ::
  {Ecto.Query.t(), keyword()}

Defense-in-depth tenant enforcement for prepare_query/3 delegation.

Checks that queries on enforced schemas include an organization_id WHERE clause. Called from the generated Repo's prepare_query/3 callback.

Skips enforcement for:

  • skip_org_check: true in opts (explicit escape hatch)
  • :ecto_query values :preload or :schema_migration
  • Non-query operations (:insert, :insert_all, :delete, :delete_all, :update, :update_all)
  • Schemas not in the enforced list

Returns {query, opts} (the prepare_query/3 return shape).