You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2025/02/10 10:01:01 UTC

(iotdb) branch master updated: Pipe: Adapted pipe metadata sync for new permission (#14775)

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

rong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 2c0f7ec033b Pipe: Adapted pipe metadata sync for new permission (#14775)
2c0f7ec033b is described below

commit 2c0f7ec033bbddea3af0fba3f877aee49fc5d14a
Author: Caideyipi <87...@users.noreply.github.com>
AuthorDate: Mon Feb 10 18:00:54 2025 +0800

    Pipe: Adapted pipe metadata sync for new permission (#14775)
---
 .../manual/enhanced/IoTDBPipeIdempotentIT.java     | 197 ++++++++++++++++++
 .../manual/enhanced/IoTDBPipeMetaIT.java}          |  86 +++++++-
 .../auto/enhanced/IoTDBPipeIdempotentIT.java       |  91 ---------
 .../request/ConfigPhysicalPlanVisitor.java         | 221 ++++++++++++++++++---
 .../confignode/manager/PermissionManager.java      |   7 +-
 .../pipe/event/PipeConfigRegionSnapshotEvent.java  |  14 +-
 .../extractor/ConfigRegionListeningFilter.java     |  84 ++++++--
 .../pipe/extractor/IoTDBConfigRegionExtractor.java |  23 ++-
 ...ConfigPhysicalPlanTablePatternParseVisitor.java |  62 ++++++
 ...peConfigPhysicalPlanTableScopeParseVisitor.java |  86 ++++++++
 ...eConfigPhysicalPlanTreePatternParseVisitor.java |  30 ++-
 ...ipeConfigPhysicalPlanTreeScopeParseVisitor.java |  80 ++++++++
 .../receiver/protocol/IoTDBConfigNodeReceiver.java | 162 ++++++++++++++-
 .../PipeConfigPhysicalPlanTSStatusVisitor.java     | 207 +++++++++++++++++--
 ...ipeConfigPhysicalPlanScopeParseVisitorTest.java | 116 +++++++++++
 ...igPhysicalPlanTablePatternParseVisitorTest.java |  25 +++
 .../schemaregion/SchemaRegionListeningFilter.java  |   8 +-
 .../options/PipeInclusionOptions.java              |  15 +-
 18 files changed, 1333 insertions(+), 181 deletions(-)

diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeIdempotentIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeIdempotentIT.java
new file mode 100644
index 00000000000..c80a67c4d4f
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeIdempotentIT.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.pipe.it.dual.tablemodel.manual.enhanced;
+
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
+import org.apache.iotdb.confignode.rpc.thrift.TCreatePipeReq;
+import org.apache.iotdb.db.it.utils.TestUtils;
+import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.MultiClusterIT2DualTableManualEnhanced;
+import org.apache.iotdb.itbase.env.BaseEnv;
+import org.apache.iotdb.pipe.it.dual.tablemodel.TableModelUtils;
+import org.apache.iotdb.pipe.it.dual.tablemodel.manual.AbstractPipeTableModelDualManualIT;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({MultiClusterIT2DualTableManualEnhanced.class})
+public class IoTDBPipeIdempotentIT extends AbstractPipeTableModelDualManualIT {
+  @Test
+  public void testCreateTableIdempotent() throws Exception {
+    testTableConfigIdempotent(Collections.emptyList(), "create table test()");
+  }
+
+  @Test
+  public void testAlterTableAddColumnIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create table test()"), "alter table test add column a id");
+  }
+
+  @Test
+  public void testAlterTableSetPropertiesIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create table test()"),
+        "alter table test set properties ttl=100");
+  }
+
+  @Test
+  public void testAlterTableDropColumnIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create table test(a id, b attribute, c int32)"),
+        "alter table test drop column b");
+  }
+
+  @Test
+  public void testDropTableIdempotent() throws Exception {
+    testTableConfigIdempotent(Collections.singletonList("create table test()"), "drop table test");
+  }
+
+  @Test
+  public void testTableCreateUserIdempotent() throws Exception {
+    testTableConfigIdempotent(Collections.emptyList(), "create user newUser 'password'");
+  }
+
+  @Test
+  public void testTableDropUserIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create user newUser 'password'"), "drop user newUser");
+  }
+
+  @Test
+  public void testTableCreateRoleIdempotent() throws Exception {
+    testTableConfigIdempotent(Collections.emptyList(), "create role newRole");
+  }
+
+  @Test
+  public void testTableDropRoleIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create role newRole"), "drop role newRole");
+  }
+
+  @Test
+  public void testTableAlterUserIdempotent3() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create user newUser 'password'"),
+        "alter user newUser set password 'passwd'");
+  }
+
+  @Test
+  public void testTableGrantRoleToUserIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Arrays.asList("create user newUser 'password'", "create role newRole"),
+        "grant role newRole to newUser");
+  }
+
+  @Test
+  public void testTableRevokeRoleFromUserIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Arrays.asList(
+            "create user newUser 'password'",
+            "create role newRole",
+            "grant role newRole to newUser"),
+        "revoke role newRole from newUser");
+  }
+
+  @Test
+  public void testTableGrantIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Collections.singletonList("create user newUser 'password'"),
+        "grant all to user newUser with grant option");
+  }
+
+  @Test
+  public void testTableRevokeIdempotent() throws Exception {
+    testTableConfigIdempotent(
+        Arrays.asList(
+            "create user newUser 'password'", "grant all to user newUser with grant option"),
+        "revoke all from user newUser");
+  }
+
+  private void testTableConfigIdempotent(final List<String> beforeSqlList, final String testSql)
+      throws Exception {
+    final String database = "test";
+    TableModelUtils.createDatabase(senderEnv, database);
+    final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
+
+    final String receiverIp = receiverDataNode.getIp();
+    final int receiverPort = receiverDataNode.getPort();
+
+    try (final SyncConfigNodeIServiceClient client =
+        (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
+      final Map<String, String> extractorAttributes = new HashMap<>();
+      final Map<String, String> processorAttributes = new HashMap<>();
+      final Map<String, String> connectorAttributes = new HashMap<>();
+
+      extractorAttributes.put("extractor.inclusion", "all");
+      extractorAttributes.put("extractor.inclusion.exclusion", "");
+      extractorAttributes.put("extractor.forwarding-pipe-requests", "false");
+      extractorAttributes.put("extractor.capture.table", "true");
+      extractorAttributes.put("extractor.capture.tree", "false");
+
+      connectorAttributes.put("connector", "iotdb-thrift-connector");
+      connectorAttributes.put("connector.ip", receiverIp);
+      connectorAttributes.put("connector.port", Integer.toString(receiverPort));
+      connectorAttributes.put("connector.batch.enable", "false");
+      connectorAttributes.put("connector.exception.conflict.resolve-strategy", "retry");
+      connectorAttributes.put("connector.exception.conflict.retry-max-time-seconds", "-1");
+
+      final TSStatus status =
+          client.createPipe(
+              new TCreatePipeReq("testPipe", connectorAttributes)
+                  .setExtractorAttributes(extractorAttributes)
+                  .setProcessorAttributes(processorAttributes));
+
+      Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+    }
+
+    if (!TestUtils.tryExecuteNonQueriesWithRetry(
+        database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, beforeSqlList)) {
+      return;
+    }
+
+    if (!TestUtils.tryExecuteNonQueryWithRetry(
+        database, BaseEnv.TABLE_SQL_DIALECT, receiverEnv, testSql)) {
+      return;
+    }
+
+    // Create an idempotent conflict
+    if (!TestUtils.tryExecuteNonQueryWithRetry(
+        database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, testSql)) {
+      return;
+    }
+
+    TableModelUtils.createDatabase(senderEnv, "test2");
+
+    // Assume that the "database" is executed on receiverEnv
+    TestUtils.assertDataSizeEventuallyOnEnv(receiverEnv, "show databases", 3, null);
+  }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeTableManualIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeMetaIT.java
similarity index 77%
rename from integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeTableManualIT.java
rename to integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeMetaIT.java
index 866f51e5840..4e33f8369d6 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeTableManualIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeMetaIT.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.pipe.it.dual.treemodel.auto.enhanced;
+package org.apache.iotdb.pipe.it.dual.tablemodel.manual.enhanced;
 
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
@@ -25,10 +25,10 @@ import org.apache.iotdb.confignode.rpc.thrift.TCreatePipeReq;
 import org.apache.iotdb.db.it.utils.TestUtils;
 import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
 import org.apache.iotdb.it.framework.IoTDBTestRunner;
-import org.apache.iotdb.itbase.category.MultiClusterIT2DualTreeAutoEnhanced;
+import org.apache.iotdb.itbase.category.MultiClusterIT2DualTableManualEnhanced;
 import org.apache.iotdb.itbase.env.BaseEnv;
 import org.apache.iotdb.pipe.it.dual.tablemodel.TableModelUtils;
-import org.apache.iotdb.pipe.it.dual.treemodel.manual.AbstractPipeDualTreeModelManualIT;
+import org.apache.iotdb.pipe.it.dual.tablemodel.manual.AbstractPipeTableModelDualManualIT;
 import org.apache.iotdb.rpc.TSStatusCode;
 
 import org.junit.Assert;
@@ -43,8 +43,8 @@ import java.util.HashSet;
 import java.util.Map;
 
 @RunWith(IoTDBTestRunner.class)
-@Category({MultiClusterIT2DualTreeAutoEnhanced.class})
-public class IoTDBPipeTableManualIT extends AbstractPipeDualTreeModelManualIT {
+@Category({MultiClusterIT2DualTableManualEnhanced.class})
+public class IoTDBPipeMetaIT extends AbstractPipeTableModelDualManualIT {
   @Test
   public void testTableSync() throws Exception {
     final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
@@ -291,4 +291,80 @@ public class IoTDBPipeTableManualIT extends AbstractPipeDualTreeModelManualIT {
           dbName);
     }
   }
+
+  @Test
+  public void testAuth() throws Exception {
+    final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
+
+    final String receiverIp = receiverDataNode.getIp();
+    final int receiverPort = receiverDataNode.getPort();
+
+    try (final SyncConfigNodeIServiceClient client =
+        (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
+
+      if (!TestUtils.tryExecuteNonQueriesWithRetry(
+          senderEnv,
+          Arrays.asList(
+              "create user testUser 'password'", "grant all on root.** to user testUser"))) {
+        return;
+      }
+
+      final String dbName = "test";
+      if (!TestUtils.tryExecuteNonQueriesWithRetry(
+          dbName,
+          BaseEnv.TABLE_SQL_DIALECT,
+          senderEnv,
+          Arrays.asList(
+              "grant create on db.tb to user testUser",
+              "grant drop on database test to user testUser"))) {
+        return;
+      }
+
+      final Map<String, String> extractorAttributes = new HashMap<>();
+      final Map<String, String> processorAttributes = new HashMap<>();
+      final Map<String, String> connectorAttributes = new HashMap<>();
+
+      extractorAttributes.put("extractor.inclusion", "all");
+      extractorAttributes.put("extractor.capture.tree", "false");
+      extractorAttributes.put("extractor.capture.table", "true");
+      extractorAttributes.put("extractor.database-name", "test");
+      extractorAttributes.put("extractor.table-name", "t.*[0-9]");
+
+      connectorAttributes.put("connector", "iotdb-thrift-connector");
+      connectorAttributes.put("connector.ip", receiverIp);
+      connectorAttributes.put("connector.port", Integer.toString(receiverPort));
+
+      final TSStatus status =
+          client.createPipe(
+              new TCreatePipeReq("testPipe", connectorAttributes)
+                  .setExtractorAttributes(extractorAttributes)
+                  .setProcessorAttributes(processorAttributes));
+
+      Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+
+      Assert.assertEquals(
+          TSStatusCode.SUCCESS_STATUS.getStatusCode(), client.startPipe("testPipe").getCode());
+
+      if (!TestUtils.tryExecuteNonQueryWithRetry(
+          dbName,
+          BaseEnv.TABLE_SQL_DIALECT,
+          senderEnv,
+          "grant alter on any to user testUser with grant option")) {
+        return;
+      }
+
+      TestUtils.assertDataAlwaysOnEnv(
+          receiverEnv,
+          "list privileges of user testUser",
+          "Role,Scope,Privileges,GrantOption,",
+          new HashSet<>(
+              Arrays.asList(
+                  ",,MANAGE_USER,false,",
+                  ",,MANAGE_ROLE,false,",
+                  ",,MAINTAIN,false,",
+                  ",*.*,ALTER,true,",
+                  ",test.*,DROP,false,")),
+          dbName);
+    }
+  }
 }
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java
index 979fd60098c..e741ab82f6d 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java
@@ -28,8 +28,6 @@ import org.apache.iotdb.it.env.MultiEnvFactory;
 import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
 import org.apache.iotdb.it.framework.IoTDBTestRunner;
 import org.apache.iotdb.itbase.category.MultiClusterIT2DualTreeAutoEnhanced;
-import org.apache.iotdb.itbase.env.BaseEnv;
-import org.apache.iotdb.pipe.it.dual.tablemodel.TableModelUtils;
 import org.apache.iotdb.pipe.it.dual.treemodel.auto.AbstractPipeDualTreeModelAutoIT;
 import org.apache.iotdb.rpc.TSStatusCode;
 
@@ -397,36 +395,6 @@ public class IoTDBPipeIdempotentIT extends AbstractPipeDualTreeModelAutoIT {
 
   // Table model
 
-  @Test
-  public void testCreateTableIdempotent() throws Exception {
-    testTableConfigIdempotent(Collections.emptyList(), "create table test()");
-  }
-
-  @Test
-  public void testAlterTableAddColumnIdempotent() throws Exception {
-    testTableConfigIdempotent(
-        Collections.singletonList("create table test()"), "alter table test add column a id");
-  }
-
-  @Test
-  public void testAlterTableSetPropertiesIdempotent() throws Exception {
-    testTableConfigIdempotent(
-        Collections.singletonList("create table test()"),
-        "alter table test set properties ttl=100");
-  }
-
-  @Test
-  public void testAlterTableDropColumnIdempotent() throws Exception {
-    testTableConfigIdempotent(
-        Collections.singletonList("create table test(a id, b attribute, c int32)"),
-        "alter table test drop column b");
-  }
-
-  @Test
-  public void testDropTableIdempotent() throws Exception {
-    testTableConfigIdempotent(Collections.singletonList("create table test()"), "drop table test");
-  }
-
   private void testIdempotent(
       final List<String> beforeSqlList,
       final String testSql,
@@ -484,63 +452,4 @@ public class IoTDBPipeIdempotentIT extends AbstractPipeDualTreeModelAutoIT {
     // Assume that the afterSql is executed on receiverEnv
     TestUtils.assertDataEventuallyOnEnv(receiverEnv, afterSqlQuery, expectedHeader, expectedResSet);
   }
-
-  private void testTableConfigIdempotent(final List<String> beforeSqlList, final String testSql)
-      throws Exception {
-    final String database = "test";
-    TableModelUtils.createDatabase(senderEnv, database);
-    final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
-
-    final String receiverIp = receiverDataNode.getIp();
-    final int receiverPort = receiverDataNode.getPort();
-
-    try (final SyncConfigNodeIServiceClient client =
-        (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
-      final Map<String, String> extractorAttributes = new HashMap<>();
-      final Map<String, String> processorAttributes = new HashMap<>();
-      final Map<String, String> connectorAttributes = new HashMap<>();
-
-      extractorAttributes.put("extractor.inclusion", "all");
-      extractorAttributes.put("extractor.inclusion.exclusion", "");
-      extractorAttributes.put("extractor.forwarding-pipe-requests", "false");
-      extractorAttributes.put("extractor.capture.table", "true");
-      extractorAttributes.put("extractor.capture.tree", "false");
-
-      connectorAttributes.put("connector", "iotdb-thrift-connector");
-      connectorAttributes.put("connector.ip", receiverIp);
-      connectorAttributes.put("connector.port", Integer.toString(receiverPort));
-      connectorAttributes.put("connector.batch.enable", "false");
-      connectorAttributes.put("connector.exception.conflict.resolve-strategy", "retry");
-      connectorAttributes.put("connector.exception.conflict.retry-max-time-seconds", "-1");
-
-      final TSStatus status =
-          client.createPipe(
-              new TCreatePipeReq("testPipe", connectorAttributes)
-                  .setExtractorAttributes(extractorAttributes)
-                  .setProcessorAttributes(processorAttributes));
-
-      Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
-    }
-
-    if (!TestUtils.tryExecuteNonQueriesWithRetry(
-        database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, beforeSqlList)) {
-      return;
-    }
-
-    if (!TestUtils.tryExecuteNonQueryWithRetry(
-        database, BaseEnv.TABLE_SQL_DIALECT, receiverEnv, testSql)) {
-      return;
-    }
-
-    // Create an idempotent conflict
-    if (!TestUtils.tryExecuteNonQueryWithRetry(
-        database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, testSql)) {
-      return;
-    }
-
-    TableModelUtils.createDatabase(senderEnv, "test2");
-
-    // Assume that the "database" is executed on receiverEnv
-    TestUtils.assertDataSizeEventuallyOnEnv(receiverEnv, "show databases", 3, null);
-  }
 }
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java
index d2a46baf585..b5c1923ecca 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java
@@ -19,7 +19,8 @@
 
 package org.apache.iotdb.confignode.consensus.request;
 
-import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.SetTTLPlan;
@@ -65,29 +66,83 @@ public abstract class ConfigPhysicalPlanVisitor<R, C> {
       case PipeDeactivateTemplate:
         return visitPipeDeactivateTemplate((PipeDeactivateTemplatePlan) plan, context);
       case CreateRole:
-        return visitCreateRole((AuthorPlan) plan, context);
+        return visitCreateRole((AuthorTreePlan) plan, context);
       case DropRole:
-        return visitDropRole((AuthorPlan) plan, context);
+        return visitDropRole((AuthorTreePlan) plan, context);
       case GrantRole:
-        return visitGrantRole((AuthorPlan) plan, context);
+        return visitGrantRole((AuthorTreePlan) plan, context);
       case RevokeRole:
-        return visitRevokeRole((AuthorPlan) plan, context);
+        return visitRevokeRole((AuthorTreePlan) plan, context);
       case CreateUser:
-        return visitCreateUser((AuthorPlan) plan, context);
+        return visitCreateUser((AuthorTreePlan) plan, context);
       case CreateUserWithRawPassword:
-        return visitCreateRawUser((AuthorPlan) plan, context);
+        return visitCreateRawUser((AuthorTreePlan) plan, context);
       case UpdateUser:
-        return visitUpdateUser((AuthorPlan) plan, context);
+        return visitUpdateUser((AuthorTreePlan) plan, context);
       case DropUser:
-        return visitDropUser((AuthorPlan) plan, context);
+        return visitDropUser((AuthorTreePlan) plan, context);
       case GrantUser:
-        return visitGrantUser((AuthorPlan) plan, context);
+        return visitGrantUser((AuthorTreePlan) plan, context);
       case RevokeUser:
-        return visitRevokeUser((AuthorPlan) plan, context);
+        return visitRevokeUser((AuthorTreePlan) plan, context);
       case GrantRoleToUser:
-        return visitGrantRoleToUser((AuthorPlan) plan, context);
+        return visitGrantRoleToUser((AuthorTreePlan) plan, context);
       case RevokeRoleFromUser:
-        return visitRevokeRoleFromUser((AuthorPlan) plan, context);
+        return visitRevokeRoleFromUser((AuthorTreePlan) plan, context);
+      case RCreateUser:
+        return visitRCreateUser((AuthorRelationalPlan) plan, context);
+      case RCreateRole:
+        return visitRCreateRole((AuthorRelationalPlan) plan, context);
+      case RUpdateUser:
+        return visitRUpdateUser((AuthorRelationalPlan) plan, context);
+      case RDropUser:
+        return visitRDropUserPlan((AuthorRelationalPlan) plan, context);
+      case RDropRole:
+        return visitRDropRolePlan((AuthorRelationalPlan) plan, context);
+      case RGrantUserRole:
+        return visitRGrantUserRole((AuthorRelationalPlan) plan, context);
+      case RRevokeUserRole:
+        return visitRRevokeUserRole((AuthorRelationalPlan) plan, context);
+      case RGrantUserAny:
+        return visitRGrantUserAny((AuthorRelationalPlan) plan, context);
+      case RGrantRoleAny:
+        return visitRGrantRoleAny((AuthorRelationalPlan) plan, context);
+      case RGrantUserAll:
+        return visitRGrantUserAll((AuthorRelationalPlan) plan, context);
+      case RGrantRoleAll:
+        return visitRGrantRoleAll((AuthorRelationalPlan) plan, context);
+      case RGrantUserDBPriv:
+        return visitRGrantUserDB((AuthorRelationalPlan) plan, context);
+      case RGrantUserTBPriv:
+        return visitRGrantUserTB((AuthorRelationalPlan) plan, context);
+      case RGrantRoleDBPriv:
+        return visitRGrantRoleDB((AuthorRelationalPlan) plan, context);
+      case RGrantRoleTBPriv:
+        return visitRGrantRoleTB((AuthorRelationalPlan) plan, context);
+      case RRevokeUserAny:
+        return visitRRevokeUserAny((AuthorRelationalPlan) plan, context);
+      case RRevokeRoleAny:
+        return visitRRevokeRoleAny((AuthorRelationalPlan) plan, context);
+      case RRevokeUserAll:
+        return visitRRevokeUserAll((AuthorRelationalPlan) plan, context);
+      case RRevokeRoleAll:
+        return visitRRevokeRoleAll((AuthorRelationalPlan) plan, context);
+      case RRevokeUserDBPriv:
+        return visitRRevokeUserDBPrivilege((AuthorRelationalPlan) plan, context);
+      case RRevokeUserTBPriv:
+        return visitRRevokeUserTBPrivilege((AuthorRelationalPlan) plan, context);
+      case RRevokeRoleDBPriv:
+        return visitRRevokeRoleDBPrivilege((AuthorRelationalPlan) plan, context);
+      case RRevokeRoleTBPriv:
+        return visitRRevokeRoleTBPrivilege((AuthorRelationalPlan) plan, context);
+      case RGrantUserSysPri:
+        return visitRGrantUserSysPrivilege((AuthorRelationalPlan) plan, context);
+      case RGrantRoleSysPri:
+        return visitRGrantRoleSysPrivilege((AuthorRelationalPlan) plan, context);
+      case RRevokeUserSysPri:
+        return visitRRevokeUserSysPrivilege((AuthorRelationalPlan) plan, context);
+      case RRevokeRoleSysPri:
+        return visitRRevokeRoleSysPrivilege((AuthorRelationalPlan) plan, context);
       case SetTTL:
         return visitTTL((SetTTLPlan) plan, context);
       case PipeCreateTable:
@@ -164,54 +219,170 @@ public abstract class ConfigPhysicalPlanVisitor<R, C> {
     return visitPlan(pipeDeactivateTemplatePlan, context);
   }
 
-  public R visitCreateUser(final AuthorPlan createUserPlan, final C context) {
+  public R visitCreateUser(final AuthorTreePlan createUserPlan, final C context) {
     return visitPlan(createUserPlan, context);
   }
 
-  public R visitCreateRawUser(final AuthorPlan createRawUserPlan, final C context) {
+  public R visitCreateRawUser(final AuthorTreePlan createRawUserPlan, final C context) {
     return visitPlan(createRawUserPlan, context);
   }
 
-  public R visitUpdateUser(final AuthorPlan updateUserPlan, final C context) {
+  public R visitUpdateUser(final AuthorTreePlan updateUserPlan, final C context) {
     return visitPlan(updateUserPlan, context);
   }
 
-  public R visitDropUser(final AuthorPlan dropUserPlan, final C context) {
+  public R visitDropUser(final AuthorTreePlan dropUserPlan, final C context) {
     return visitPlan(dropUserPlan, context);
   }
 
-  public R visitGrantUser(final AuthorPlan grantUserPlan, final C context) {
+  public R visitGrantUser(final AuthorTreePlan grantUserPlan, final C context) {
     return visitPlan(grantUserPlan, context);
   }
 
-  public R visitRevokeUser(final AuthorPlan revokeUserPlan, final C context) {
+  public R visitRevokeUser(final AuthorTreePlan revokeUserPlan, final C context) {
     return visitPlan(revokeUserPlan, context);
   }
 
-  public R visitCreateRole(final AuthorPlan createRolePlan, final C context) {
+  public R visitCreateRole(final AuthorTreePlan createRolePlan, final C context) {
     return visitPlan(createRolePlan, context);
   }
 
-  public R visitDropRole(final AuthorPlan dropRolePlan, final C context) {
+  public R visitDropRole(final AuthorTreePlan dropRolePlan, final C context) {
     return visitPlan(dropRolePlan, context);
   }
 
-  public R visitGrantRole(final AuthorPlan grantRolePlan, final C context) {
+  public R visitGrantRole(final AuthorTreePlan grantRolePlan, final C context) {
     return visitPlan(grantRolePlan, context);
   }
 
-  public R visitRevokeRole(final AuthorPlan revokeRolePlan, final C context) {
+  public R visitRevokeRole(final AuthorTreePlan revokeRolePlan, final C context) {
     return visitPlan(revokeRolePlan, context);
   }
 
-  public R visitGrantRoleToUser(final AuthorPlan grantRoleToUserPlan, final C context) {
+  public R visitGrantRoleToUser(final AuthorTreePlan grantRoleToUserPlan, final C context) {
     return visitPlan(grantRoleToUserPlan, context);
   }
 
-  public R visitRevokeRoleFromUser(final AuthorPlan revokeRoleFromUserPlan, final C context) {
+  public R visitRevokeRoleFromUser(final AuthorTreePlan revokeRoleFromUserPlan, final C context) {
     return visitPlan(revokeRoleFromUserPlan, context);
   }
 
+  public R visitRCreateUser(final AuthorRelationalPlan rCreateUserPlan, final C context) {
+    return visitPlan(rCreateUserPlan, context);
+  }
+
+  public R visitRCreateRole(final AuthorRelationalPlan rCreateRolePlan, final C context) {
+    return visitPlan(rCreateRolePlan, context);
+  }
+
+  public R visitRUpdateUser(final AuthorRelationalPlan rUpdateUserPlan, final C context) {
+    return visitPlan(rUpdateUserPlan, context);
+  }
+
+  public R visitRDropUserPlan(final AuthorRelationalPlan rDropUserPlan, final C context) {
+    return visitPlan(rDropUserPlan, context);
+  }
+
+  public R visitRDropRolePlan(final AuthorRelationalPlan rDropRolePlan, final C context) {
+    return visitPlan(rDropRolePlan, context);
+  }
+
+  public R visitRGrantUserRole(final AuthorRelationalPlan rGrantUserRolePlan, final C context) {
+    return visitPlan(rGrantUserRolePlan, context);
+  }
+
+  public R visitRRevokeUserRole(final AuthorRelationalPlan rRevokeUserRolePlan, final C context) {
+    return visitPlan(rRevokeUserRolePlan, context);
+  }
+
+  public R visitRGrantUserAny(final AuthorRelationalPlan rGrantUserAnyPlan, final C context) {
+    return visitPlan(rGrantUserAnyPlan, context);
+  }
+
+  public R visitRGrantRoleAny(final AuthorRelationalPlan rGrantRoleAnyPlan, final C context) {
+    return visitPlan(rGrantRoleAnyPlan, context);
+  }
+
+  public R visitRGrantUserAll(final AuthorRelationalPlan rGrantUserAllPlan, final C context) {
+    return visitPlan(rGrantUserAllPlan, context);
+  }
+
+  public R visitRGrantRoleAll(final AuthorRelationalPlan rGrantRoleAllPlan, final C context) {
+    return visitPlan(rGrantRoleAllPlan, context);
+  }
+
+  public R visitRGrantUserDB(final AuthorRelationalPlan rGrantUserDBPlan, final C context) {
+    return visitPlan(rGrantUserDBPlan, context);
+  }
+
+  public R visitRGrantUserTB(final AuthorRelationalPlan rGrantUserTBPlan, final C context) {
+    return visitPlan(rGrantUserTBPlan, context);
+  }
+
+  public R visitRGrantRoleDB(final AuthorRelationalPlan rGrantRoleDBPlan, final C context) {
+    return visitPlan(rGrantRoleDBPlan, context);
+  }
+
+  public R visitRGrantRoleTB(final AuthorRelationalPlan rGrantRoleTBPlan, final C context) {
+    return visitPlan(rGrantRoleTBPlan, context);
+  }
+
+  public R visitRRevokeUserAny(final AuthorRelationalPlan rRevokeUserAnyPlan, final C context) {
+    return visitPlan(rRevokeUserAnyPlan, context);
+  }
+
+  public R visitRRevokeRoleAny(final AuthorRelationalPlan rRevokeRoleAnyPlan, final C context) {
+    return visitPlan(rRevokeRoleAnyPlan, context);
+  }
+
+  public R visitRRevokeUserAll(final AuthorRelationalPlan rRevokeUserAllPlan, final C context) {
+    return visitPlan(rRevokeUserAllPlan, context);
+  }
+
+  public R visitRRevokeRoleAll(final AuthorRelationalPlan rRevokeRoleAllPlan, final C context) {
+    return visitPlan(rRevokeRoleAllPlan, context);
+  }
+
+  public R visitRRevokeUserDBPrivilege(
+      final AuthorRelationalPlan rRevokeUserDBPrivilegePlan, final C context) {
+    return visitPlan(rRevokeUserDBPrivilegePlan, context);
+  }
+
+  public R visitRRevokeUserTBPrivilege(
+      final AuthorRelationalPlan rRevokeUserTBPrivilegePlan, final C context) {
+    return visitPlan(rRevokeUserTBPrivilegePlan, context);
+  }
+
+  public R visitRRevokeRoleDBPrivilege(
+      final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final C context) {
+    return visitPlan(rRevokeRoleTBPrivilegePlan, context);
+  }
+
+  public R visitRRevokeRoleTBPrivilege(
+      final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final C context) {
+    return visitPlan(rRevokeRoleTBPrivilegePlan, context);
+  }
+
+  public R visitRGrantUserSysPrivilege(
+      final AuthorRelationalPlan rGrantUserSysPrivilegePlan, final C context) {
+    return visitPlan(rGrantUserSysPrivilegePlan, context);
+  }
+
+  public R visitRGrantRoleSysPrivilege(
+      final AuthorRelationalPlan rGrantRoleSysPrivilegePlan, final C context) {
+    return visitPlan(rGrantRoleSysPrivilegePlan, context);
+  }
+
+  public R visitRRevokeUserSysPrivilege(
+      final AuthorRelationalPlan rRevokeUserSysPrivilegePlan, final C context) {
+    return visitPlan(rRevokeUserSysPrivilegePlan, context);
+  }
+
+  public R visitRRevokeRoleSysPrivilege(
+      final AuthorRelationalPlan rRevokeRoleSysPrivilegePlan, final C context) {
+    return visitPlan(rRevokeRoleSysPrivilegePlan, context);
+  }
+
   public R visitTTL(final SetTTLPlan setTTLPlan, final C context) {
     return visitPlan(setTTLPlan, context);
   }
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
index 4d31ae8961e..bab7b08c25e 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.commons.auth.AuthException;
 import org.apache.iotdb.commons.auth.entity.PrivilegeUnion;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
 import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeEnrichedPlan;
 import org.apache.iotdb.confignode.consensus.response.auth.PermissionInfoResp;
 import org.apache.iotdb.confignode.manager.consensus.ConsensusManager;
 import org.apache.iotdb.confignode.persistence.AuthorInfo;
@@ -66,7 +67,9 @@ public class PermissionManager {
       if (authorPlan.getAuthorType() == ConfigPhysicalPlanType.CreateUser
           || authorPlan.getAuthorType() == ConfigPhysicalPlanType.CreateRole
           || authorPlan.getAuthorType() == ConfigPhysicalPlanType.CreateUserWithRawPassword) {
-        tsStatus = getConsensusManager().write(authorPlan);
+        tsStatus =
+            getConsensusManager()
+                .write(isGeneratedByPipe ? new PipeEnrichedPlan(authorPlan) : authorPlan);
       } else {
         List<TDataNodeConfiguration> allDataNodes =
             configManager.getNodeManager().getRegisteredDataNodes();
@@ -76,7 +79,7 @@ public class PermissionManager {
                 .operateAuthPlan(authorPlan, allDataNodes, isGeneratedByPipe);
       }
       return tsStatus;
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn("Failed in the write API executing the consensus layer due to: ", e);
       TSStatus res = new TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       res.setMessage(e.getMessage());
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java
index b37bfde0baa..eda703f6e51 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java
@@ -67,14 +67,24 @@ public class PipeConfigRegionSnapshotEvent extends PipeSnapshotEvent
             new HashSet<>(
                 Arrays.asList(
                     ConfigPhysicalPlanType.CreateRole.getPlanType(),
-                    ConfigPhysicalPlanType.GrantRole.getPlanType()))));
+                    ConfigPhysicalPlanType.GrantRole.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantRoleDBPriv.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantRoleTBPriv.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantRoleAny.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantRoleSysPri.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantRoleAll.getPlanType()))));
     SNAPSHOT_FILE_TYPE_2_CONFIG_PHYSICAL_PLAN_TYPE_MAP.put(
         CNSnapshotFileType.USER,
         Collections.unmodifiableSet(
             new HashSet<>(
                 Arrays.asList(
                     ConfigPhysicalPlanType.CreateUserWithRawPassword.getPlanType(),
-                    ConfigPhysicalPlanType.GrantUser.getPlanType()))));
+                    ConfigPhysicalPlanType.GrantUser.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantUserDBPriv.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantUserTBPriv.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantUserAny.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantUserSysPri.getPlanType(),
+                    ConfigPhysicalPlanType.RGrantUserAll.getPlanType()))));
     SNAPSHOT_FILE_TYPE_2_CONFIG_PHYSICAL_PLAN_TYPE_MAP.put(
         CNSnapshotFileType.USER_ROLE,
         Collections.singleton(ConfigPhysicalPlanType.GrantRoleToUser.getPlanType()));
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java
index 0c87b8d60e7..5f0e2889d9f 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java
@@ -41,8 +41,8 @@ import java.util.stream.Collectors;
 import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getExclusionString;
 import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getInclusionString;
 import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.parseOptions;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefix;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefix;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefixes;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefixes;
 
 /**
  * {@link ConfigRegionListeningFilter} is to classify the {@link ConfigPhysicalPlan}s to help {@link
@@ -122,16 +122,45 @@ public class ConfigRegionListeningFilter {
 
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.role.create"),
-          Collections.singletonList(ConfigPhysicalPlanType.CreateRole));
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.CreateRole, ConfigPhysicalPlanType.RCreateRole)));
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.role.drop"),
-          Collections.singletonList(ConfigPhysicalPlanType.DropRole));
+          Collections.unmodifiableList(
+              Arrays.asList(ConfigPhysicalPlanType.DropRole, ConfigPhysicalPlanType.RDropRole)));
+
+      // Both
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.role.grant"),
-          Collections.singletonList(ConfigPhysicalPlanType.GrantRole));
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.GrantRole,
+                  ConfigPhysicalPlanType.RGrantRoleAll,
+                  ConfigPhysicalPlanType.RGrantRoleSysPri)));
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.role.revoke"),
-          Collections.singletonList(ConfigPhysicalPlanType.RevokeRole));
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.RevokeRole,
+                  ConfigPhysicalPlanType.RRevokeRoleAll,
+                  ConfigPhysicalPlanType.RRevokeRoleSysPri)));
+
+      // Table
+      OPTION_PLAN_MAP.put(
+          new PartialPath("auth.role.grant.table"),
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.RGrantRoleAny,
+                  ConfigPhysicalPlanType.RGrantRoleDBPriv,
+                  ConfigPhysicalPlanType.RGrantRoleTBPriv)));
+      OPTION_PLAN_MAP.put(
+          new PartialPath("auth.role.revoke.table"),
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.RRevokeRoleAny,
+                  ConfigPhysicalPlanType.RRevokeRoleDBPriv,
+                  ConfigPhysicalPlanType.RRevokeRoleTBPriv)));
 
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.user.create"),
@@ -141,20 +170,49 @@ public class ConfigRegionListeningFilter {
                   ConfigPhysicalPlanType.CreateUserWithRawPassword)));
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.user.alter"),
-          Collections.singletonList(ConfigPhysicalPlanType.UpdateUser));
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.UpdateUser, ConfigPhysicalPlanType.RUpdateUser)));
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.user.drop"),
-          Collections.singletonList(ConfigPhysicalPlanType.DropUser));
+          Collections.unmodifiableList(
+              Arrays.asList(ConfigPhysicalPlanType.DropUser, ConfigPhysicalPlanType.RUpdateUser)));
+
+      // Both
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.user.grant"),
           Collections.unmodifiableList(
               Arrays.asList(
-                  ConfigPhysicalPlanType.GrantUser, ConfigPhysicalPlanType.GrantRoleToUser)));
+                  ConfigPhysicalPlanType.GrantUser,
+                  ConfigPhysicalPlanType.GrantRoleToUser,
+                  ConfigPhysicalPlanType.RGrantUserRole,
+                  ConfigPhysicalPlanType.RGrantUserAll,
+                  ConfigPhysicalPlanType.RGrantUserSysPri)));
       OPTION_PLAN_MAP.put(
           new PartialPath("auth.user.revoke"),
           Collections.unmodifiableList(
               Arrays.asList(
-                  ConfigPhysicalPlanType.RevokeUser, ConfigPhysicalPlanType.RevokeRoleFromUser)));
+                  ConfigPhysicalPlanType.RevokeUser,
+                  ConfigPhysicalPlanType.RevokeRoleFromUser,
+                  ConfigPhysicalPlanType.RRevokeUserRole,
+                  ConfigPhysicalPlanType.RGrantUserAll,
+                  ConfigPhysicalPlanType.RGrantUserSysPri)));
+
+      // Table
+      OPTION_PLAN_MAP.put(
+          new PartialPath("auth.user.grant.table"),
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.RGrantUserAny,
+                  ConfigPhysicalPlanType.RGrantUserDBPriv,
+                  ConfigPhysicalPlanType.RGrantUserTBPriv)));
+      OPTION_PLAN_MAP.put(
+          new PartialPath("auth.user.revoke.table"),
+          Collections.unmodifiableList(
+              Arrays.asList(
+                  ConfigPhysicalPlanType.RRevokeUserAny,
+                  ConfigPhysicalPlanType.RRevokeUserDBPriv,
+                  ConfigPhysicalPlanType.RRevokeUserTBPriv)));
     } catch (final IllegalPathException ignore) {
       // There won't be any exceptions here
     }
@@ -185,11 +243,11 @@ public class ConfigRegionListeningFilter {
     exclusionOptions.forEach(exclusion -> planTypes.removeAll(getOptionsByPrefix(exclusion)));
 
     if (!TreePattern.isTreeModelDataAllowToBeCaptured(parameters)) {
-      planTypes.removeAll(getOptionsByPrefix(treeOnlySyncPrefix));
+      treeOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
     }
 
     if (!TablePattern.isTableModelDataAllowToBeCaptured(parameters)) {
-      planTypes.removeAll(getOptionsByPrefix(tableOnlySyncPrefix));
+      tableOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
     }
 
     return planTypes;
@@ -197,7 +255,7 @@ public class ConfigRegionListeningFilter {
 
   private static Set<ConfigPhysicalPlanType> getOptionsByPrefix(final PartialPath prefix) {
     return OPTION_PLAN_MAP.keySet().stream()
-        .filter(path -> path.overlapWithFullPathPrefix(prefix))
+        .filter(path -> path.matchPrefixPath(prefix))
         .map(OPTION_PLAN_MAP::get)
         .flatMap(Collection::stream)
         .collect(Collectors.toSet());
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java
index 9387d67bebe..2795879dcce 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java
@@ -62,6 +62,10 @@ public class IoTDBConfigRegionExtractor extends IoTDBNonDataRegionExtractor {
       new PipeConfigPhysicalPlanTreePatternParseVisitor();
   public static final PipeConfigPhysicalPlanTablePatternParseVisitor TABLE_PATTERN_PARSE_VISITOR =
       new PipeConfigPhysicalPlanTablePatternParseVisitor();
+  public static final PipeConfigPhysicalPlanTreeScopeParseVisitor TREE_SCOPE_PARSE_VISITOR =
+      new PipeConfigPhysicalPlanTreeScopeParseVisitor();
+  public static final PipeConfigPhysicalPlanTableScopeParseVisitor TABLE_SCOPE_PARSE_VISITOR =
+      new PipeConfigPhysicalPlanTableScopeParseVisitor();
 
   private Set<ConfigPhysicalPlanType> listenedTypeSet = new HashSet<>();
 
@@ -149,8 +153,23 @@ public class IoTDBConfigRegionExtractor extends IoTDBNonDataRegionExtractor {
         return result;
       }
     }
-    if (!Boolean.FALSE.equals(isTableDatabasePlan)) {
-      result = TABLE_PATTERN_PARSE_VISITOR.process(plan, tablePattern);
+    if (!Boolean.FALSE.equals(isTableDatabasePlan) && result.isPresent()) {
+      result = TABLE_PATTERN_PARSE_VISITOR.process(result.get(), tablePattern);
+      if (!result.isPresent()) {
+        return result;
+      }
+    }
+    if (!treePattern.isTreeModelDataAllowedToBeCaptured() && result.isPresent()) {
+      result = TREE_SCOPE_PARSE_VISITOR.process(result.get(), null);
+      if (!result.isPresent()) {
+        return result;
+      }
+    }
+    if (!tablePattern.isTableModelDataAllowedToBeCaptured() && result.isPresent()) {
+      result = TABLE_SCOPE_PARSE_VISITOR.process(result.get(), null);
+      if (!result.isPresent()) {
+        return result;
+      }
     }
     return result;
   }
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java
index 91be75a3bb5..679614ac458 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.pipe.datastructure.pattern.TablePattern;
 import org.apache.iotdb.commons.utils.PathUtils;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
 import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeCreateTablePlan;
@@ -132,4 +133,65 @@ public class PipeConfigPhysicalPlanTablePatternParseVisitor
     return pattern.matchesDatabase(PathUtils.unQualifyDatabaseName(database))
         && pattern.matchesTable(tableName);
   }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRGrantUserDB(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorDBPlan(plan, pattern);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRGrantRoleDB(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorDBPlan(plan, pattern);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRRevokeUserDBPrivilege(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorDBPlan(plan, pattern);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRRevokeRoleDBPrivilege(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorDBPlan(plan, pattern);
+  }
+
+  private Optional<ConfigPhysicalPlan> visitAuthorDBPlan(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return pattern.matchesDatabase(plan.getDatabaseName()) ? Optional.of(plan) : Optional.empty();
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRGrantUserTB(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorTBPlan(plan, pattern);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRGrantRoleTB(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorTBPlan(plan, pattern);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRRevokeUserTBPrivilege(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorTBPlan(plan, pattern);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRRevokeRoleTBPrivilege(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return visitAuthorTBPlan(plan, pattern);
+  }
+
+  private Optional<ConfigPhysicalPlan> visitAuthorTBPlan(
+      final AuthorRelationalPlan plan, final TablePattern pattern) {
+    return pattern.matchesDatabase(plan.getDatabaseName())
+            && pattern.matchesTable(plan.getTableName())
+        ? Optional.of(plan)
+        : Optional.empty();
+  }
 }
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTableScopeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTableScopeParseVisitor.java
new file mode 100644
index 00000000000..e5673c0dafd
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTableScopeParseVisitor.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.manager.pipe.extractor;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class PipeConfigPhysicalPlanTableScopeParseVisitor
+    extends ConfigPhysicalPlanVisitor<Optional<ConfigPhysicalPlan>, Void> {
+  @Override
+  public Optional<ConfigPhysicalPlan> visitPlan(final ConfigPhysicalPlan plan, final Void context) {
+    return Optional.of(plan);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRGrantUserAll(
+      final AuthorRelationalPlan plan, final Void context) {
+    return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.GrantUser);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRGrantRoleAll(
+      final AuthorRelationalPlan plan, final Void context) {
+    return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.GrantRole);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRRevokeUserAll(
+      final AuthorRelationalPlan plan, final Void context) {
+    return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.RevokeUser);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRRevokeRoleAll(
+      final AuthorRelationalPlan plan, final Void context) {
+    return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.RevokeRole);
+  }
+
+  private Optional<ConfigPhysicalPlan> visitTableAuthorPlan(
+      final AuthorRelationalPlan authorRelationalPlan, final ConfigPhysicalPlanType type) {
+    final Set<Integer> permissions =
+        Arrays.stream(PrivilegeType.values())
+            .filter(PrivilegeType::forRelationalSys)
+            .map(Enum::ordinal)
+            .collect(Collectors.toSet());
+    return !permissions.isEmpty()
+        ? Optional.of(
+            new AuthorTreePlan(
+                type,
+                authorRelationalPlan.getUserName(),
+                authorRelationalPlan.getRoleName(),
+                authorRelationalPlan.getPassword(),
+                authorRelationalPlan.getNewPassword(),
+                permissions,
+                authorRelationalPlan.getGrantOpt(),
+                Collections.emptyList()))
+        : Optional.empty();
+  }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java
index f5e5888ed7d..344a61c2304 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java
@@ -25,7 +25,6 @@ import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.commons.pipe.datastructure.pattern.IoTDBTreePattern;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
-import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
 import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
@@ -166,52 +165,51 @@ public class PipeConfigPhysicalPlanTreePatternParseVisitor
 
   @Override
   public Optional<ConfigPhysicalPlan> visitGrantUser(
-      final AuthorPlan grantUserPlan, final IoTDBTreePattern pattern) {
+      final AuthorTreePlan grantUserPlan, final IoTDBTreePattern pattern) {
     return visitTreeAuthorPlan(grantUserPlan, pattern);
   }
 
   @Override
   public Optional<ConfigPhysicalPlan> visitRevokeUser(
-      final AuthorPlan revokeUserPlan, final IoTDBTreePattern pattern) {
+      final AuthorTreePlan revokeUserPlan, final IoTDBTreePattern pattern) {
     return visitTreeAuthorPlan(revokeUserPlan, pattern);
   }
 
   @Override
   public Optional<ConfigPhysicalPlan> visitGrantRole(
-      final AuthorPlan revokeUserPlan, final IoTDBTreePattern pattern) {
+      final AuthorTreePlan revokeUserPlan, final IoTDBTreePattern pattern) {
     return visitTreeAuthorPlan(revokeUserPlan, pattern);
   }
 
   @Override
   public Optional<ConfigPhysicalPlan> visitRevokeRole(
-      final AuthorPlan revokeUserPlan, final IoTDBTreePattern pattern) {
+      final AuthorTreePlan revokeUserPlan, final IoTDBTreePattern pattern) {
     return visitTreeAuthorPlan(revokeUserPlan, pattern);
   }
 
   private Optional<ConfigPhysicalPlan> visitTreeAuthorPlan(
-      final AuthorPlan pathRelatedAuthorPlan, final IoTDBTreePattern pattern) {
-    AuthorTreePlan plan = (AuthorTreePlan) pathRelatedAuthorPlan;
+      final AuthorTreePlan pathRelatedAuthorTreePlan, final IoTDBTreePattern pattern) {
     final List<PartialPath> intersectedPaths =
-        plan.getNodeNameList().stream()
+        pathRelatedAuthorTreePlan.getNodeNameList().stream()
             .map(pattern::getIntersection)
             .flatMap(Collection::stream)
             .collect(Collectors.toList());
     final Set<Integer> permissions =
         !intersectedPaths.isEmpty()
-            ? plan.getPermissions()
-            : plan.getPermissions().stream()
+            ? pathRelatedAuthorTreePlan.getPermissions()
+            : pathRelatedAuthorTreePlan.getPermissions().stream()
                 .filter(permission -> !PrivilegeType.values()[permission].isPathPrivilege())
                 .collect(Collectors.toSet());
     return !permissions.isEmpty()
         ? Optional.of(
             new AuthorTreePlan(
-                plan.getAuthorType(),
-                plan.getUserName(),
-                plan.getRoleName(),
-                plan.getPassword(),
-                plan.getNewPassword(),
+                pathRelatedAuthorTreePlan.getAuthorType(),
+                pathRelatedAuthorTreePlan.getUserName(),
+                pathRelatedAuthorTreePlan.getRoleName(),
+                pathRelatedAuthorTreePlan.getPassword(),
+                pathRelatedAuthorTreePlan.getNewPassword(),
                 permissions,
-                plan.getGrantOpt(),
+                pathRelatedAuthorTreePlan.getGrantOpt(),
                 intersectedPaths))
         : Optional.empty();
   }
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreeScopeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreeScopeParseVisitor.java
new file mode 100644
index 00000000000..175b836532f
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreeScopeParseVisitor.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.manager.pipe.extractor;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class PipeConfigPhysicalPlanTreeScopeParseVisitor
+    extends ConfigPhysicalPlanVisitor<Optional<ConfigPhysicalPlan>, Void> {
+  @Override
+  public Optional<ConfigPhysicalPlan> visitPlan(final ConfigPhysicalPlan plan, final Void context) {
+    return Optional.of(plan);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitGrantRole(
+      final AuthorTreePlan grantRolePlan, final Void context) {
+    return visitTreeAuthorPlan(grantRolePlan);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitGrantUser(
+      final AuthorTreePlan grantUserPlan, final Void context) {
+    return visitTreeAuthorPlan(grantUserPlan);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRevokeUser(
+      final AuthorTreePlan revokeUserPlan, final Void context) {
+    return visitTreeAuthorPlan(revokeUserPlan);
+  }
+
+  @Override
+  public Optional<ConfigPhysicalPlan> visitRevokeRole(
+      final AuthorTreePlan revokeRolePlan, final Void context) {
+    return visitTreeAuthorPlan(revokeRolePlan);
+  }
+
+  private Optional<ConfigPhysicalPlan> visitTreeAuthorPlan(final AuthorTreePlan authorTreePlan) {
+    final Set<Integer> permissions =
+        authorTreePlan.getPermissions().stream()
+            .filter(permission -> PrivilegeType.values()[permission].forRelationalSys())
+            .collect(Collectors.toSet());
+    return !permissions.isEmpty()
+        ? Optional.of(
+            new AuthorTreePlan(
+                authorTreePlan.getAuthorType(),
+                authorTreePlan.getUserName(),
+                authorTreePlan.getRoleName(),
+                authorTreePlan.getPassword(),
+                authorTreePlan.getNewPassword(),
+                permissions,
+                authorTreePlan.getGrantOpt(),
+                authorTreePlan.getNodeNameList()))
+        : Optional.empty();
+  }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
index 48d9a6f2f16..15da365f57e 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
@@ -41,6 +41,7 @@ import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
 import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
 import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
@@ -317,6 +318,35 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
         return configManager
             .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.USE_TRIGGER))
             .getStatus();
+      case PipeCreateTable:
+        return configManager
+            .checkUserPrivileges(
+                username,
+                new PrivilegeUnion(
+                    ((PipeCreateTablePlan) plan).getDatabase(),
+                    ((PipeCreateTablePlan) plan).getTable().getTableName(),
+                    PrivilegeType.CREATE))
+            .getStatus();
+      case AddTableColumn:
+      case SetTableProperties:
+      case CommitDeleteColumn:
+        return configManager
+            .checkUserPrivileges(
+                username,
+                new PrivilegeUnion(
+                    ((PipeCreateTablePlan) plan).getDatabase(),
+                    ((PipeCreateTablePlan) plan).getTable().getTableName(),
+                    PrivilegeType.ALTER))
+            .getStatus();
+      case CommitDeleteTable:
+        return configManager
+            .checkUserPrivileges(
+                username,
+                new PrivilegeUnion(
+                    ((PipeCreateTablePlan) plan).getDatabase(),
+                    ((PipeCreateTablePlan) plan).getTable().getTableName(),
+                    PrivilegeType.DROP))
+            .getStatus();
       case GrantRole:
       case GrantUser:
       case RevokeUser:
@@ -338,22 +368,122 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
           }
         }
         return StatusUtils.OK;
+      case RGrantUserAny:
+      case RGrantRoleAny:
+      case RRevokeUserAny:
+      case RRevokeRoleAny:
+        for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+          final TSStatus status =
+              configManager
+                  .checkUserPrivileges(
+                      username, new PrivilegeUnion(PrivilegeType.values()[permission], true, true))
+                  .getStatus();
+          if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+            return status;
+          }
+        }
+        return StatusUtils.OK;
+      case RGrantUserAll:
+      case RGrantRoleAll:
+      case RRevokeUserAll:
+      case RRevokeRoleAll:
+        for (PrivilegeType privilegeType : PrivilegeType.values()) {
+          final TSStatus status;
+          if (privilegeType.isRelationalPrivilege()) {
+            status =
+                configManager
+                    .checkUserPrivileges(username, new PrivilegeUnion(privilegeType, true, true))
+                    .getStatus();
+          } else if (privilegeType.forRelationalSys()) {
+            status =
+                configManager
+                    .checkUserPrivileges(username, new PrivilegeUnion(privilegeType, true))
+                    .getStatus();
+          } else {
+            continue;
+          }
+          if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+            return status;
+          }
+        }
+        return StatusUtils.OK;
+      case RGrantUserDBPriv:
+      case RGrantRoleDBPriv:
+      case RRevokeUserDBPriv:
+      case RRevokeRoleDBPriv:
+        for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+          final TSStatus status =
+              configManager
+                  .checkUserPrivileges(
+                      username,
+                      new PrivilegeUnion(
+                          ((AuthorRelationalPlan) plan).getDatabaseName(),
+                          PrivilegeType.values()[permission],
+                          true))
+                  .getStatus();
+          if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+            return status;
+          }
+        }
+        return StatusUtils.OK;
+      case RGrantUserTBPriv:
+      case RGrantRoleTBPriv:
+      case RRevokeUserTBPriv:
+      case RRevokeRoleTBPriv:
+        for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+          final TSStatus status =
+              configManager
+                  .checkUserPrivileges(
+                      username,
+                      new PrivilegeUnion(
+                          ((AuthorRelationalPlan) plan).getDatabaseName(),
+                          ((AuthorRelationalPlan) plan).getTableName(),
+                          PrivilegeType.values()[permission],
+                          true))
+                  .getStatus();
+          if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+            return status;
+          }
+        }
+        return StatusUtils.OK;
+      case RGrantUserSysPri:
+      case RGrantRoleSysPri:
+      case RRevokeUserSysPri:
+      case RRevokeRoleSysPri:
+        for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+          final TSStatus status =
+              configManager
+                  .checkUserPrivileges(
+                      username, new PrivilegeUnion(PrivilegeType.values()[permission], true))
+                  .getStatus();
+          if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+            return status;
+          }
+        }
+        return StatusUtils.OK;
       case UpdateUser:
+      case RUpdateUser:
         return ((AuthorPlan) plan).getUserName().equals(username)
             ? StatusUtils.OK
             : configManager
                 .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_USER))
                 .getStatus();
       case CreateUser:
+      case RCreateUser:
       case CreateUserWithRawPassword:
       case DropUser:
+      case RDropUser:
         return configManager
             .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_USER))
             .getStatus();
       case CreateRole:
+      case RCreateRole:
       case DropRole:
+      case RDropRole:
       case GrantRoleToUser:
+      case RGrantUserRole:
       case RevokeRoleFromUser:
+      case RRevokeUserRole:
         return configManager
             .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_ROLE))
             .getStatus();
@@ -552,6 +682,9 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
                     ByteBuffer.wrap(((PipeDeleteDevicesPlan) plan).getModBytes())),
                 true)
             .getStatus();
+      case CreateUser:
+      case CreateUserWithRawPassword:
+      case CreateRole:
       case DropUser:
       case DropRole:
       case GrantRole:
@@ -561,11 +694,34 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
       case RevokeRole:
       case RevokeRoleFromUser:
       case UpdateUser:
+      case RCreateUser:
+      case RCreateRole:
+      case RDropUser:
+      case RDropRole:
+      case RGrantRoleAll:
+      case RGrantUserAll:
+      case RRevokeRoleAll:
+      case RRevokeUserAll:
+      case RGrantRoleAny:
+      case RGrantUserAny:
+      case RRevokeUserAny:
+      case RRevokeRoleAny:
+      case RGrantRoleDBPriv:
+      case RGrantUserDBPriv:
+      case RRevokeRoleDBPriv:
+      case RRevokeUserDBPriv:
+      case RGrantRoleTBPriv:
+      case RGrantUserTBPriv:
+      case RRevokeRoleTBPriv:
+      case RRevokeUserTBPriv:
+      case RGrantRoleSysPri:
+      case RGrantUserSysPri:
+      case RRevokeRoleSysPri:
+      case RRevokeUserSysPri:
+      case RGrantUserRole:
+      case RRevokeUserRole:
         return configManager.getPermissionManager().operatePermission((AuthorPlan) plan, true);
       case CreateSchemaTemplate:
-      case CreateUser:
-      case CreateRole:
-      case CreateUserWithRawPassword:
       default:
         return configManager.getConsensusManager().write(new PipeEnrichedPlan(plan));
     }
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java
index 0583e32e280..653ef4339ea 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java
@@ -22,7 +22,8 @@ package org.apache.iotdb.confignode.manager.pipe.receiver.visitor;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
-import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.SetTTLPlan;
@@ -191,7 +192,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitCreateUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitCreateUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.USER_ALREADY_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -200,7 +201,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitCreateRawUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitCreateRawUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.USER_ALREADY_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -209,7 +210,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitUpdateUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitUpdateUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.USER_NOT_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_USER_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -218,7 +219,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitDropUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitDropUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.USER_NOT_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -227,7 +228,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitGrantUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitGrantUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.NO_PERMISSION.getStatusCode()) {
       // Admin user
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
@@ -241,7 +242,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitRevokeUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitRevokeUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.NOT_HAS_PRIVILEGE.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -255,7 +256,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitCreateRole(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitCreateRole(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.ROLE_ALREADY_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -264,7 +265,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitDropRole(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitDropRole(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.ROLE_NOT_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -273,7 +274,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitGrantRole(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitGrantRole(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.ROLE_NOT_EXIST.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_USER_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -282,7 +283,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitRevokeRole(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitRevokeRole(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.NOT_HAS_PRIVILEGE.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -294,7 +295,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitGrantRoleToUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitGrantRoleToUser(final AuthorTreePlan plan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.USER_ALREADY_HAS_ROLE.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -303,7 +304,8 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
   }
 
   @Override
-  public TSStatus visitRevokeRoleFromUser(final AuthorPlan plan, final TSStatus context) {
+  public TSStatus visitRevokeRoleFromUser(
+      final AuthorTreePlan revokeRoleFromUserPlan, final TSStatus context) {
     if (context.getCode() == TSStatusCode.USER_NOT_HAS_ROLE.getStatusCode()) {
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
@@ -311,7 +313,184 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
       return new TSStatus(TSStatusCode.PIPE_RECEIVER_USER_CONFLICT_EXCEPTION.getStatusCode())
           .setMessage(context.getMessage());
     }
-    return super.visitRevokeRoleFromUser(plan, context);
+    return super.visitRevokeRoleFromUser(revokeRoleFromUserPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRCreateUser(
+      final AuthorRelationalPlan rCreateUserPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rCreateUserPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRCreateRole(
+      final AuthorRelationalPlan rCreateRolePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rCreateRolePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRUpdateUser(
+      final AuthorRelationalPlan rUpdateUserPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rUpdateUserPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRDropUserPlan(
+      final AuthorRelationalPlan rDropUserPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rDropUserPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRDropRolePlan(
+      final AuthorRelationalPlan rDropRolePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rDropRolePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantUserRole(
+      final AuthorRelationalPlan rGrantUserRolePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantUserRolePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeUserRole(
+      final AuthorRelationalPlan rRevokeUserRolePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeUserRolePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantUserAny(
+      final AuthorRelationalPlan rGrantUserAnyPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantUserAnyPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantRoleAny(
+      final AuthorRelationalPlan rGrantRoleAnyPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantRoleAnyPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantUserAll(
+      final AuthorRelationalPlan rGrantUserAllPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantUserAllPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantRoleAll(
+      final AuthorRelationalPlan rGrantRoleAllPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantRoleAllPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantUserDB(
+      final AuthorRelationalPlan rGrantUserDBPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantUserDBPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantUserTB(
+      final AuthorRelationalPlan rGrantUserTBPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantUserTBPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantRoleDB(
+      final AuthorRelationalPlan rGrantRoleDBPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantRoleDBPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantRoleTB(
+      final AuthorRelationalPlan rGrantRoleTBPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantRoleTBPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeUserAny(
+      final AuthorRelationalPlan rRevokeUserAnyPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeUserAnyPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeRoleAny(
+      final AuthorRelationalPlan rRevokeRoleAnyPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeRoleAnyPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeUserAll(
+      final AuthorRelationalPlan rRevokeUserAllPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeUserAllPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeRoleAll(
+      final AuthorRelationalPlan rRevokeRoleAllPlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeRoleAllPlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeUserDBPrivilege(
+      final AuthorRelationalPlan rRevokeUserDBPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeUserDBPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeUserTBPrivilege(
+      final AuthorRelationalPlan rRevokeUserTBPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeUserTBPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeRoleDBPrivilege(
+      final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeRoleTBPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeRoleTBPrivilege(
+      final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeRoleTBPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantUserSysPrivilege(
+      final AuthorRelationalPlan rGrantUserSysPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantUserSysPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRGrantRoleSysPrivilege(
+      final AuthorRelationalPlan rGrantRoleSysPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rGrantRoleSysPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeUserSysPrivilege(
+      final AuthorRelationalPlan rRevokeUserSysPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeUserSysPrivilegePlan, context);
+  }
+
+  @Override
+  public TSStatus visitRRevokeRoleSysPrivilege(
+      final AuthorRelationalPlan rRevokeRoleSysPrivilegePlan, final TSStatus context) {
+    return visitAuthorRelationalPlan(rRevokeRoleSysPrivilegePlan, context);
+  }
+
+  private TSStatus visitAuthorRelationalPlan(
+      final AuthorRelationalPlan plan, final TSStatus context) {
+    if (context.getCode() == TSStatusCode.USER_NOT_EXIST.getStatusCode()
+        || context.getCode() == TSStatusCode.USER_ALREADY_EXIST.getStatusCode()
+        || context.getCode() == TSStatusCode.ROLE_NOT_EXIST.getStatusCode()
+        || context.getCode() == TSStatusCode.ROLE_ALREADY_EXIST.getStatusCode()
+        || context.getCode() == TSStatusCode.USER_ALREADY_HAS_ROLE.getStatusCode()
+        || context.getCode() == TSStatusCode.USER_NOT_HAS_ROLE.getStatusCode()
+        || context.getCode() == TSStatusCode.NO_PERMISSION.getStatusCode()) {
+      return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
+          .setMessage(context.getMessage());
+    }
+    return visitPlan(plan, context);
   }
 
   @Override
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanScopeParseVisitorTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanScopeParseVisitorTest.java
new file mode 100644
index 00000000000..6e5e9870fbf
--- /dev/null
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanScopeParseVisitorTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.manager.pipe.extractor;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.stream.Collectors;
+
+public class PipeConfigPhysicalPlanScopeParseVisitorTest {
+  @Test
+  public void testTreeScopeParsing() {
+    testTreeScopeParsing(ConfigPhysicalPlanType.GrantRole, false);
+    testTreeScopeParsing(ConfigPhysicalPlanType.RevokeRole, false);
+    testTreeScopeParsing(ConfigPhysicalPlanType.GrantUser, true);
+    testTreeScopeParsing(ConfigPhysicalPlanType.RevokeUser, true);
+  }
+
+  private void testTreeScopeParsing(final ConfigPhysicalPlanType type, final boolean isUser) {
+    Assert.assertEquals(
+        new AuthorTreePlan(
+            type,
+            isUser ? "user" : "",
+            isUser ? "" : "role",
+            "",
+            "",
+            new HashSet<>(
+                Arrays.stream(PrivilegeType.values())
+                    .filter(PrivilegeType::forRelationalSys)
+                    .map(Enum::ordinal)
+                    .collect(Collectors.toList())),
+            false,
+            Collections.singletonList(new PartialPath(new String[] {"root", "**"}))),
+        IoTDBConfigRegionExtractor.TREE_SCOPE_PARSE_VISITOR
+            .process(
+                new AuthorTreePlan(
+                    type,
+                    isUser ? "user" : "",
+                    isUser ? "" : "role",
+                    "",
+                    "",
+                    new HashSet<>(
+                        Arrays.stream(PrivilegeType.values())
+                            .filter(privilegeType -> !privilegeType.isRelationalPrivilege())
+                            .map(Enum::ordinal)
+                            .collect(Collectors.toList())),
+                    false,
+                    Collections.singletonList(new PartialPath(new String[] {"root", "**"}))),
+                null)
+            .orElseThrow(AssertionError::new));
+  }
+
+  @Test
+  public void testTableScopeParsing() {
+    testTableScopeParsing(
+        ConfigPhysicalPlanType.GrantRole, ConfigPhysicalPlanType.RGrantRoleAll, false);
+    testTableScopeParsing(
+        ConfigPhysicalPlanType.RevokeRole, ConfigPhysicalPlanType.RRevokeRoleAll, false);
+    testTableScopeParsing(
+        ConfigPhysicalPlanType.GrantUser, ConfigPhysicalPlanType.RGrantUserAll, true);
+    testTableScopeParsing(
+        ConfigPhysicalPlanType.RevokeUser, ConfigPhysicalPlanType.RRevokeUserAll, true);
+  }
+
+  private void testTableScopeParsing(
+      final ConfigPhysicalPlanType outputType,
+      final ConfigPhysicalPlanType inputType,
+      final boolean isUser) {
+    Assert.assertEquals(
+        new AuthorTreePlan(
+            outputType,
+            isUser ? "user" : "",
+            isUser ? "" : "role",
+            "",
+            "",
+            new HashSet<>(
+                Arrays.stream(PrivilegeType.values())
+                    .filter(PrivilegeType::forRelationalSys)
+                    .map(Enum::ordinal)
+                    .collect(Collectors.toList())),
+            true,
+            Collections.emptyList()),
+        IoTDBConfigRegionExtractor.TABLE_SCOPE_PARSE_VISITOR
+            .process(
+                new AuthorRelationalPlan(
+                    inputType, isUser ? "user" : "", isUser ? "" : "role", "", "", -1, true),
+                null)
+            .orElseThrow(AssertionError::new));
+  }
+}
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java
index 0681dc5aaca..64ec14be5d8 100644
--- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java
@@ -19,10 +19,12 @@
 
 package org.apache.iotdb.confignode.manager.pipe.extractor;
 
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
 import org.apache.iotdb.commons.pipe.datastructure.pattern.TablePattern;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
 import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
 import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeCreateTablePlan;
@@ -112,6 +114,29 @@ public class PipeConfigPhysicalPlanTablePatternParseVisitorTest {
         new CommitDeleteTablePlan("da", "ac"));
   }
 
+  @Test
+  public void testAuth() {
+    testInput(
+        new AuthorRelationalPlan(
+            ConfigPhysicalPlanType.RGrantRoleAll, "", "role", "", "", -1, false),
+        new AuthorRelationalPlan(
+            ConfigPhysicalPlanType.RGrantUserDBPriv,
+            "user",
+            "",
+            "da",
+            "",
+            PrivilegeType.SELECT.ordinal(),
+            false),
+        new AuthorRelationalPlan(
+            ConfigPhysicalPlanType.RGrantUserTBPriv,
+            "user",
+            "",
+            "db1",
+            "ac",
+            PrivilegeType.DROP.ordinal(),
+            false));
+  }
+
   private void testInput(
       final ConfigPhysicalPlan trueInput,
       final ConfigPhysicalPlan falseInput1,
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java
index cb64d208b38..86e985f330c 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java
@@ -41,8 +41,8 @@ import java.util.stream.Collectors;
 import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getExclusionString;
 import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getInclusionString;
 import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.parseOptions;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefix;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefix;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefixes;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefixes;
 
 /**
  * {@link SchemaRegionListeningFilter} is to classify the {@link PlanNode}s to help {@link
@@ -118,11 +118,11 @@ public class SchemaRegionListeningFilter {
     exclusionOptions.forEach(exclusion -> planTypes.removeAll(getOptionsByPrefix(exclusion)));
 
     if (!TreePattern.isTreeModelDataAllowToBeCaptured(parameters)) {
-      planTypes.removeAll(getOptionsByPrefix(treeOnlySyncPrefix));
+      treeOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
     }
 
     if (!TablePattern.isTableModelDataAllowToBeCaptured(parameters)) {
-      planTypes.removeAll(getOptionsByPrefix(tableOnlySyncPrefix));
+      tableOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
     }
     return planTypes;
   }
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java
index a4a91f504a0..61478ed88b1 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java
@@ -30,6 +30,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
@@ -45,10 +46,16 @@ import static org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstan
 public class PipeInclusionOptions {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(PipeInclusionOptions.class);
-  public static final PartialPath treeOnlySyncPrefix =
-      new PartialPath(new String[] {"schema", "timeseries"});
-  public static final PartialPath tableOnlySyncPrefix =
-      new PartialPath(new String[] {"schema", "table"});
+  public static final List<PartialPath> treeOnlySyncPrefixes =
+      Collections.singletonList(new PartialPath(new String[] {"schema", "timeseries"}));
+  public static final List<PartialPath> tableOnlySyncPrefixes =
+      Collections.unmodifiableList(
+          Arrays.asList(
+              new PartialPath(new String[] {"schema", "table"}),
+              new PartialPath(new String[] {"auth", "role", "grant", "table"}),
+              new PartialPath(new String[] {"auth", "role", "revoke", "table"}),
+              new PartialPath(new String[] {"auth", "user", "grant", "table"}),
+              new PartialPath(new String[] {"auth", "user", "revoke", "table"})));
   public static final String ALL = "all";
 
   private static final Set<PartialPath> OPTIONS = new HashSet<>();