This is an automated email from the ASF dual-hosted git repository.

jshao 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 01000c3468 [#7933] feat(doc): add user doc for policy usage (#8136)
01000c3468 is described below

commit 01000c346879bbce5953b9e3690972cc424acc0f
Author: mchades <[email protected]>
AuthorDate: Tue Aug 19 15:39:26 2025 +0800

    [#7933] feat(doc): add user doc for policy usage (#8136)
    
    ### What changes were proposed in this pull request?
    
    add user doc for policy usage
    
    ### Why are the changes needed?
    
    Fix: #7933
    
    ### Does this PR introduce _any_ user-facing change?
    
    no
    
    ### How was this patch tested?
    
    no need
---
 docs/index.md                        |   2 +
 docs/manage-policies-in-gravitino.md | 468 +++++++++++++++++++++++++++++++++++
 docs/manage-tags-in-gravitino.md     |   8 +-
 3 files changed, 474 insertions(+), 4 deletions(-)

diff --git a/docs/index.md b/docs/index.md
index 501f9375fe..c441b6665e 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -139,6 +139,8 @@ Gravitino provides governance features to manage metadata 
in a unified way. See:
 
 * [Manage tags in Gravitino](./manage-tags-in-gravitino.md): a complete guide 
to using Gravitino
   to manage tags.
+* [Manage policies in Gravitino](./manage-policies-in-gravitino.md): a 
complete guide to using Gravitino
+  to manage policies.
 * [Manage jobs in Gravitino](./manage-jobs-in-gravitino.md): a complete guide 
to using Gravitino
   to manage jobs.
 
diff --git a/docs/manage-policies-in-gravitino.md 
b/docs/manage-policies-in-gravitino.md
new file mode 100644
index 0000000000..b4c6c7f1b7
--- /dev/null
+++ b/docs/manage-policies-in-gravitino.md
@@ -0,0 +1,468 @@
+---
+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.
+
+The `enabled` field of a policy is only a display attribute that marks whether 
the policy is enabled or disabled.
+It does not affect the actual behavior or characteristics of the policy 
itself. This field is intended for 
+external presentation and does not control policy application logic in 
Gravitino.
+
+The `enabled` field can be used for various purposes, such as:
+- You may want to temporarily disable a policy for auditing or review 
purposes, without deleting it or changing its content.
+- Enabling a policy can be used to indicate that it is ready for use or has 
passed necessary approvals.
+- The `enabled` status can be used in UI filtering or reporting to distinguish 
between active and inactive policies. 
+- An external policy enforcement system can use this field to determine 
whether to execute the corresponding 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", 
+  "content": {
+    "supportedObjectTypes": ["CATALOG", "TABLE"]
+  }
+}' http://localhost:8090/api/metalakes/test/policies
+
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" \
+-d '{
+  "name": "policy2", 
+  "policyType": "custom", 
+  "content": {
+    "supportedObjectTypes": ["CATALOG", "TABLE"]
+  }
+}' http://localhost:8090/api/metalakes/test/policies
+
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" \
+-d '{
+  "name": "policy3", 
+  "policyType": "custom", 
+  "content": {
+    "supportedObjectTypes": ["CATALOG", "TABLE"]
+  }
+}' http://localhost:8090/api/metalakes/test/policies
+
+# Associate and disassociate policies with a catalog
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+  "policiesToAdd": ["policy1", "policy2"],
+  "policiesToRemove": ["policy3"]
+}' http://localhost:8090/api/metalakes/test/objects/catalog/my_catalog/policies
+
+# Associate policies with a schema
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+  "policiesToAdd": ["policy1"]
+}' 
http://localhost:8090/api/metalakes/test/objects/schema/my_catalog.my_schema/policies
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+// Assume catalog 'my_catalog' and schema 'my_catalog.my_schema' exist
+Catalog catalog = client.loadCatalog("my_catalog");
+catalog.supportsPolicies().associatePolicies(
+    new String[] {"policy1", "policy2"},
+    new String[] {"policy3"});
+
+// You need to load the schema from the catalog
+Schema schema = catalog.asSchemas().loadSchema("my_schema");
+schema.supportsPolicies().associatePolicies(new String[] {"policy1"}, null);
+```
+
+</TabItem>
+</Tabs>
+
+### List associated policies for a metadata object
+
+You can list all the policies associated with a metadata object. If a policy 
is inheritable, 
+listing policies of a metadata object will also list the policies of its 
parent metadata objects.
+
+The request path for REST API is 
`/api/metalakes/{metalake}/objects/{metadataObjectType}/{metadataObjectFullName}/policies`.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+# List policy names for a catalog
+curl -X GET -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/objects/catalog/my_catalog/policies
+
+# List policy details for a schema
+curl -X GET -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/objects/schema/my_catalog.my_schema/policies?details=true
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+Catalog catalog = client.loadCatalog("my_catalog");
+String[] policyNames = catalog.supportsPolicies().listPolicies();
+Policy[] policies = catalog.supportsPolicies().listPolicyInfos();
+
+Schema schema = catalog.asSchemas().loadSchema("my_schema");
+String[] schemaPolicyNames = schema.supportsPolicies().listPolicies();
+Policy[] schemaPolicies = schema.supportsPolicies().listPolicyInfos();
+```
+
+</TabItem>
+</Tabs>
+
+### Get an associated policy by name for a metadata object
+
+You can get an associated policy by its name for a metadata object.
+
+The request path for REST API is 
`/api/metalakes/{metalake}/objects/{metadataObjectType}/{metadataObjectFullName}/policies/{policy}`.
+
+<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/objects/catalog/my_catalog/policies/policy1
+
+curl -X GET -H "Accept: application/vnd.gravitino.v1+json" \
+http://localhost:8090/api/metalakes/test/objects/schema/my_catalog.my_schema/policies/policy1
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+Catalog catalog = client.loadCatalog("my_catalog");
+Policy policy = catalog.supportsPolicies().getPolicy("policy1");
+
+Schema schema = catalog.asSchemas().loadSchema("my_schema");
+Policy schemaPolicy = schema.supportsPolicies().getPolicy("policy1");
+```
+
+</TabItem>
+</Tabs>
+
+### List metadata objects associated with a policy
+
+You can list all the metadata objects **directly associated with** a policy.
+
+<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/policy1/objects
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+Policy policy = client.getPolicy("policy1");
+MetadataObject[] objects = policy.associatedObjects().objects();
+int count = policy.associatedObjects().count();
+```
+
+</TabItem>
+</Tabs>
+
diff --git a/docs/manage-tags-in-gravitino.md b/docs/manage-tags-in-gravitino.md
index 16a6c71322..b2272780c1 100644
--- a/docs/manage-tags-in-gravitino.md
+++ b/docs/manage-tags-in-gravitino.md
@@ -24,7 +24,7 @@ the future versions.
 :::info
 1. Metadata objects are objects that are managed in Gravitino, such as 
`CATALOG`, `SCHEMA`, `TABLE`,
    `COLUMN`, `FILESET`, `TOPIC`, `COLUMN`, `MODEL`, etc. A metadata object is 
combined by a `type` and a
-   comma-separated `name`. For example, a `CATALOG` object has a name 
"catalog1" with type
+   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", a `COLUMN` 
object has a name 
    "catalog1.schema1.table1.column1" with type "COLUMN".
@@ -32,9 +32,9 @@ the future versions.
 3. Tags in Gravitino is inheritable, so listing tags of a metadata object will 
also list the
    tags of its parent metadata objects. For example, listing tags of a `Table` 
will also list
    the tags of its parent `Schema` and `Catalog`.
-4. Same tag can be associated to both parent and child metadata objects. When 
you list the
-   associated tags of a child metadata object, this tag will be included twice 
in the result
-   list with different `inherited` values.
+4. The same tag can be associated with both parent and child metadata objects. 
But when you list the
+   associated tags of a child metadata object, this tag will be included only 
once in the result
+   list with `inherited` value `false`.
 :::
 
 ## Tag operations

Reply via email to