This may be a real beginner thing to be figuring out, but I’m working on both:
- Good security practices
- Phoenix module naming
Here’s my current idea.
# Customer-scoped APIs
IndexFlow.Domains.get!(customer_id, id)
IndexFlow.Sitemaps.list(customer_id)
# System APIs
IndexFlow.Domains.Internal.get!(id)
IndexFlow.Sitemaps.Internal.bulk_update_status(ids, status)
I want this because the app is both end-user facing plus has batch jobs running on schedules. Those jobs need full access across all customers. But queries done on behalf of a customer need to be scoped to them. I want to make it obvious to me (and the default) when I’m more secure.
Now, as far as locating this code? I’ll probably create /domains/intrernal.ex
, etc. I do dislike that this will be alongside my schema files, yet it’s a context. But my module files are getting way too big as it is…
Anyone else tackle this?
I use a different endpoint for admin purpose… mostly because of client request to have a clear separation with public facing endpoint.
But my core logic stays the same.
1 Like
I’m not saying this is a great solution for you, its just one I’ve used in an absurdly secure environment - in case it helps.
HTTP call → Service Layer → Broker Layer → Data Layer
- Service layer checks that its a sane call (auth happened correctly, nothing fishy about the request) and passes it onto the Broker layer. It might format result for a particular purpose.
- Broker layer checks that the caller is allowed to make that call, has proper access to see that data, etc, and executes queries/commands against the Data Layer.
- Data Layer - think Repo calls.
Third-parties use the Service Layer, Processes use the Broker Layer.
I always pass the current Scope
as the first argument to these functions (could also be the current User
) and dispatch based on authorization rules.
1 Like