This is an automated email from the ASF dual-hosted git repository.
roryqi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 751a5e7df9 [#9072] feat(authz): Add document and api for policy access
control (#9115)
751a5e7df9 is described below
commit 751a5e7df99bf03a22aad2d6a1668f4c4b78528d
Author: yangyang zhong <[email protected]>
AuthorDate: Thu Nov 20 11:19:37 2025 +0800
[#9072] feat(authz): Add document and api for policy access control (#9115)
### What changes were proposed in this pull request?
Add document and api for policy access control
### Why are the changes needed?
Fix: #9072
### Does this PR introduce _any_ user-facing change?
None
### How was this patch tested?
org.apache.gravitino.authorization.TestSecurableObjects
---
.../java/org/apache/gravitino/MetadataObject.java | 7 +-
.../java/org/apache/gravitino/MetadataObjects.java | 3 +-
.../apache/gravitino/authorization/Privilege.java | 7 +-
.../apache/gravitino/authorization/Privileges.java | 79 ++++++++++++++++++++++
.../authorization/TestSecurableObjects.java | 22 ++++++
docs/security/access-control.md | 17 +++++
6 files changed, 132 insertions(+), 3 deletions(-)
diff --git a/api/src/main/java/org/apache/gravitino/MetadataObject.java
b/api/src/main/java/org/apache/gravitino/MetadataObject.java
index 09824eaefe..4df271d049 100644
--- a/api/src/main/java/org/apache/gravitino/MetadataObject.java
+++ b/api/src/main/java/org/apache/gravitino/MetadataObject.java
@@ -63,7 +63,12 @@ public interface MetadataObject {
/** A model is mapped to the model artifact in ML. */
MODEL,
/** A tag is used to help manage other metadata object. */
- TAG;
+ TAG,
+ /**
+ * A policy can be associated with a metadata object for data governance
and similar purposes.
+ */
+ POLICY,
+ ;
}
/**
diff --git a/api/src/main/java/org/apache/gravitino/MetadataObjects.java
b/api/src/main/java/org/apache/gravitino/MetadataObjects.java
index 7400e37a1c..c3f7e8a7c3 100644
--- a/api/src/main/java/org/apache/gravitino/MetadataObjects.java
+++ b/api/src/main/java/org/apache/gravitino/MetadataObjects.java
@@ -74,7 +74,8 @@ public class MetadataObjects {
|| type == MetadataObject.Type.CATALOG
|| type == MetadataObject.Type.METALAKE
|| type == MetadataObject.Type.ROLE
- || type == MetadataObject.Type.TAG,
+ || type == MetadataObject.Type.TAG
+ || type == MetadataObject.Type.POLICY,
"If the length of names is 1, it must be the CATALOG, METALAKE,TAG, or
ROLE type");
Preconditions.checkArgument(
diff --git
a/api/src/main/java/org/apache/gravitino/authorization/Privilege.java
b/api/src/main/java/org/apache/gravitino/authorization/Privilege.java
index 2a53505eb1..23a7c4a2cc 100644
--- a/api/src/main/java/org/apache/gravitino/authorization/Privilege.java
+++ b/api/src/main/java/org/apache/gravitino/authorization/Privilege.java
@@ -98,7 +98,12 @@ public interface Privilege {
/** The privilege to create a tag */
CREATE_TAG(0L, 1L << 21),
/** The privilege to apply a tag */
- APPLY_TAG(0L, 1L << 22);
+ APPLY_TAG(0L, 1L << 22),
+ /** The privilege to create a policy */
+ CREATE_POLICY(0L, 1L << 23),
+ /** The privilege to apply a policy */
+ APPLY_POLICY(0L, 1L << 24),
+ ;
private final long highBits;
private final long lowBits;
diff --git
a/api/src/main/java/org/apache/gravitino/authorization/Privileges.java
b/api/src/main/java/org/apache/gravitino/authorization/Privileges.java
index b92383a027..7a85f12237 100644
--- a/api/src/main/java/org/apache/gravitino/authorization/Privileges.java
+++ b/api/src/main/java/org/apache/gravitino/authorization/Privileges.java
@@ -137,6 +137,10 @@ public class Privileges {
return CreateTag.allow();
case APPLY_TAG:
return ApplyTag.allow();
+ case APPLY_POLICY:
+ return ApplyPolicy.allow();
+ case CREATE_POLICY:
+ return CreatePolicy.allow();
default:
throw new IllegalArgumentException("Doesn't support the privilege: " +
name);
}
@@ -963,4 +967,79 @@ public class Privileges {
return type == MetadataObject.Type.METALAKE || type ==
MetadataObject.Type.TAG;
}
}
+
+ /** The privilege to create a tag */
+ public static class CreatePolicy extends GenericPrivilege<CreatePolicy> {
+ private static final CreatePolicy ALLOW_INSTANCE =
+ new CreatePolicy(Condition.ALLOW, Name.CREATE_POLICY);
+ private static final CreatePolicy DENY_INSTANCE =
+ new CreatePolicy(Condition.DENY, Name.CREATE_POLICY);
+
+ /**
+ * Constructor for GenericPrivilege.
+ *
+ * @param condition the condition of the privilege
+ * @param name the name of the privilege
+ */
+ protected CreatePolicy(Condition condition, Name name) {
+ super(condition, name);
+ }
+
+ /**
+ * @return The instance with allow condition of the privilege.
+ */
+ public static CreatePolicy allow() {
+ return ALLOW_INSTANCE;
+ }
+
+ /**
+ * @return The instance with deny condition of the privilege.
+ */
+ public static CreatePolicy deny() {
+ return DENY_INSTANCE;
+ }
+
+ @Override
+ public boolean canBindTo(MetadataObject.Type type) {
+ return type == MetadataObject.Type.METALAKE;
+ }
+ }
+
+ /** The privilege to apply policy to object. */
+ public static final class ApplyPolicy extends GenericPrivilege<ApplyPolicy> {
+
+ private static final ApplyPolicy ALLOW_INSTANCE =
+ new ApplyPolicy(Condition.ALLOW, Name.APPLY_POLICY);
+ private static final ApplyPolicy DENY_INSTANCE =
+ new ApplyPolicy(Condition.DENY, Name.APPLY_POLICY);
+
+ /**
+ * Constructor for GenericPrivilege.
+ *
+ * @param condition the condition of the privilege
+ * @param name the name of the privilege
+ */
+ ApplyPolicy(Condition condition, Name name) {
+ super(condition, name);
+ }
+
+ /**
+ * @return The instance with allow condition of the privilege.
+ */
+ public static ApplyPolicy allow() {
+ return ALLOW_INSTANCE;
+ }
+
+ /**
+ * @return The instance with deny condition of the privilege.
+ */
+ public static ApplyPolicy deny() {
+ return DENY_INSTANCE;
+ }
+
+ @Override
+ public boolean canBindTo(MetadataObject.Type type) {
+ return type == MetadataObject.Type.METALAKE || type ==
MetadataObject.Type.POLICY;
+ }
+ }
}
diff --git
a/api/src/test/java/org/apache/gravitino/authorization/TestSecurableObjects.java
b/api/src/test/java/org/apache/gravitino/authorization/TestSecurableObjects.java
index 7fad26f0e3..813ac9f4b2 100644
---
a/api/src/test/java/org/apache/gravitino/authorization/TestSecurableObjects.java
+++
b/api/src/test/java/org/apache/gravitino/authorization/TestSecurableObjects.java
@@ -182,6 +182,8 @@ public class TestSecurableObjects {
Privilege useModel = Privileges.UseModel.allow();
Privilege createTag = Privileges.CreateTag.allow();
Privilege applyTag = Privileges.ApplyTag.allow();
+ Privilege createPolicy = Privileges.CreatePolicy.allow();
+ Privilege applyPolicy = Privileges.ApplyPolicy.allow();
// Test create catalog
Assertions.assertTrue(createCatalog.canBindTo(MetadataObject.Type.METALAKE));
@@ -397,5 +399,25 @@ public class TestSecurableObjects {
Assertions.assertFalse(useModel.canBindTo(MetadataObject.Type.TOPIC));
Assertions.assertFalse(useModel.canBindTo(MetadataObject.Type.FILESET));
Assertions.assertFalse(useModel.canBindTo(MetadataObject.Type.ROLE));
+
+
Assertions.assertTrue(createPolicy.canBindTo(MetadataObject.Type.METALAKE));
+ Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.POLICY));
+
Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.CATALOG));
+ Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.SCHEMA));
+ Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.TABLE));
+ Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.MODEL));
+ Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.TOPIC));
+
Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.FILESET));
+ Assertions.assertFalse(createPolicy.canBindTo(MetadataObject.Type.ROLE));
+
+ Assertions.assertTrue(applyPolicy.canBindTo(MetadataObject.Type.METALAKE));
+ Assertions.assertTrue(applyPolicy.canBindTo(MetadataObject.Type.POLICY));
+ Assertions.assertFalse(applyTag.canBindTo(MetadataObject.Type.CATALOG));
+ Assertions.assertFalse(applyTag.canBindTo(MetadataObject.Type.SCHEMA));
+ Assertions.assertFalse(applyTag.canBindTo(MetadataObject.Type.TABLE));
+ Assertions.assertFalse(applyTag.canBindTo(MetadataObject.Type.MODEL));
+ Assertions.assertFalse(useModel.canBindTo(MetadataObject.Type.TOPIC));
+ Assertions.assertFalse(useModel.canBindTo(MetadataObject.Type.FILESET));
+ Assertions.assertFalse(useModel.canBindTo(MetadataObject.Type.ROLE));
}
}
diff --git a/docs/security/access-control.md b/docs/security/access-control.md
index 1a6d9a28a0..23d1a0c8f1 100644
--- a/docs/security/access-control.md
+++ b/docs/security/access-control.md
@@ -272,6 +272,13 @@ DENY `WRITE_FILESET` won‘t deny the `READ_FILESET`
operation if the user has t
| CREATE_TAG | Metalake | Create a tag
|
| APPLY_TAG | Metalake, Tag | Associate tags with metadata
objects. |
+### Policy privileges
+
+| Name | Supports Securable Object | Operation
|
+|---------------|---------------------------|-------------------------------------------|
+| CREATE_POLICY | Metalake | Create a policy
|
+| APPLY_POLICY | Metalake, Policy | Associate policies with metadata
objects. |
+
## Inheritance Model
Securable objects in Gravitino are hierarchical and privileges are inherited
downward.
@@ -1042,4 +1049,14 @@ The following table lists the required privileges for
each API.
| list tags for object | Permission to both list tags Requires
both permission to **list tags** and permission to **load metadata objects**.
load metadata objects is required.
|
| get tag for object | Requires both permission to **get the
tag** and permission to **load metadata objects**.
|
| associate object tags | Requires both `APPLY_TAG` permission and
permission to **load metadata objects**.
|
+| list policies for object | The owner of the metalake can see all
the policies, others can see the policies which they can load.
|
+| create policy | `CREATE_POLICY` on the metalake or the
owner of the metalake.
|
+| get policy | `APPLY_POLICY` on the metalake or
policy, the owner of the metalake or the policy.
|
+| alter policy | Must be the owner of the metalake or the
policy.
|
+| set policy | Must be the owner of the metalake or the
policy.
|
+| delete policy | Must be the owner of the metalake or the
policy.
|
+| list objects for policy | Requires both permission to **get the
policy** and permission to **load metadata objects**.
|
+| associate-object-policies | Requires both `APPLY_POLICY` permission
and permission to **load metadata objects**.
|
+| list policies for object | Requires both permission to **get the
policy** and permission to **load metadata objects**.
|
+| get policy for object | Requires both permission to **get the
policy** and permission to **load metadata objects**.
|