jerryshao commented on code in PR #8136:
URL: https://github.com/apache/gravitino/pull/8136#discussion_r2283996215
##########
docs/manage-policies-in-gravitino.md:
##########
@@ -0,0 +1,443 @@
+---
+title: "Manage policies in Gravitino"
+slug: /manage-policies-in-gravitino
+date: 2025-08-04
+keyword: policy management, policy, policies, Gravitino, data governance
+license: This software is licensed under the Apache License version 2.
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+## Introduction
+
+Starting from 1.0.0, Gravitino introduces a new policy system that allows you
to manage policies for
+metadata objects. Policies are a set of rules that can be associated with a
metadata
+object for data governance and similar purposes.
+
+This document provides a brief introduction to using policies in Gravitino,
covering both the Gravitino Java client and
+REST APIs. If you want to know more about the policy system in Gravitino,
please refer to the
+Javadoc and REST API documentation.
+
+:::info
+1. Metadata objects are objects that are managed in Gravitino, such as
`CATALOG`, `SCHEMA`, `TABLE`,
+ `FILESET`, `TOPIC`, and `MODEL`. A metadata object is combined by a `type`
and a dot-separated
+ `name`. For example, a `CATALOG` object has a name "catalog1" with type
"CATALOG", a `SCHEMA`
+ object has a name "catalog1.schema1" with type "SCHEMA", a `TABLE` object
has a name
+ "catalog1.schema1.table1" with type "TABLE".
+2. Currently, `CATALOG`, `SCHEMA`, `TABLE`, `FILESET`, `TOPIC`, and `MODEL`
objects can be
+ associated with policies.
+3. Policies in Gravitino are inheritable, so listing policies of a metadata
object will also list the
+ policies of its parent metadata objects. For example, listing policies of a
`Table` will also list
+ the policies of its parent `Schema` and `Catalog`.
+4. The same policy can be associated with both parent and child metadata
objects. But when you list the
+ associated policies of a child metadata object, this policy will be
included only once in the result
+ list with `inherited` value `false`.
+:::
+
+## Policy operations
+
+### Create new policies
+
+The first step to managing policies is to create new policies. You can create
a new policy by providing a policy
+name, type, and other optional fields like comment, enabled, etc.
+
+Gravitino supports two kinds of policies: built-in policies and custom
policies.
+For built-in policies, the `policyType` starts with `system.` and the
`supportedObjectTypes` in the policy content is predefined.
+For custom policies, the `policyType` must be `custom` and the
`supportedObjectTypes` can be any combination of metadata object types.
+
+:::note
+1. The field `supportedObjectTypes` in the content is immutable after the
policy is created.
+:::
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+# Create a custom policy
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "name": "my_policy1",
+ "comment": "This is a test policy",
+ "policyType": "custom",
+ "enabled": true,
+ "content": {
+ "customRules": {
+ "rule1": 123
+ },
+ "supportedObjectTypes": [
+ "CATALOG",
+ "SCHEMA",
+ "TABLE",
+ "FILESET",
+ "TOPIC",
+ "MODEL"
+ ],
+ "properties": {
+ "key1": "value1"
+ }
+ }
+}' http://localhost:8090/api/metalakes/test/policies
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+GravitinoClient client = ...
+
+// Create a custom policy
+PolicyContent content = PolicyContents.custom(
+ ImmutableMap.of("rule1", 123),
+ ImmutableSet.of(
+ MetadataObject.Type.CATALOG,
+ MetadataObject.Type.TABLE),
+ ImmutableMap.of("key1", "value1"));
+Policy policy = client.createPolicy(
+ "my_policy1",
+ "custom",
+ "This is a test policy",
+ true /* enabled */,
+ content);
+```
+
+</TabItem>
+</Tabs>
+
+### List created policies
+
+You can list all the created policy names as well as policy objects in a
metalake in Gravitino.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+# List policy names
+curl -X GET -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/policies
+
+# List policy details
+curl -X GET -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/policies?details=true
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+GravitinoClient client = ...
+String[] policyNames = client.listPolicies();
+
+Policy[] policies = client.listPolicyInfos();
+```
+
+</TabItem>
+</Tabs>
+
+### Get a policy by name
+
+You can get a policy by its name.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+curl -X GET -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/policies/my_policy1
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+GravitinoClient client = ...
+Policy policy = client.getPolicy("my_policy1");
+```
+
+</TabItem>
+</Tabs>
+
+### Update a policy
+
+Gravitino allows you to update a policy by providing changes.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+curl -X PUT -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "updates": [
+ {
+ "@type": "rename",
+ "newName": "my_policy_new"
+ },
+ {
+ "@type": "updateComment",
+ "newComment": "This is my new policy comment"
+ },
+ {
+ "@type": "updateContent",
+ "policyType": "custom",
+ "newContent": {
+ "customRules": {
+ "rule1": 456
+ },
+ "supportedObjectTypes": [
+ "CATALOG",
+ "TABLE"
+ ],
+ "properties": {
+ "key1": "new_value1",
+ "key2": "new_value2"
+ }
+ }
+ }
+ ]
+}' http://localhost:8090/api/metalakes/test/policies/my_policy1
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+GravitinoClient client = ...
+PolicyContent newContent = PolicyContents.custom(
+ ImmutableMap.of("rule1", 456),
+ ImmutableSet.of(
+ MetadataObject.Type.CATALOG,
+ MetadataObject.Type.TABLE),
+ ImmutableMap.of("key1", "new_value1", "key2", "new_value2"));
+
+Policy policy = client.alterPolicy(
+ "my_policy1",
+ PolicyChange.rename("my_policy_new"),
+ PolicyChange.updateComment("This is my new policy comment"),
+ PolicyChange.updateContent("custom", newContent));
+```
+
+</TabItem>
+</Tabs>
+
+Currently, Gravitino supports the following policy changes:
+
+| Supported modification | JSON
| Java |
+|------------------------|----------------------------------------------------------------------|-------------------------------------------------------|
+| Rename a policy | `{"@type":"rename","newName":"policy_renamed"}`
| `PolicyChange.rename("policy_renamed")` |
+| Update a comment |
`{"@type":"updateComment","newComment":"new_comment"}` |
`PolicyChange.updateComment("new_comment")` |
+| Update policy content |
`{"@type":"updateContent","policyType":"custom","newContent":{...}}` |
`PolicyChange.updateContent("test_type", newContent)` |
+
+### Enable or disable a policy
+
+You can enable or disable a policy.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+# Disable a policy
+curl -X PATCH -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "enable": false
+}' http://localhost:8090/api/metalakes/test/policies/my_policy_new
+
+# Enable a policy
+curl -X PATCH -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "enable": true
+}' http://localhost:8090/api/metalakes/test/policies/my_policy_new
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+GravitinoClient client = ...
+// Disable a policy
+client.disablePolicy("my_policy_new");
+
+// Enable a policy
+client.enablePolicy("my_policy_new");
+```
+
+</TabItem>
+</Tabs>
+
+### Delete a policy
+
+You can delete a policy by its name.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+curl -X DELETE -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/policies/my_policy_new
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+GravitinoClient client = ...
+client.deletePolicy("my_policy_new");
+```
+
+</TabItem>
+</Tabs>
+
+## Policy associations
+
+Gravitino allows you to associate and disassociate policies with metadata
objects. Currently,
+`CATALOG`, `SCHEMA`, `TABLE`, `FILESET`, `TOPIC`, and `MODEL` objects can have
policies.
+
+### Associate and disassociate policies with a metadata object
+
+You can associate and disassociate policies with a metadata object by
providing the object type, object
+name and policy names.
+
+The request path for REST API is
`/api/metalakes/{metalake}/objects/{metadataObjectType}/{metadataObjectFullName}/policies`.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+# First, create some policies to associate
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" \
+-d '{"name": "policy1", "policyType": "custom", "supportedObjectTypes":
["CATALOG", "SCHEMA"], "content": {}}' \
Review Comment:
Do we support empty content?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]