-
Notifications
You must be signed in to change notification settings - Fork 340
Authorizer: expose the required level of detail #3228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| boolean requiresPrincipalRoles(); | ||
|
|
||
| boolean requiresCatalogRoles(); | ||
|
|
||
| boolean requiresResolvedEntities(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have public docs for this ?
Also to avoid breaking down stream service can we have default values as true ? downstream impl of this interface can override it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the whole interface could need some more docs. It took me quite a long time to understand that e.g. Set<PolarisBaseEntity> activatedEntities is a set of principal and catalog roles. Historically, that parameter was Set<Long> activatedGranteeIds.
Can you clarify what docs you'd like to see? Mean, "requiresXyz" pretty much tells what the implementation expects/needs in the calls to authorizeOrThrow.
I suspected that it's clear now, at least for the custom downstream implementations, that activatedEntities is
Honestly, I think this interface should be entirely replaced to untangle the hard coupling with Polaris internal roles and Polaris internal RBAC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upd: default methods are in the latest commit on this PR
| @Override | ||
| public boolean requiresPrincipalRoles() { | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean requiresCatalogRoles() { | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean requiresResolvedEntities() { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder this comes under the use case Delegated AuthZ, should we have another interface for it entirely to undertand whats required for delegation ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing to do with delegation. Just to get rid of unnecessary work to get data (principal/catalog roles, grant records) that some implementations just do not need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@singhpk234 : I'm not sure what you mean by "delegated" AuthZ 🤔 The PolarisAuthorizer interface has multiple implementations, but I do not think this is "delegation" per se... Maybe I'm missing some context.
As far as the different (two in OSS) implementations of PolarisAuthorizer are concerns, they have different requirements on the amount of input data they require for making AuthZ decisions. These new interface methods are intended (as far as I understand) to allow other Polaris classes to perform less work, if some input data is not needed by a particular authorizer.
I suppose there will be other related code changes that expose the benefits of the new methods added in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean by "delegated" AuthZ 🤔 The PolarisAuthorizer interface has multiple implementations, but I do not think this is "delegation" per se... Maybe I'm missing some context
I see, my understanding the reason why we don't use the principalRoles / catalogRoles etc as the grants etc are managed by external system which is OPA here which gives us an AuthZ decision (YES | NO) hence the Authorization is delegated here as otherwise PolarisAuthZ would have required these stuff as grants etc are done based on that. This is what i had in mind, in context of above so here is what my thought process was considering the code change :
public interface SupportsDelegatedAuthZ {
default boolean requiresPrincipalRoles() {
return false;
}
default boolean requiresCatalogRoles() {
return false;
}
default boolean requiresResolvedEntities() {
return false;
}
}OPAAuthZ implements PolarisAuthZ, SupportsDelegateAuthZ {
// overrides
}
THis way persistence who wanna optimize to not look up prinicipal role and catalog role can first check SupportsDelegateAuthZ and skip the look ups accordingly.
Again i am thinking out loud here !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Short and precise: instanceof is a no-go in CDI as it doesn't work. It would prevent making PolarisAuthorizer request scoped in the future.
The long-term solution IMO is to have a different API/SPI structure for these things, but I do not have thought about it at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@singhpk234 : Thanks for clarifying the meaning of "delegated authZ" in this context. I think I understand what you mean, although, I would not personally use the term "delegation" here as in the content of Auth N/Z it has a different meaning usually (acting on behalf of a different identity).
Re: SupportsDelegatedAuthZ the implementation you propose is mostly equivalent to the state of the code in this PR, IMHO.
However, there is a downside - as @snazy mentions, the callers would have to perform instanceof checks on the PolarisAuthorizer instances, which will complicate the code on the caller side. Plus, CDI will become much harder, because injection normally guarantees only the declared type of the variable in runtime. Sub-classing is not guaranteed to be exposed in injected objects in CDI... Sub-classes may be exposes "as is" or they may not be (e.g. proxies may be injected). All in all, this approach increases code complexity.
If you have strong reasons to avoid introducing even byte-code compatible changes to PolarisAuthorizer (as in this PR). I'd proposed to move the methods from SupportsDelegatedAuthZ into a (new) AuthorizationHints interface to be produced from PolarisAuthorizerFactory and used at call sites that can optimize execution based on the information the new interface provides.
@snazy @singhpk234 : WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strong reasons to avoid introducing even byte-code compatible changes
TBH i don't have strong concerns for introducing byte-code compatibility changes, my main consideration were the version upgrade should be smooth and the API should well documented so the downstream users can override it accordingly which i think is already addressed in the recent commit so I am good from that POV as this is definitely an integration point.
I'd proposed to move the methods from SupportsDelegatedAuthZ into a (new) AuthorizationHints interface to be produced from PolarisAuthorizerFactory and used at call sites that can optimize execution based on the information the new interface provides.
I leave this to the your better judgement ! I don't have a strong for or against opinion on this ! since the concerns i had are already addressed.
cc @HonahX can you also please weigh in on this discussion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If adding default methods to the existing interface is not a concern, my preference would be to go with the current state of this PR 🙂
Adds informative functions for `PolarisAuthorizer` call sites whether principal roles, catalog roles and resolved entities are required. This change allows call sites to skip certain lookups against the backend database for information that's not needed for authorizers. For example the OPA authorizer neither needs roles nor any grant information from `ResolvedPolarisEntity`. This change only adds the informative functions to `Authorizer` but does not add any optimization to the call sites.
b0a22cc to
d54a158
Compare
No strong objections. However, given that a bunch of code (mostly |
|
Yup, the idea is that the |
|
Hi @snazy - I took a look at this PR again after yesterday's discussion, and I now fully understand your point 😃 I'm completely in agreement with your approach. I think the question of whether the additional I am curious to hear your thoughts on the following two questions:
|
|
Based on the discussion about "detached" principals, from my POV I guess one coarse flag should be sufficient. That is, if Polaris is the RBAC engine (default), then all Principal Entities, Principal Roles, Catalog Roles need to be resolved. Otherwise, none of them need to be resolved. @snazy @sungwy @collado-mike : WDYT? |
Adds informative functions for
PolarisAuthorizercall sites whether principal roles, catalog roles and resolved entities are required.This change allows call sites to skip certain lookups against the backend database for information that's not needed for authorizers.
For example the OPA authorizer neither needs roles nor any grant information from
ResolvedPolarisEntity.This change only adds the informative functions to
Authorizerbut does not add any optimization to the call sites.