Skip to content

Commit d3b5daf

Browse files
sungwyMonkeyCanCode
authored andcommitted
auth: Refactor AuthorizationRequest Into Explicit Shapes (apache#4409)
1 parent 68434c5 commit d3b5daf

17 files changed

Lines changed: 791 additions & 392 deletions

extensions/auth/opa/impl/src/main/java/org/apache/polaris/extension/auth/opa/OpaPolarisAuthorizer.java

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,21 @@
4040
import org.apache.hc.core5.http.io.entity.StringEntity;
4141
import org.apache.iceberg.exceptions.ForbiddenException;
4242
import org.apache.polaris.core.auth.AuthorizationDecision;
43+
import org.apache.polaris.core.auth.AuthorizationIntent;
4344
import org.apache.polaris.core.auth.AuthorizationRequest;
4445
import org.apache.polaris.core.auth.AuthorizationState;
4546
import org.apache.polaris.core.auth.PathSegment;
4647
import org.apache.polaris.core.auth.PolarisAuthorizableOperation;
4748
import org.apache.polaris.core.auth.PolarisAuthorizer;
4849
import org.apache.polaris.core.auth.PolarisPrincipal;
4950
import org.apache.polaris.core.auth.PolarisSecurable;
51+
import org.apache.polaris.core.auth.PolicyAttachmentAuthorizationIntent;
52+
import org.apache.polaris.core.auth.PrivilegeGrantAuthorizationIntent;
53+
import org.apache.polaris.core.auth.RenameAuthorizationIntent;
54+
import org.apache.polaris.core.auth.RoleAssignmentAuthorizationIntent;
55+
import org.apache.polaris.core.auth.RootPrivilegeGrantAuthorizationIntent;
56+
import org.apache.polaris.core.auth.SingleTargetAuthorizationIntent;
57+
import org.apache.polaris.core.auth.TargetlessAuthorizationIntent;
5058
import org.apache.polaris.core.entity.PolarisBaseEntity;
5159
import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper;
5260
import org.apache.polaris.core.persistence.ResolvedPolarisEntity;
@@ -117,17 +125,52 @@ public void resolveAuthorizationInputs(
117125
@NonNull
118126
public AuthorizationDecision authorize(
119127
@NonNull AuthorizationState authzState, @NonNull AuthorizationRequest request) {
120-
boolean allowed =
121-
queryOpa(
122-
buildOpaAuthorizationInput(
123-
request.getPrincipal(),
124-
request.getOperation(),
125-
toResourceEntitiesFromSecurables(request.getTargets()),
126-
toResourceEntitiesFromSecurables(request.getSecondaries())));
127-
return allowed
128-
? AuthorizationDecision.allow()
129-
: AuthorizationDecision.deny(
130-
"OPA denied authorization for " + request.formatForAuthorizationMessage());
128+
for (AuthorizationIntent intent : request.intents()) {
129+
PolarisAuthorizableOperation operation = intent.getOperation();
130+
List<ResourceEntity> targets;
131+
List<ResourceEntity> secondaries;
132+
switch (intent) {
133+
case TargetlessAuthorizationIntent ignored -> {
134+
targets = List.of();
135+
secondaries = List.of();
136+
}
137+
case SingleTargetAuthorizationIntent singleTargetIntent -> {
138+
targets = toResourceEntitiesFromSecurable(singleTargetIntent.target());
139+
secondaries = List.of();
140+
}
141+
case RenameAuthorizationIntent renameIntent -> {
142+
targets = toResourceEntitiesFromSecurable(renameIntent.from());
143+
secondaries = toResourceEntitiesFromSecurable(renameIntent.to());
144+
}
145+
case PolicyAttachmentAuthorizationIntent policyAttachmentIntent -> {
146+
targets = toResourceEntitiesFromSecurable(policyAttachmentIntent.policy());
147+
secondaries = toResourceEntitiesFromSecurable(policyAttachmentIntent.attachedTo());
148+
}
149+
case RoleAssignmentAuthorizationIntent roleAssignmentIntent -> {
150+
targets = toResourceEntitiesFromSecurable(roleAssignmentIntent.role());
151+
secondaries = toResourceEntitiesFromSecurable(roleAssignmentIntent.assignee());
152+
}
153+
case PrivilegeGrantAuthorizationIntent privilegeGrantIntent -> {
154+
targets = toResourceEntitiesFromSecurable(privilegeGrantIntent.grantTarget());
155+
secondaries = toResourceEntitiesFromSecurable(privilegeGrantIntent.grantee());
156+
}
157+
case RootPrivilegeGrantAuthorizationIntent rootPrivilegeGrantIntent -> {
158+
targets = List.of();
159+
secondaries = toResourceEntitiesFromSecurable(rootPrivilegeGrantIntent.grantee());
160+
}
161+
}
162+
boolean allowed =
163+
queryOpa(
164+
buildOpaAuthorizationInput(request.principal(), operation, targets, secondaries));
165+
if (!allowed) {
166+
return AuthorizationDecision.deny(
167+
"OPA denied authorization for principal="
168+
+ request.principal().getName()
169+
+ " operation="
170+
+ operation);
171+
}
172+
}
173+
return AuthorizationDecision.allow();
131174
}
132175

133176
/**
@@ -296,9 +339,9 @@ private ImmutableContext buildContext() {
296339

297340
private ImmutableResource buildResource(
298341
List<ResourceEntity> targets, List<ResourceEntity> secondaries) {
299-
// Backward compatibility: keep the existing OPA input shape with separate target and
300-
// secondary lists. Future work can align this with AuthorizationTargetBinding semantics
301-
// using binding tuples like [(target, secondary), ...].
342+
// Keep the existing OPA input shape by always emitting target and secondary lists, using
343+
// empty lists when an intent does not carry that slot. Future work can revisit the payload
344+
// shape if OPA starts consuming intent subtype distinctions directly.
302345
return ImmutableResource.builder().targets(targets).secondaries(secondaries).build();
303346
}
304347

@@ -361,17 +404,8 @@ private List<ResourceEntity> toResourceEntitiesFromResolvedPaths(
361404
return entities;
362405
}
363406

364-
@NonNull
365-
private List<ResourceEntity> toResourceEntitiesFromSecurables(
366-
@Nullable List<PolarisSecurable> securables) {
367-
if (securables == null || securables.isEmpty()) {
368-
return List.of();
369-
}
370-
371-
List<ResourceEntity> entities = new ArrayList<>();
372-
for (PolarisSecurable securable : securables) {
373-
entities.add(buildResourceEntity(securable));
374-
}
375-
return entities;
407+
private List<ResourceEntity> toResourceEntitiesFromSecurable(
408+
@Nullable PolarisSecurable securable) {
409+
return securable == null ? List.of() : List.of(buildResourceEntity(securable));
376410
}
377411
}

0 commit comments

Comments
 (0)