How to write a policy to ensure the user belongs to the tenant through a membership relation?
I have read many examples on multitenancy implementation with Ash, but most of these examples assume that the user belongs to one tenant.
In my case, a user can belong to one or more tenants and can switch from one to another using a select list.
We therefore have three resources, Organization, User, and Membership, to make the connection. Our application mainly uses a JSON API where we pass an authentication token in each request, as well as a custom X-Org-Id header with the current tenant ID the user selected.
I would like to create a policy that ensures that the user belongs to the organization through the Membership relationship.
I thought about using the
relates_to_actor_via function (https://hexdocs.pm/ash/Ash.Policy.Check.Builtins.html#relates_to_actor_via/2), but it doesn't work when creating a resource. I understand this restriction if it depends on the content of the resource, but that's not the case here.
This use case seems standard to me, so I'm thinking I'm probably missing something. Any ideas on how I could do this?
Edit: Whitout that check, it means that the User could create ressource under Organization that he does not belongs to, correct?Solution:Jump to solution
You should be able to create a SimpleCheck that can confirm that the actor has a membership for the tenant though: https://hexdocs.pm/ash/Ash.Policy.SimpleCheck.html#content
10 Replies
Based on my exp. it will require writing a custom
FilterCheck . I was dealing with something similar here - https://discord.com/channels/711271361523351632/1418525578306257007 .@Geril thanks to point me to your case !
I also tried something similar with
exist :
Unfortunatly, it generates this error: Data layer does not support unrelated exists expressions
Indeed, the Membership is not a direct relation of the Ressource.
Another solution is to ensure this constraint at the controller/api level.For create actions, inline checks referencing related data cannot be used, see the "Inline checks" subsection here for more info: https://hexdocs.pm/ash/policies.html#types-of-checks
Solution
You should be able to create a SimpleCheck that can confirm that the actor has a membership for the tenant though: https://hexdocs.pm/ash/Ash.Policy.SimpleCheck.html#content
Simple check is exactly what I was looking for. At the moment, with my use case, I believe I can stay with SimpleCheck even for update and other actions.
Here is the check:
The
memberships relation has been preloaded before.This article (unfrotunatly behind the paywall of medium :() explains in details how to do what I wanted: https://medium.com/@lambert.kamaro/part-16-understanding-authorization-in-ash-framework-7c12160535b8
Medium
Part 16 :  Understanding Authorization in Ash Framework
Ash Framework for Phoenix Developers
Freeium
**freedium
Whaaat?! Why am I only finding this out now?! 😱 So many thanks! I'm going to share this treasure with my colleagues right away.
Here is the link for the same article without a paywall.
Enjoy.
https://medium.com/@lambert.kamaro/part-16-understanding-authorization-in-ash-framework-7c12160535b8?sk=71afced8909910e2ac05c6f6e7aae8fc
Medium
Part 16 :  Understanding Authorization in Ash Framework
Ash Framework for Phoenix Developers