Core: Remove AuthorizationTargetBinding in favor of direct resource lists#4201
Core: Remove AuthorizationTargetBinding in favor of direct resource lists#4201flyrain wants to merge 2 commits into
Conversation
Remove the AuthorizationTargetBinding interface entirely and replace it with a simpler two-list API that naturally expresses 1:N relationships in authorization operations. Problem: The binding interface forced 1:1 pairing between target and secondary resources, but many operations have 1:N cardinality. For example, attaching ONE policy to MULTIPLE tables required duplicating the policy across multiple bindings, which was then immediately flattened to separate lists. Solution: Use direct factory method with two lists: - targets: resources where targetPrivileges are checked - secondaries: resources where secondaryPrivileges are checked Benefits: - Simpler API with no intermediate wrapper objects - Naturally supports any cardinality (1:1, 1:N, N:M) - Directly maps to RbacOperationSemantics structure - No duplication for batch operations Changes: - AuthorizationRequest: Use of(principal, op, targets, secondaries) API only - AuthorizationTargetBinding: Deleted entire interface - All tests: Updated to use new direct list API - OpaPolarisAuthorizer: Updated comment reference
| * | ||
| * <p><b>Examples:</b> | ||
| * <ul> | ||
| * <li>{@code ATTACH_POLICY_TO_TABLE}: targets=[policy], secondaries=[table1, table2, ...] |
There was a problem hiding this comment.
I'm looking at the OPEN API spec to understand which APIs support multiple targets and secondaries, and Attach and Detach policy API seem to only support a single table-like target today:
polaris/spec/polaris-catalog-apis/policy-apis.yaml
Lines 583 to 628 in 6e24fb6
There was a problem hiding this comment.
Is 1->N mapping of targets to secondaries used used in detach-all option of dropPolicy?
There was a problem hiding this comment.
We don't do that now. I think it's a potential use case. Removed the doc to avoid confusion
There was a problem hiding this comment.
Yes, I think my comment came in a bit late - I was working on a stale branch and you beat me to it :)
| * <p><b>Examples:</b> | ||
| * <ul> | ||
| * <li>{@code ATTACH_POLICY_TO_TABLE}: targets=[policy], secondaries=[table1, table2, ...] | ||
| * <br>Checks POLICY_ATTACH on policy, TABLE_ATTACH_POLICY on each table |
There was a problem hiding this comment.
I’m not fully convinced about allowing arbitrary M → N mappings between targets and secondaries.
When we pass a non-unique list of M targets and N secondaries, what exactly are we intending to evaluate?
- Are we expecting
ATTACH_POLICY_TO_TABLEto be evaluated across the full Cartesian product (M×N)? - Or are we treating the two lists independently, where the authorization engine checks all
Mtargets and allNsecondaries without any explicit pairing semantics?
If the only non-1:1 use case we care about is 1 → N (e.g., one policy attached to multiple tables), we could instead keep the semantics explicit by constructing AuthorizationTargetBinding entries per pair and duplicating the policy and associating it with each secondary target. That makes the evaluation model unambiguous and avoids introducing implicit M × N behavior.
There was a problem hiding this comment.
As I said here #4201 (comment), this PR is nowhere to promote N:M relationship, although it is possible. This PR is to avoid mandatory 1:1 mapping between targets and secondaries. But let me know if there are solid use case to enforce 1:1 mapping. I mighty miss some discussions.
There was a problem hiding this comment.
I gave this a bit more thought, and given the impact on PolarisAuthorization implementations, it probably makes sense to continue the discussion on the mailing list.
I’ve responded on the DISCUSS thread you started @flyrain - looking forward to continuing the conversation there with the broader community.
|
Thanks for the PR @flyrain - I added some comments. I’d like to better understand the current use cases for M → N mappings between targets and secondaries to form a clearer opinion on which semantics we should adopt. |
Here are potential use cases, to grant a groups of privileges to multiple catalog roles. I understand we don't do that now. This PR itself also isn't intentionally promote this use case. Instead, it removes the enforcement of strictly 1:1 mapping brought by the binding class. |
dimas-b
left a comment
There was a problem hiding this comment.
From my POV making this SPI change without a concrete use case is going to be confusing. At the same time looking at previous comments, it does not appear that we have a concrete use case ATM 🤔
| @Nonnull PolarisAuthorizableOperation operation, | ||
| @Nonnull List<AuthorizationTargetBinding> targetBindings) { | ||
| @Nonnull List<PolarisSecurable> targets, | ||
| @Nonnull List<PolarisSecurable> secondaries) { |
There was a problem hiding this comment.
What is the intended semantics of the relationship between targets and secondaries?
If it is group-to-group association (N:M), how is the authorizer supposed to know the meaning of each of the targets and secondaries in relation to the operation? Should it check each target with respect to each secondary?
| * @param principal the principal requesting authorization | ||
| * @param operation the operation to authorize | ||
| * @param targets resources where target privileges will be checked (may be empty) | ||
| * @param secondaries resources where secondary privileges will be checked (may be empty) |
There was a problem hiding this comment.
privileges is a concept of the default (internal) Polaris RBAC model. It may not apply to other Authorizer types.
IIRC, If targets and secondaries form a non-trivial (size > 1) set, I believe a more coherent approach would be for the caller to perform multiple authorization checks for each |
|
Hi @dimas-b, thanks for the review, as we discussed in the dev mailing thread: https://lists.apache.org/thread/o5hntqfvfhn5z9t78480nplpypddg200. I think it is less about whether the SPI can support it, and more about whether the current modeling (binding vs two lists) makes the intended My motivation for the simpler model is to avoid over-constraining the API to 1:1 bindings while keeping the semantics flexible and future-proof. Even if today’s use cases look mostly 1:1, I’m hesitant to encode that assumption into the model. I'm also open to make the evaluation semantics explicit (independent vs pairwise), rather than relying on the shape of the API to imply it. Curious what you think. |
I'm OK with a discussion on doc. Can we share the meeting notes and doc links in the dev mailing list first? I couldn't find it there. |
|
General Authorizer Sync thread: Minutes doc: Last meeting : |
|
This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
|
Close this due to the change in #4409 |
Remove the
AuthorizationTargetBindinginterface and replace it with a simpler two-list API that naturally expresses 1:N relationships in authorization operations.Problem: The binding interface forced 1:1 pairing between target and secondary resources, but many operations have 1:N cardinality. For example, attaching ONE policy to MULTIPLE tables required duplicating the policy across multiple bindings, which was then immediately flattened to separate lists.
Solution: Use direct factory method with two lists:
Benefits:
RbacOperationSemanticsstructure, which configs privileges on both target securables and secondary securables for each operation, while not restricts the mappings between them.Please note that: the
AuthorizationTargetBindinginterface was introduced recently without affecting any existing Polaris version. It's safe to remove it now instead of using a deprecation process.Checklist
CHANGELOG.md(if needed)site/content/in-dev/unreleased(if needed)