Advice for policy simplicity
Hey, I'm just getting into policies and wanted some advice on how to make this easy to work with.
So I want all code interface actions to permit calling any function from the application itself or IEx. But I want all external callers to be verified for access. Is this a good start?
If I understand it correctly, this means that if an actor is absent or authorize? is false, the caller is authorized. If an actor is present we check if they are an admin. The Admin UI always disables authorization I think, and if I don't give any extra arguments in my code interface functions then they will go through too.
Is this a good design? What is the performance impact? Or would it better to make separate actions that are only exposed externally and not in the code interface and authorize only those?
11 Replies
🤔
Out of curiosity, why do you want all code interface calls to automatically authorize?
Is it because everything is either an API or its internal?
If so you could do something like this instead:
Mainly because I think the app should have access to everything it needs internally
Yeah but your app can always provide
authorize?: false
on its calls to resources too
Then you have something explicit that is bypassing authorization, instead of something implicit
Also this:
Is very scary
it means if somehow someone made it past your authentication layer to call actions w/o a user, that they will be allowed to do whatever they wantYeah that's a good point. I'm mainly trying to figure out what is a good balance. Obviously all external requests should be authorized (unless coming from the admin UI), but I also didn't want to have to deal with authorization from within the code itself...
There are various other options
using
authorize?: false
on your internal calls
Alternatively, you can have a special type of actor that you set for internal calls
actor: %SystemUser{}
I'm not discounting that this is just a me problem. Maybe this is the wrong perspective and authorization should always be explicitly disabled or visible 🤔
Solution
This option:
define :foo, default_options: [authorize?: false]
is a middle ground to me
A bit annoying to add that to all your code interface calls
But makes it perfectly clear what does/doesn't authorize in your system with something that is easy to change on a case-by-case basis.
Yeah thanks for that. I'll stick to that for now and see how it feels. I'd like to keep things simple internally, but ofc without accidentally exposing something externally without authorization 😅.
Speaking of which, how do you check the type or struct of the actor?
Do we just check the hidden
__struct__
field?Pretty much, yes
well, I'd make a custom check
and pattern match in the simple check