Multi-level Hierarchy Beyond Native Multitenancy - Need Guidance

Building an e-commerce platform with a 4-level hierarchy:
Sudo → Tenant → Seller → Stores
Sudo → Tenant → Seller → Stores
Problem: Ash's multitenancy only supports a single attribute, but I need to filter by both tenant_id AND store_id.
# Current limitation
multitenancy do
strategy :attribute
attribute :tenant_id # Can only use one
end

# But I need both:
- tenant_id filtering
- store_id filtering
# Current limitation
multitenancy do
strategy :attribute
attribute :tenant_id # Can only use one
end

# But I need both:
- tenant_id filtering
- store_id filtering
What I've tried that didn't work well: 1. Manual propagation everywhere - Had to pass actor, tenant, and context: %{store: store_id} to EVERY operation. The worst part was propagating store_id in actions - especially with manage_relationship which doesn't propagate custom context properly. 2. Using Ash's Scope - Even with the Scope pattern, I still need to manually ensure store_id is passed everywhere:
scope = %Scope{actor: seller, tenant: tenant_id, context: %{store: store_id}}
Catalog.create_product(attrs, scope: scope)
scope = %Scope{actor: seller, tenant: tenant_id, context: %{store: store_id}}
Catalog.create_product(attrs, scope: scope)
But the store_id in context isn't automatically applied like tenant_id is. 3. Custom changes for relationships - Had to replace manage_relationship with manual implementations because it doesn't propagate the full context in nested queries. Requirements: * Seller from Tenant A never sees Tenant B data * Store 1 never accesses Store 2 orders * Automatic filtering (no manual filters everywhere) * Validations need to respect both tenant and store context Questions: 1. Is there a way to make Ash treat store_id as a second level of multitenancy automatically? 2. How do you handle complex hierarchies beyond the standard tenant_id? 3. Should I be using a completely different approach for this use case? Anyone built complex multi-tenancy with Ash? Would love to see examples or patterns!
2 Replies
barnabasj
barnabasj2mo ago
This won't solve your problem as a whole, but there is a shared key in context that should be propagated everywhere also manage_relationship https://hexdocs.pm/ash/actions.html#context You can also put policies on the domain, that would make it easier to have the filter for tenant/store_id on all the actions by default.
Emanoel
EmanoelOP2mo ago
Thanks a lot for the tip! That’s really helpful — I hadn’t thought about using the domain policies for that. I’ll give it a try and see how it goes.

Did you find this page helpful?