AshReplicant. Resource. Verifiers. ValidateActionMultitenancy
(AshReplicant v0.3.0)
Copy Markdown
View Source
Compile-verifier (surfaced as a Spark diagnostic; build-blocking under
--warnings-as-errors): the sink-selected actions of a multitenant replicant
resource must not declare multitenancy :bypass / :bypass_all.
The sink mirrors through the host's PRIMARY create (upsert, and the SCD2 version-open),
PRIMARY destroy, and — for an SCD2 resource — the configured history_close_action.
It also READS through the PRIMARY read: the SCD2 close (Ash.bulk_update) and mirror
delete (Ash.bulk_destroy) build an Ash.Query.do_filter over the primary read to
match the rows they update/delete, and under the stream strategy that read must be
tenant-scoped. Ash keys the tenant scoping on each action's :multitenancy mode:
:enforce(default) — force-sets/filters the discriminator AND requires a tenant → scoped;:allow_global— force-sets/filters when a tenant is present (the sink ALWAYS passes a resolved tenant, fail-closed on nil/false) → scoped;:bypass/:bypass_all— neither scopes nor requires → the tenant the sink passes is silently ignored and the write/read spans tenants (fail-open isolation). On a read this lets abulk_update/bulk_destroymatch and mutate ANOTHER tenant's rows.
So this verifier rejects :bypass / :bypass_all on any sink-selected action (primary
read/create/destroy + SCD2 close) of a multitenant resource. It fires only when the resource
declares multitenancy (a non-multitenant resource has no tenant to bypass). A non-sink action's
mode is the host's business and is not checked. Messages are value-free — they name the action
and its declared mode, never a row value.