This is an automated email from the ASF dual-hosted git repository.
liuxun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 9af57e84e [#5336] feat(auth-ranger): Remove MANAGED_BY_GRAVITINO limit
and compatible for existing ranger policy (#5629)
9af57e84e is described below
commit 9af57e84e48d584edef22064446d10e30104e5a5
Author: theoryxu <[email protected]>
AuthorDate: Wed Nov 27 12:50:40 2024 +0800
[#5336] feat(auth-ranger): Remove MANAGED_BY_GRAVITINO limit and compatible
for existing ranger policy (#5629)
### What changes were proposed in this pull request?
Many clients and users have used Ranger for a while. Gravitino should be
compatible with these cases.
There are some principles Gravitino needs to follow when it pushes down
policies:
1. Gravitino can't modify existing policy names because users may have
their own name rules.
2. Gravitino and users could share the same policy and not disturb each
other for the same resource.
For the target, this PR includes the following changes:
1. `wildcardSearchPolies` removes the `MANAGED_BY_GRAVITINO` filter.
2. Gravitino managed role name add the prefix `GRAVITINO_`.
3. Using Gravitino Managed role to identify and operate policy items.
Despite doing these, users should be cautious about directly managing
the ranger policy. There are some restricts:
1. Don't directly rename Gravitino-managed policies.
2. Don't directly modify policy resources in the policy that have
Gravitino Managed roles.
3. Don't directly modify policy items that have Gravitino Managed roles.
### Why are the changes needed?
Fix: #5336
### Does this PR introduce _any_ user-facing change?
N/A
### How was this patch tested?
Added ITs
---------
Co-authored-by: theoryxu <[email protected]>
---
.../ranger/RangerAuthorizationPlugin.java | 70 +++---
.../authorization/ranger/RangerHelper.java | 136 ++++++++----
.../ranger/integration/test/RangerHiveIT.java | 235 ++++++++++++++-------
.../ranger/integration/test/RangerITEnv.java | 24 +--
docs/security/authorization-pushdown.md | 6 +
5 files changed, 305 insertions(+), 166 deletions(-)
diff --git
a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java
b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java
index b0e46d5c1..1b2c924d2 100644
---
a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java
+++
b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java
@@ -148,7 +148,8 @@ public abstract class RangerAuthorizationPlugin
.toArray(RoleChange[]::new));
// Lastly, delete the role in the Ranger
try {
- rangerClient.deleteRole(role.name(), rangerAdminName, rangerServiceName);
+ rangerClient.deleteRole(
+ rangerHelper.generateGravitinoRoleName(role.name()),
rangerAdminName, rangerServiceName);
} catch (RangerServiceException e) {
// Ignore exception to support idempotent operation
LOG.warn("Ranger delete role: {} failed!", role, e);
@@ -333,6 +334,7 @@ public abstract class RangerAuthorizationPlugin
ownerRoleName = RangerHelper.GRAVITINO_CATALOG_OWNER_ROLE;
}
rangerHelper.createRangerRoleIfNotExists(ownerRoleName, true);
+
rangerHelper.createRangerRoleIfNotExists(RangerHelper.GRAVITINO_OWNER_ROLE,
true);
try {
if (preOwnerUserName != null || preOwnerGroupName != null) {
GrantRevokeRoleRequest revokeRoleRequest =
@@ -607,7 +609,6 @@ public abstract class RangerAuthorizationPlugin
*/
private boolean doAddSecurableObject(String roleName, RangerSecurableObject
securableObject) {
RangerPolicy policy = rangerHelper.findManagedPolicy(securableObject);
-
if (policy != null) {
// Check the policy item's accesses and roles equal the Ranger securable
object's privilege
List<RangerPrivilege> allowPrivilies =
@@ -621,7 +622,11 @@ public abstract class RangerAuthorizationPlugin
Set<RangerPrivilege> policyPrivileges =
policy.getPolicyItems().stream()
- .filter(policyItem -> policyItem.getRoles().contains(roleName))
+ .filter(
+ policyItem ->
+ policyItem
+ .getRoles()
+
.contains(rangerHelper.generateGravitinoRoleName(roleName)))
.flatMap(policyItem -> policyItem.getAccesses().stream())
.map(RangerPolicy.RangerPolicyItemAccess::getType)
.map(RangerPrivileges::valueOf)
@@ -629,7 +634,11 @@ public abstract class RangerAuthorizationPlugin
Set<RangerPrivilege> policyDenyPrivileges =
policy.getDenyPolicyItems().stream()
- .filter(policyItem -> policyItem.getRoles().contains(roleName))
+ .filter(
+ policyItem ->
+ policyItem
+ .getRoles()
+
.contains(rangerHelper.generateGravitinoRoleName(roleName)))
.flatMap(policyItem -> policyItem.getAccesses().stream())
.map(RangerPolicy.RangerPolicyItemAccess::getType)
.map(RangerPrivileges::valueOf)
@@ -721,11 +730,7 @@ public abstract class RangerAuthorizationPlugin
&& policyItem.getGroups().isEmpty());
try {
- if (policy.getPolicyItems().isEmpty() &&
policy.getDenyPolicyItems().isEmpty()) {
- rangerClient.deletePolicy(policy.getId());
- } else {
- rangerClient.updatePolicy(policy.getId(), policy);
- }
+ rangerClient.updatePolicy(policy.getId(), policy);
} catch (RangerServiceException e) {
LOG.error("Failed to remove the policy item from the Ranger policy {}!",
policy);
throw new AuthorizationPluginException(
@@ -738,6 +743,7 @@ public abstract class RangerAuthorizationPlugin
RangerPolicy.RangerPolicyItem policyItem,
RangerSecurableObject rangerSecurableObject,
String roleName) {
+ roleName = rangerHelper.generateGravitinoRoleName(roleName);
boolean match =
policyItem.getAccesses().stream()
.allMatch(
@@ -793,15 +799,8 @@ public abstract class RangerAuthorizationPlugin
try {
List<RangerPolicy> policies =
rangerClient.getPoliciesInService(rangerServiceName);
policies.stream()
- .forEach(
- policy -> {
- try {
- rangerClient.deletePolicy(policy.getId());
- } catch (RangerServiceException e) {
- LOG.error("Failed to rename the policy {}!", policy);
- throw new RuntimeException(e);
- }
- });
+ .filter(rangerHelper::hasGravitinoManagedPolicyItem)
+ .forEach(rangerHelper::removeAllGravitinoManagedPolicyItem);
} catch (RangerServiceException e) {
throw new RuntimeException(e);
}
@@ -970,16 +969,7 @@ public abstract class RangerAuthorizationPlugin
.getValues()
.contains(preciseFilters.get(entry.getKey()))))
.collect(Collectors.toList());
- policies.stream()
- .forEach(
- policy -> {
- try {
- rangerClient.deletePolicy(policy.getId());
- } catch (RangerServiceException e) {
- LOG.error("Failed to rename the policy {}!", policy);
- throw new RuntimeException(e);
- }
- });
+ policies.forEach(rangerHelper::removeAllGravitinoManagedPolicyItem);
}
private void updatePolicyByMetadataObject(
@@ -1003,25 +993,29 @@ public abstract class RangerAuthorizationPlugin
.forEach(
policy -> {
try {
- // Update the policy name
String policyName = policy.getName();
- List<String> policyNames =
Lists.newArrayList(DOT_SPLITTER.splitToList(policyName));
- Preconditions.checkArgument(
- policyNames.size() >= oldMetadataNames.size(),
- String.format("The policy name(%s) is invalid!",
policyName));
int index = operationTypeIndex.get(operationType);
- if (policyNames.get(index).equals(RangerHelper.RESOURCE_ALL)) {
- // Doesn't need to rename the policy `*`
- return;
+
+ // Update the policy name is following Gravitino's spec
+ if
(policy.getName().equals(DOT_JOINER.join(oldMetadataNames))) {
+ List<String> policyNames =
+ Lists.newArrayList(DOT_SPLITTER.splitToList(policyName));
+ Preconditions.checkArgument(
+ policyNames.size() >= oldMetadataNames.size(),
+ String.format("The policy name(%s) is invalid!",
policyName));
+ if
(policyNames.get(index).equals(RangerHelper.RESOURCE_ALL)) {
+ // Doesn't need to rename the policy `*`
+ return;
+ }
+ policyNames.set(index, newMetadataNames.get(index));
+ policy.setName(DOT_JOINER.join(policyNames));
}
- policyNames.set(index, newMetadataNames.get(index));
// Update the policy resource name to new name
policy
.getResources()
.put(
rangerHelper.policyResourceDefines.get(index),
new
RangerPolicy.RangerPolicyResource(newMetadataNames.get(index)));
- policy.setName(DOT_JOINER.join(policyNames));
boolean alreadyExist =
existNewPolicies.stream()
diff --git
a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java
b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java
index b8c9868f6..cb74ad026 100644
---
a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java
+++
b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java
@@ -19,10 +19,8 @@
package org.apache.gravitino.authorization.ranger;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -58,8 +56,14 @@ public class RangerHelper {
private final RangerClient rangerClient;
private final String rangerAdminName;
private final String rangerServiceName;
- public static final String GRAVITINO_METALAKE_OWNER_ROLE =
"GRAVITINO_METALAKE_OWNER_ROLE";
- public static final String GRAVITINO_CATALOG_OWNER_ROLE =
"GRAVITINO_CATALOG_OWNER_ROLE";
+
+ public static final String GRAVITINO_ROLE_PREFIX = "GRAVITINO_";
+ public static final String GRAVITINO_METALAKE_OWNER_ROLE =
+ GRAVITINO_ROLE_PREFIX + "METALAKE_OWNER_ROLE";
+ public static final String GRAVITINO_CATALOG_OWNER_ROLE =
+ GRAVITINO_ROLE_PREFIX + "CATALOG_OWNER_ROLE";
+ // marking owner policy items
+ public static final String GRAVITINO_OWNER_ROLE = GRAVITINO_ROLE_PREFIX +
"OWNER_ROLE";
public RangerHelper(
RangerClient rangerClient,
@@ -75,29 +79,22 @@ public class RangerHelper {
}
/**
- * For easy management, each privilege will create one
RangerPolicyItemAccess in the policy.
+ * There are two types of policy items. Gravitino managed policy items: They
contain one privilege
+ * each. User-defined policy items: They could contain multiple privileges
and not be managed and
+ * checked by Gravitino.
*
* @param policyItem The policy item to check
* @throws AuthorizationPluginException If the policy item contains more
than one access type
*/
void checkPolicyItemAccess(RangerPolicy.RangerPolicyItem policyItem)
throws AuthorizationPluginException {
+ if (!isGravitinoManagedPolicyItemAccess(policyItem)) {
+ return;
+ }
if (policyItem.getAccesses().size() != 1) {
throw new AuthorizationPluginException(
"The access type only have one in the delegate Gravitino management
policy");
}
- Set<String> setAccesses = new HashSet<>();
- policyItem
- .getAccesses()
- .forEach(
- access -> {
- if (setAccesses.contains(access.getType())) {
- throw new AuthorizationPluginException(
- "Contain duplicate privilege(%s) in the delegate Gravitino
management policy ",
- access.getType());
- }
- setAccesses.add(access.getType());
- });
}
/**
@@ -120,7 +117,9 @@ public class RangerHelper {
policyItem -> {
return policyItem.getAccesses().stream()
.anyMatch(
- access ->
access.getType().equals(rangerPrivilege.getName()));
+ access ->
+
access.getType().equals(rangerPrivilege.getName())
+ &&
isGravitinoManagedPolicyItemAccess(policyItem));
})
.collect(Collectors.toList());
} else {
@@ -130,7 +129,9 @@ public class RangerHelper {
policyItem -> {
return policyItem.getAccesses().stream()
.anyMatch(
- access ->
access.getType().equals(rangerPrivilege.getName()));
+ access ->
+
access.getType().equals(rangerPrivilege.getName())
+ &&
isGravitinoManagedPolicyItemAccess(policyItem));
})
.collect(Collectors.toList());
}
@@ -142,7 +143,7 @@ public class RangerHelper {
new RangerPolicy.RangerPolicyItemAccess();
access.setType(rangerPrivilege.getName());
policyItem.getAccesses().add(access);
- policyItem.getRoles().add(roleName);
+ policyItem.getRoles().add(generateGravitinoRoleName(roleName));
if (Privilege.Condition.ALLOW == rangerPrivilege.condition()) {
policy.getPolicyItems().add(policyItem);
} else {
@@ -154,8 +155,10 @@ public class RangerHelper {
.forEach(
policyItem -> {
// If the role is not in the policy item, then add it
- if (!policyItem.getRoles().contains(roleName)) {
- policyItem.getRoles().add(roleName);
+ if (!policyItem
+ .getRoles()
+ .contains(generateGravitinoRoleName(roleName))) {
+
policyItem.getRoles().add(generateGravitinoRoleName(roleName));
}
});
}
@@ -172,7 +175,6 @@ public class RangerHelper {
throws AuthorizationPluginException {
Map<String, String> searchFilters = new HashMap<>();
searchFilters.put(SearchFilter.SERVICE_NAME, rangerServiceName);
- searchFilters.put(SearchFilter.POLICY_LABELS_PARTIAL,
MANAGED_BY_GRAVITINO);
for (int i = 0; i < metadataNames.size(); i++) {
searchFilters.put(
SearchFilter.RESOURCE_PREFIX + policyResourceDefines.get(i),
metadataNames.get(i));
@@ -224,8 +226,7 @@ public class RangerHelper {
}
// Only return the policies that are managed by Gravitino.
if (policies.size() > 1) {
- throw new AuthorizationPluginException(
- "Every metadata object has only a Gravitino managed policy.");
+ throw new AuthorizationPluginException("Each metadata object can have at
most one policy.");
}
if (policies.isEmpty()) {
@@ -242,7 +243,45 @@ public class RangerHelper {
return policy;
}
+ public boolean
isGravitinoManagedPolicyItemAccess(RangerPolicy.RangerPolicyItem policyItem) {
+ return policyItem.getRoles().stream().anyMatch(role ->
role.startsWith(GRAVITINO_ROLE_PREFIX));
+ }
+
+ public boolean hasGravitinoManagedPolicyItem(RangerPolicy policy) {
+ List<RangerPolicy.RangerPolicyItem> policyItems = policy.getPolicyItems();
+ policyItems.addAll(policy.getDenyPolicyItems());
+ policyItems.addAll(policy.getRowFilterPolicyItems());
+ policyItems.addAll(policy.getDataMaskPolicyItems());
+ return
policyItems.stream().anyMatch(this::isGravitinoManagedPolicyItemAccess);
+ }
+
+ public void removeAllGravitinoManagedPolicyItem(RangerPolicy policy) {
+ try {
+ policy.setPolicyItems(
+ policy.getPolicyItems().stream()
+ .filter(item -> !isGravitinoManagedPolicyItemAccess(item))
+ .collect(Collectors.toList()));
+ policy.setDenyPolicyItems(
+ policy.getDenyPolicyItems().stream()
+ .filter(item -> !isGravitinoManagedPolicyItemAccess(item))
+ .collect(Collectors.toList()));
+ policy.setRowFilterPolicyItems(
+ policy.getRowFilterPolicyItems().stream()
+ .filter(item -> !isGravitinoManagedPolicyItemAccess(item))
+ .collect(Collectors.toList()));
+ policy.setDataMaskPolicyItems(
+ policy.getDataMaskPolicyItems().stream()
+ .filter(item -> !isGravitinoManagedPolicyItemAccess(item))
+ .collect(Collectors.toList()));
+ rangerClient.updatePolicy(policy.getId(), policy);
+ } catch (RangerServiceException e) {
+ LOG.error("Failed to update the policy {}!", policy);
+ throw new RuntimeException(e);
+ }
+ }
+
protected boolean checkRangerRole(String roleName) throws
AuthorizationPluginException {
+ roleName = generateGravitinoRoleName(roleName);
try {
rangerClient.getRole(roleName, rangerAdminName, rangerServiceName);
} catch (RangerServiceException e) {
@@ -252,8 +291,16 @@ public class RangerHelper {
return true;
}
+ public String generateGravitinoRoleName(String roleName) {
+ if (roleName.startsWith(GRAVITINO_ROLE_PREFIX)) {
+ return roleName;
+ }
+ return GRAVITINO_ROLE_PREFIX + roleName;
+ }
+
protected GrantRevokeRoleRequest createGrantRevokeRoleRequest(
String roleName, String userName, String groupName) {
+ roleName = generateGravitinoRoleName(roleName);
Set<String> users =
StringUtils.isEmpty(userName) ? Sets.newHashSet() :
Sets.newHashSet(userName);
Set<String> groups =
@@ -278,16 +325,23 @@ public class RangerHelper {
* @param isOwnerRole The role is owner role or not
*/
protected RangerRole createRangerRoleIfNotExists(String roleName, boolean
isOwnerRole) {
+ roleName = generateGravitinoRoleName(roleName);
if (isOwnerRole) {
Preconditions.checkArgument(
roleName.equalsIgnoreCase(GRAVITINO_METALAKE_OWNER_ROLE)
- || roleName.equalsIgnoreCase(GRAVITINO_CATALOG_OWNER_ROLE),
- "The role name should be GRAVITINO_METALAKE_OWNER_ROLE or
GRAVITINO_CATALOG_OWNER_ROLE");
+ || roleName.equalsIgnoreCase(GRAVITINO_CATALOG_OWNER_ROLE)
+ || roleName.equalsIgnoreCase(GRAVITINO_OWNER_ROLE),
+ String.format(
+ "The role name should be %s or %s or %s",
+ GRAVITINO_METALAKE_OWNER_ROLE, GRAVITINO_CATALOG_OWNER_ROLE,
GRAVITINO_OWNER_ROLE));
} else {
Preconditions.checkArgument(
!roleName.equalsIgnoreCase(GRAVITINO_METALAKE_OWNER_ROLE)
- && !roleName.equalsIgnoreCase(GRAVITINO_CATALOG_OWNER_ROLE),
- "The role name should not be GRAVITINO_METALAKE_OWNER_ROLE or
GRAVITINO_CATALOG_OWNER_ROLE");
+ && !roleName.equalsIgnoreCase(GRAVITINO_CATALOG_OWNER_ROLE)
+ && !roleName.equalsIgnoreCase(GRAVITINO_OWNER_ROLE),
+ String.format(
+ "The role name should not be %s or %s or %s",
+ GRAVITINO_METALAKE_OWNER_ROLE, GRAVITINO_CATALOG_OWNER_ROLE,
GRAVITINO_OWNER_ROLE));
}
RangerRole rangerRole = null;
@@ -325,6 +379,7 @@ public class RangerHelper {
});
});
})
+ .filter(this::isGravitinoManagedPolicyItemAccess)
.collect(Collectors.toList());
// Add or remove the owner in the policy item
matchPolicyItems.forEach(
@@ -376,6 +431,8 @@ public class RangerHelper {
} else {
policyItem.getGroups().add(newOwner.name());
}
+ // mark the policy item is created by Gravitino
+ addRoleToPolicyItemIfNoExists(policyItem,
GRAVITINO_OWNER_ROLE);
}
policy.getPolicyItems().add(policyItem);
});
@@ -385,7 +442,6 @@ public class RangerHelper {
RangerPolicy policy = new RangerPolicy();
policy.setService(rangerServiceName);
policy.setName(metadataObject.fullName());
-
policy.setPolicyLabels(Lists.newArrayList(RangerHelper.MANAGED_BY_GRAVITINO));
List<String> nsMetadataObject = metadataObject.names();
for (int i = 0; i < nsMetadataObject.size(); i++) {
RangerPolicy.RangerPolicyResource policyResource =
@@ -411,6 +467,8 @@ public class RangerHelper {
} else {
policyItem.getGroups().add(newOwner.name());
}
+ // mark the policy item is created by Gravitino
+ policyItem.getRoles().add(GRAVITINO_OWNER_ROLE);
}
policy.getPolicyItems().add(policyItem);
});
@@ -428,7 +486,7 @@ public class RangerHelper {
policyItem
.getAccesses()
.add(new
RangerPolicy.RangerPolicyItemAccess(ownerPrivilege.getName()));
- policyItem.getRoles().add(ownerRoleName);
+ policyItem.getRoles().add(generateGravitinoRoleName(ownerRoleName));
policy.getPolicyItems().add(policyItem);
});
return policy;
@@ -454,9 +512,7 @@ public class RangerHelper {
// Add or remove the owner role in the policy item
matchPolicyItems.forEach(
policyItem -> {
- if (!policyItem.getRoles().contains(ownerRoleName)) {
- policyItem.getRoles().add(ownerRoleName);
- }
+ addRoleToPolicyItemIfNoExists(policyItem, ownerRoleName);
});
// If the policy item is not equal to owner's privileges, then update the
policy
@@ -480,10 +536,16 @@ public class RangerHelper {
policyItem
.getAccesses()
.add(new
RangerPolicy.RangerPolicyItemAccess(ownerPrivilege.getName()));
- if (!policyItem.getRoles().contains(ownerRoleName)) {
- policyItem.getRoles().add(ownerRoleName);
- }
+ addRoleToPolicyItemIfNoExists(policyItem, ownerRoleName);
policy.getPolicyItems().add(policyItem);
});
}
+
+ private void addRoleToPolicyItemIfNoExists(
+ RangerPolicy.RangerPolicyItem policyItem, String roleName) {
+ String gravitinoRoleName = generateGravitinoRoleName(roleName);
+ if (!policyItem.getRoles().contains(gravitinoRoleName)) {
+ policyItem.getRoles().add(gravitinoRoleName);
+ }
+ }
}
diff --git
a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java
b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java
index da43daca7..7c45ff9b0 100644
---
a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java
+++
b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java
@@ -33,7 +33,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
import org.apache.gravitino.MetadataObject;
import org.apache.gravitino.MetadataObjects;
import org.apache.gravitino.authorization.MetadataObjectChange;
@@ -50,7 +52,6 @@ import
org.apache.gravitino.authorization.ranger.RangerMetadataObject;
import org.apache.gravitino.authorization.ranger.RangerPrivileges;
import org.apache.gravitino.authorization.ranger.RangerSecurableObject;
import org.apache.gravitino.authorization.ranger.reference.RangerDefines;
-import org.apache.gravitino.exceptions.AuthorizationPluginException;
import org.apache.gravitino.integration.test.util.GravitinoITUtils;
import org.apache.gravitino.meta.AuditInfo;
import org.apache.gravitino.meta.GroupEntity;
@@ -209,9 +210,9 @@ public class RangerHiveIT {
Role mockCatalogRole = mockCatalogRole(currentFunName());
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(mockCatalogRole));
// Check if exist this policy
- assertFindManagedPolicy(mockCatalogRole, true);
+ assertFindManagedPolicyItems(mockCatalogRole, true);
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(mockCatalogRole));
- assertFindManagedPolicy(mockCatalogRole, false);
+ assertFindManagedPolicyItems(mockCatalogRole, false);
}
@Test
@@ -232,7 +233,7 @@ public class RangerHiveIT {
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(mockCatalogRole));
// Check if exist this policy
- assertFindManagedPolicy(mockCatalogRole, true);
+ assertFindManagedPolicyItems(mockCatalogRole, true);
mockCatalogRole.securableObjects().stream()
.forEach(
securableObject -> {
@@ -250,7 +251,7 @@ public class RangerHiveIT {
});
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(mockCatalogRole));
- assertFindManagedPolicy(mockCatalogRole, false);
+ assertFindManagedPolicyItems(mockCatalogRole, false);
}
@Test
@@ -258,12 +259,12 @@ public class RangerHiveIT {
// prepare to create a role
RoleEntity role = mock3TableRole(currentFunName());
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
// delete this role
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(role));
// Check if the policy is deleted
- assertFindManagedPolicy(role, false);
+ assertFindManagedPolicyItems(role, false);
}
@Test
@@ -274,7 +275,7 @@ public class RangerHiveIT {
// delete this role
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(mockCatalogRole));
// Check if exist this policy
- assertFindManagedPolicy(mockCatalogRole, false);
+ assertFindManagedPolicyItems(mockCatalogRole, false);
}
@Test
@@ -293,7 +294,7 @@ public class RangerHiveIT {
// delete this role
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(role));
// Because this metaobject has owner, so the policy should not be deleted
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, false);
}
@Test
@@ -327,20 +328,16 @@ public class RangerHiveIT {
String dbName = currentFunName();
createHivePolicy(
Lists.newArrayList(String.format("%s*", dbName), "*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
createHivePolicy(
Lists.newArrayList(String.format("%s*", dbName), "tab*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
createHivePolicy(
Lists.newArrayList(String.format("%s3", dbName), "*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
createHivePolicy(
Lists.newArrayList(String.format("%s3", dbName), "tab*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
// findManagedPolicy function use precise search, so return null
RangerSecurableObject rangerSecurableObject =
rangerAuthHivePlugin.generateRangerSecurableObject(
@@ -354,14 +351,13 @@ public class RangerHiveIT {
// Add a policy for `db3.tab1`
createHivePolicy(
Lists.newArrayList(String.format("%s3", dbName), "tab1"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
// findManagedPolicy function use precise search, so return not null
Assertions.assertNotNull(rangerHelper.findManagedPolicy(rangerSecurableObject));
}
@Test
- public void testManagedByGravitinoLabel() {
+ public void testGravitinoCompatibleWithExistingPolicy() {
RoleEntity role = mock3TableRole(currentFunName());
role.securableObjects().stream()
.forEach(
@@ -372,15 +368,71 @@ public class RangerHiveIT {
SecurableObjects.DOT_SPLITTER.splitToList(securableObject.fullName()));
names.remove(0); // remove catalog node
// Manual create the Ranger Policy
- createHivePolicy(Lists.newArrayList(names),
DOT_JOINER.join(names), false);
+ createHivePolicy(Lists.newArrayList(names),
DOT_JOINER.join(names));
+ });
+ List<String> existingPolicyNames =
+ findRoleResourceRelatedPolicies(role).stream()
+ .map(RangerPolicy::getName)
+ .collect(Collectors.toList());
+ rangerAuthHivePlugin.onRoleCreated(role);
+ findRoleResourceRelatedPolicies(role)
+ .forEach(
+ policy -> {
+ List<RangerPolicy.RangerPolicyItem> policyItems = new
ArrayList<>();
+ policyItems.addAll(policy.getPolicyItems());
+ policyItems.addAll(policy.getDenyPolicyItems());
+ policyItems.addAll(policy.getRowFilterPolicyItems());
+ policyItems.addAll(policy.getDataMaskPolicyItems());
+
+ if (existingPolicyNames.contains(policy.getName())) {
+ Assertions.assertTrue(
+ policyItems.stream()
+ .anyMatch(
+ item ->
+ !item.getRoles()
+ .contains(
+
rangerHelper.generateGravitinoRoleName(role.name()))));
+ }
+ Assertions.assertTrue(
+ policyItems.stream()
+ .anyMatch(
+ item ->
+ item.getRoles()
+
.contains(rangerHelper.generateGravitinoRoleName(role.name()))));
+ });
+
+ rangerAuthHivePlugin.onRoleDeleted(role);
+ findRoleResourceRelatedPolicies(role)
+ .forEach(
+ policy -> {
+ List<RangerPolicy.RangerPolicyItem> policyItems = new
ArrayList<>();
+ policyItems.addAll(policy.getPolicyItems());
+ policyItems.addAll(policy.getDenyPolicyItems());
+ policyItems.addAll(policy.getRowFilterPolicyItems());
+ policyItems.addAll(policy.getDataMaskPolicyItems());
+
+ if (existingPolicyNames.contains(policy.getName())) {
+ Assertions.assertFalse(
+ policyItems.stream()
+ .anyMatch(
+ item ->
+ item.getRoles()
+ .contains(
+
rangerHelper.generateGravitinoRoleName(role.name()))));
+ Assertions.assertTrue(
+ policyItems.stream()
+ .anyMatch(
+ item ->
+ !item.getRoles()
+ .contains(
+
rangerHelper.generateGravitinoRoleName(role.name()))));
+ } else {
+ Assertions.assertEquals(0, policyItems.size());
+ }
});
- // Use role to create Ranger Policy
- Assertions.assertThrows(
- AuthorizationPluginException.class, () ->
rangerAuthHivePlugin.onRoleCreated(role));
}
- static void createHivePolicy(
- List<String> metaObjects, String roleName, boolean
labelManagedByGravitino) {
+ static void createHivePolicy(List<String> metaObjects, String roleName) {
Assertions.assertTrue(metaObjects.size() < 4);
Map<String, RangerPolicy.RangerPolicyResource> policyResourceMap = new
HashMap<>();
for (int i = 0; i < metaObjects.size(); i++) {
@@ -404,8 +456,7 @@ public class RangerHiveIT {
RangerITEnv.RANGER_HIVE_REPO_NAME,
roleName,
policyResourceMap,
- Collections.singletonList(policyItem),
- labelManagedByGravitino);
+ Collections.singletonList(policyItem));
}
static boolean deleteHivePolicy(RangerSecurableObject rangerSecurableObject)
{
@@ -473,7 +524,7 @@ public class RangerHiveIT {
mockCatalogRole,
RoleChange.addSecurableObject(
mockCatalogRole.name(),
mockCatalogRole.securableObjects().get(0))));
- assertFindManagedPolicy(mockCatalogRole, true);
+ assertFindManagedPolicyItems(mockCatalogRole, true);
}
@Test
@@ -517,7 +568,7 @@ public class RangerHiveIT {
mockCatalogRole,
RoleChange.removeSecurableObject(
mockCatalogRole.name(),
mockCatalogRole.securableObjects().get(0))));
- assertFindManagedPolicy(mockCatalogRole, false);
+ assertFindManagedPolicyItems(mockCatalogRole, false);
}
@Test
@@ -621,7 +672,7 @@ public class RangerHiveIT {
mockCatalogRole.name(),
mockCatalogRole.securableObjects().get(0),
newSecurableObject)));
- assertFindManagedPolicy(mockCatalogRole, false);
+ assertFindManagedPolicyItems(mockCatalogRole, false);
}
@Test
@@ -643,7 +694,7 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(oldSecurableObject1))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
MetadataObject newMetadataObject =
MetadataObjects.parse(
@@ -663,7 +714,7 @@ public class RangerHiveIT {
.withAuditInfo(auditInfo)
.withSecurableObjects(Lists.newArrayList(newSecurableObject1))
.build();
- assertFindManagedPolicy(newRole, true);
+ assertFindManagedPolicyItems(newRole, true);
}
@Test
@@ -685,7 +736,7 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(oldSecurableObject1))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
MetadataObject newMetadataObject =
MetadataObjects.parse(
@@ -705,7 +756,7 @@ public class RangerHiveIT {
.withAuditInfo(auditInfo)
.withSecurableObjects(Lists.newArrayList(newSecurableObject1))
.build();
- assertFindManagedPolicy(newRole, true);
+ assertFindManagedPolicyItems(newRole, true);
}
@Test
@@ -727,7 +778,7 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(oldSecurableObject1))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
MetadataObject newMetadataObject =
MetadataObjects.parse(
@@ -735,7 +786,7 @@ public class RangerHiveIT {
Assertions.assertTrue(
rangerAuthHivePlugin.onMetadataUpdated(
MetadataObjectChange.rename(oldMetadataObject,
newMetadataObject)));
- assertFindManagedPolicy(role, false);
+ assertFindManagedPolicyItems(role, false);
SecurableObject newSecurableObject1 =
SecurableObjects.parse(
newMetadataObject.fullName(),
@@ -748,7 +799,7 @@ public class RangerHiveIT {
.withAuditInfo(auditInfo)
.withSecurableObjects(Lists.newArrayList(newSecurableObject1))
.build();
- assertFindManagedPolicy(newRole, true);
+ assertFindManagedPolicyItems(newRole, true);
}
@Test
@@ -770,7 +821,7 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(oldSecurableObject1))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
MetadataObject newMetadataObject =
MetadataObjects.parse(
@@ -778,7 +829,7 @@ public class RangerHiveIT {
Assertions.assertTrue(
rangerAuthHivePlugin.onMetadataUpdated(
MetadataObjectChange.rename(oldMetadataObject,
newMetadataObject)));
- assertFindManagedPolicy(role, false);
+ assertFindManagedPolicyItems(role, false);
SecurableObject newSecurableObject1 =
SecurableObjects.parse(
newMetadataObject.fullName(),
@@ -791,7 +842,7 @@ public class RangerHiveIT {
.withAuditInfo(auditInfo)
.withSecurableObjects(Lists.newArrayList(newSecurableObject1))
.build();
- assertFindManagedPolicy(newRole, true);
+ assertFindManagedPolicyItems(newRole, true);
}
@Test
@@ -808,20 +859,16 @@ public class RangerHiveIT {
throws RangerServiceException {
createHivePolicy(
Lists.newArrayList(String.format("%s*", funcName), "*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
createHivePolicy(
Lists.newArrayList(String.format("%s*", funcName), "tab*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
createHivePolicy(
Lists.newArrayList(String.format("%s3", funcName), "*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
createHivePolicy(
Lists.newArrayList(String.format("%s3", funcName), "tab*"),
- GravitinoITUtils.genRandomName(currentFunName()),
- true);
+ GravitinoITUtils.genRandomName(currentFunName()));
Assertions.assertEquals(
4,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
@@ -841,14 +888,20 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(oldSecurableObject1))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
Assertions.assertTrue(
rangerAuthHivePlugin.onMetadataUpdated(MetadataObjectChange.remove(metadataObject)));
- assertFindManagedPolicy(role, false);
+ assertFindManagedPolicyItems(role, false);
Assertions.assertEquals(
- 0,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
+ 6,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
+ rangerClient
+ .getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME)
+ .forEach(
+ policy -> {
+
Assertions.assertFalse(rangerHelper.hasGravitinoManagedPolicyItem(policy));
+ });
}
@Test
@@ -878,7 +931,7 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(schemaSecurableObject,
tableSecurableObject))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
Assertions.assertEquals(
4,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
@@ -891,9 +944,9 @@ public class RangerHiveIT {
.withAuditInfo(auditInfo)
.withSecurableObjects(Lists.newArrayList(schemaSecurableObject))
.build();
- assertFindManagedPolicy(roleVerify, false);
+ assertFindManagedPolicyItems(roleVerify, false);
Assertions.assertEquals(
- 2,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
+ 4,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
}
@Test
@@ -923,7 +976,7 @@ public class RangerHiveIT {
.withSecurableObjects(Lists.newArrayList(securableObjectSchema,
securableObjectTab))
.build();
Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role));
- assertFindManagedPolicy(role, true);
+ assertFindManagedPolicyItems(role, true);
Assertions.assertTrue(
rangerAuthHivePlugin.onMetadataUpdated(MetadataObjectChange.remove(tableObject)));
@@ -941,10 +994,10 @@ public class RangerHiveIT {
.withAuditInfo(auditInfo)
.withSecurableObjects(Lists.newArrayList(securableObjectTab))
.build();
- assertFindManagedPolicy(verifyScheamRole, true);
- assertFindManagedPolicy(verifyTableRole, false);
+ assertFindManagedPolicyItems(verifyScheamRole, true);
+ assertFindManagedPolicyItems(verifyTableRole, false);
Assertions.assertEquals(
- 2,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
+ 4,
rangerClient.getPoliciesInService(RangerITEnv.RANGER_HIVE_REPO_NAME).size());
}
@Test
@@ -1006,8 +1059,8 @@ public class RangerHiveIT {
// Delete the role
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(verifyRole));
- // Because these metaobjects have an owner, so the policy will not be
deleted.
- assertFindManagedPolicy(role, true);
+ // policy item will be deleted.
+ assertFindManagedPolicyItems(role, false);
rangerAuthHivePlugin.translateOwner(oldMetadataObject).stream()
.forEach(
rangerSecurableObject -> {
@@ -1163,22 +1216,49 @@ public class RangerHiveIT {
rangerAuthHivePlugin, role, null, null, null,
Lists.newArrayList(groupName1));
}
- private void assertFindManagedPolicy(Role role, boolean policyExist) {
- role.securableObjects().stream()
- .forEach(
+ private void assertFindManagedPolicyItems(Role role, boolean
gravitinoPolicyItemExist) {
+ List<RangerPolicy> policies = findRoleResourceRelatedPolicies(role);
+
+ if (gravitinoPolicyItemExist) {
+ Assertions.assertTrue(policies.size() > 0);
+ }
+
+ policies.forEach(
+ policy -> {
+ List<RangerPolicy.RangerPolicyItem> policyItems = new ArrayList<>();
+ policyItems.addAll(policy.getPolicyItems());
+ policyItems.addAll(policy.getDenyPolicyItems());
+ policyItems.addAll(policy.getRowFilterPolicyItems());
+ policyItems.addAll(policy.getDataMaskPolicyItems());
+ if (gravitinoPolicyItemExist) {
+
Assertions.assertTrue(hasGravitinoManagedPolicyItemAccess(policyItems,
role.name()));
+ } else {
+
Assertions.assertFalse(hasGravitinoManagedPolicyItemAccess(policyItems,
role.name()));
+ }
+ });
+ }
+
+ private List<RangerPolicy> findRoleResourceRelatedPolicies(Role role) {
+ return role.securableObjects().stream()
+ .flatMap(
securableObject ->
rangerAuthHivePlugin.translatePrivilege(securableObject).stream()
- .forEach(
+ .map(
rangerSecurableObject -> {
LOG.info("rangerSecurableObject: " +
rangerSecurableObject);
- if (policyExist) {
- Assertions.assertNotNull(
-
rangerHelper.findManagedPolicy(rangerSecurableObject));
- } else {
- Assertions.assertNull(
-
rangerHelper.findManagedPolicy(rangerSecurableObject));
- }
- }));
+ return
rangerHelper.findManagedPolicy(rangerSecurableObject);
+ }))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ public boolean hasGravitinoManagedPolicyItemAccess(
+ List<RangerPolicy.RangerPolicyItem> items, String roleName) {
+ return items.stream()
+ .anyMatch(
+ item ->
+ item.getRoles().stream()
+ .anyMatch(r ->
r.equals(rangerHelper.generateGravitinoRoleName(roleName))));
}
private static class MockOwner implements Owner {
@@ -1729,14 +1809,14 @@ public class RangerHiveIT {
Lists.newArrayList(groupName1, groupName2, groupName3));
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(role1));
- // Because role1's secrable object have owner, so the policy will not be
deleted.
- assertFindManagedPolicy(role1, true);
+ // policy items will be deleted.
+ assertFindManagedPolicyItems(role1, false);
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(role2));
- assertFindManagedPolicy(role2, true);
+ assertFindManagedPolicyItems(role2, false);
Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(role3));
- assertFindManagedPolicy(role3, true);
+ assertFindManagedPolicyItems(role3, false);
}
/**
@@ -1764,7 +1844,6 @@ public class RangerHiveIT {
}
Assertions.assertEquals(policy.getName(), policyName);
-
Assertions.assertTrue(policy.getPolicyLabels().contains(RangerHelper.MANAGED_BY_GRAVITINO));
// verify namespace
List<String> metaObjNamespaces = rangerSecurableObject.names();
diff --git
a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java
b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java
index 13202add7..0c6dd5803 100644
---
a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java
+++
b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java
@@ -20,7 +20,6 @@ package
org.apache.gravitino.authorization.ranger.integration.test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -180,8 +179,7 @@ public class RangerITEnv {
RANGER_HDFS_REPO_NAME,
policyName,
policyResourceMap,
- Collections.singletonList(policyItem),
- false);
+ Collections.singletonList(policyItem));
}
/**
@@ -218,8 +216,7 @@ public class RangerITEnv {
RANGER_HIVE_REPO_NAME,
policyName,
policyResourceMap,
- Collections.singletonList(policyItem),
- false);
+ Collections.singletonList(policyItem));
}
public void createRangerTrinoRepository(String trinoIp) {
@@ -380,7 +377,9 @@ public class RangerITEnv {
try {
rangerRole =
RangerITEnv.rangerClient.getRole(
- role.name(), rangerAuthPlugin.rangerAdminName,
RangerITEnv.RANGER_HIVE_REPO_NAME);
+ rangerHelper.generateGravitinoRoleName(role.name()),
+ rangerAuthPlugin.rangerAdminName,
+ RangerITEnv.RANGER_HIVE_REPO_NAME);
LOG.info("rangerRole: " + rangerRole.toString());
} catch (RangerServiceException e) {
throw new RuntimeException(e);
@@ -471,7 +470,11 @@ public class RangerITEnv {
.allMatch(
policyItem -> {
// Verify role name in Ranger
policy item
- return
policyItem.getRoles().contains(role.name());
+ return policyItem
+ .getRoles()
+ .contains(
+
RangerHelper.GRAVITINO_ROLE_PREFIX
+ + role.name());
});
Assertions.assertTrue(match);
});
@@ -515,13 +518,11 @@ public class RangerITEnv {
String serviceName,
String policyName,
Map<String, RangerPolicy.RangerPolicyResource> policyResourceMap,
- List<RangerPolicy.RangerPolicyItem> policyItems,
- boolean labelManagedByGravitino) {
+ List<RangerPolicy.RangerPolicyItem> policyItems) {
Map<String, String> resourceFilter = new HashMap<>(); // use to match the
precise policy
Map<String, String> policyFilter = new HashMap<>();
policyFilter.put(SearchFilter.SERVICE_NAME, serviceName);
- policyFilter.put(SearchFilter.POLICY_LABELS_PARTIAL,
RangerHelper.MANAGED_BY_GRAVITINO);
final int[] index = {0};
policyResourceMap.forEach(
(k, v) -> {
@@ -575,9 +576,6 @@ public class RangerITEnv {
policy.setServiceType(type);
policy.setService(serviceName);
policy.setName(policyName);
- if (labelManagedByGravitino) {
-
policy.setPolicyLabels(Lists.newArrayList(RangerHelper.MANAGED_BY_GRAVITINO));
- }
policy.setResources(policyResourceMap);
policy.setPolicyItems(policyItems);
rangerClient.createPolicy(policy);
diff --git a/docs/security/authorization-pushdown.md
b/docs/security/authorization-pushdown.md
index dbcaa8d80..43c1096bd 100644
--- a/docs/security/authorization-pushdown.md
+++ b/docs/security/authorization-pushdown.md
@@ -28,6 +28,12 @@ In order to use the Ranger Hadoop SQL Plugin, you need to
configure the followin
Once you have used the correct configuration, you can perform authorization
operations by calling Gravitino [authorization RESTful
API](https://gravitino.apache.org/docs/latest/api/rest/grant-roles-to-a-user).
+Gravitino will initially create three roles in Apache Ranger:
+
+- GRAVITINO_METALAKE_OWNER_ROLE: Includes users and user groups designated as
metalake owners, corresponding to the owner's privileges in Ranger policies.
+- GRAVITINO_CATALOG_OWNER_ROLE: Includes users and user groups designated as
catalog owners, corresponding to the owner's privileges in Ranger policies.
+- GRAVITINO_OWNER_ROLE: Used to label Ranger policy items related to schema
and table owner privileges. It does not include any users or user groups.
+
#### Example of using the Ranger Hadoop SQL Plugin
Suppose you have an Apache Hive service in your datacenter and have created a
`hiveRepo` in Apache Ranger to manage its permissions.