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
@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")
@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: truein opts (explicit escape hatch):ecto_queryvalues:preloador: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).