You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by si...@apache.org on 2022/04/02 06:37:48 UTC

[ozone] branch HDDS-4944 updated: HDDS-6396. [Multi-Tenant] Merge and cleanup tenant group/role/policy tables, refactor protobuf messages and `isTenantAdmin` (#3177)

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

siyao pushed a commit to branch HDDS-4944
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-4944 by this push:
     new f99130b  HDDS-6396. [Multi-Tenant] Merge and cleanup tenant group/role/policy tables, refactor protobuf messages and `isTenantAdmin` (#3177)
f99130b is described below

commit f99130b6f9d371cc169768e101529c372ad9ef47
Author: Siyao Meng <50...@users.noreply.github.com>
AuthorDate: Fri Apr 1 23:37:27 2022 -0700

    HDDS-6396. [Multi-Tenant] Merge and cleanup tenant group/role/policy tables, refactor protobuf messages and `isTenantAdmin` (#3177)
---
 .../java/org/apache/hadoop/ozone/OzoneConsts.java  |  14 +-
 .../apache/hadoop/ozone/client/ObjectStore.java    |  12 +-
 .../ozone/client/protocol/ClientProtocol.java      |  12 +-
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  |  10 +-
 ...eleteTenantInfo.java => DeleteTenantState.java} |  16 +-
 .../hadoop/ozone/om/helpers/OmDBAccessIdInfo.java  |  31 ++--
 .../hadoop/ozone/om/helpers/OmDBTenantInfo.java    | 199 --------------------
 .../hadoop/ozone/om/helpers/OmDBTenantState.java   | 205 +++++++++++++++++++++
 ...incipalInfo.java => OmDBUserPrincipalInfo.java} |  51 ++---
 .../{TenantInfoList.java => TenantStateList.java}  |  33 ++--
 .../ozone/om/helpers/TenantUserInfoValue.java      |  42 ++---
 .../hadoop/ozone/om/helpers/TenantUserList.java    |  31 ++--
 .../MultiTenantAccessAuthorizerDummyPlugin.java    |   2 +-
 .../MultiTenantAccessAuthorizerRangerPlugin.java   |   1 +
 .../hadoop/ozone/om/multitenant/OzoneTenant.java   |  22 +--
 .../om/multitenant/OzoneTenantRolePrincipal.java   |  26 +--
 .../ozone/om/protocol/OzoneManagerProtocol.java    |  10 +-
 ...OzoneManagerProtocolClientSideTranslatorPB.java |  14 +-
 .../hadoop/ozone/shell/TestOzoneTenantShell.java   |   1 +
 .../src/main/proto/OmClientProtocol.proto          |  72 ++++----
 .../apache/hadoop/ozone/om/OMMetadataManager.java  |  14 +-
 .../ozone/om/codec/OmDBAccessIdInfoCodec.java      |   4 +-
 ...antInfoCodec.java => OmDBTenantStateCodec.java} |  22 ++-
 ...oCodec.java => OmDBUserPrincipalInfoCodec.java} |  26 +--
 .../hadoop/ozone/om/OMMultiTenantManager.java      |  53 +++++-
 .../hadoop/ozone/om/OMMultiTenantManagerImpl.java  | 159 +++++++++++-----
 .../hadoop/ozone/om/OmMetadataManagerImpl.java     |  82 ++-------
 .../org/apache/hadoop/ozone/om/OzoneManager.java   | 128 ++++---------
 .../hadoop/ozone/om/codec/OMDBDefinition.java      |  51 ++---
 ...achedTenantInfo.java => CachedTenantState.java} |   4 +-
 .../s3/tenant/OMTenantAssignAdminRequest.java      |  27 ++-
 .../tenant/OMTenantAssignUserAccessIdRequest.java  |  48 ++---
 .../request/s3/tenant/OMTenantCreateRequest.java   |  51 +++--
 .../request/s3/tenant/OMTenantDeleteRequest.java   |  24 +--
 .../request/s3/tenant/OMTenantRequestHelper.java   |  36 ++--
 .../s3/tenant/OMTenantRevokeAdminRequest.java      |  29 ++-
 .../tenant/OMTenantRevokeUserAccessIdRequest.java  |  14 +-
 .../s3/tenant/OMTenantAssignAdminResponse.java     |   1 -
 .../tenant/OMTenantAssignUserAccessIdResponse.java |  26 +--
 .../response/s3/tenant/OMTenantCreateResponse.java |  34 +---
 .../response/s3/tenant/OMTenantDeleteResponse.java |  16 +-
 .../s3/tenant/OMTenantRevokeAdminResponse.java     |   1 -
 .../tenant/OMTenantRevokeUserAccessIdResponse.java |  22 +--
 .../protocolPB/OzoneManagerRequestHandler.java     |   9 +-
 .../ozone/om/TestOMMultiTenantManagerImpl.java     |  42 +++--
 .../s3/security/TestS3GetSecretRequest.java        |   7 +-
 .../ozone/shell/tenant/GetUserInfoHandler.java     |   9 +-
 .../ozone/shell/tenant/TenantDeleteHandler.java    |   4 +-
 .../ozone/shell/tenant/TenantListHandler.java      |  33 ++--
 .../ozone/shell/tenant/TenantListUsersHandler.java |   4 +-
 50 files changed, 821 insertions(+), 963 deletions(-)

diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
index 40f29b0..dca3efa 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
@@ -341,11 +341,15 @@ public final class OzoneConsts {
 
   // For multi-tenancy
   public static final String TENANT_ID_USERNAME_DELIMITER = "$";
-  public static final String TENANT_ID_ROLE_DELIMITER = "-";
-  public static final String DEFAULT_TENANT_USER_POLICY_SUFFIX = "-users";
-  public static final String DEFAULT_TENANT_BUCKET_POLICY_SUFFIX = "-buckets";
-  public static final String DEFAULT_TENANT_POLICY_ID_SUFFIX = "-default";
-  public static final String DEFAULT_TENANT_USER_GROUP_SUFFIX = "-users";
+  public static final String DEFAULT_TENANT_BUCKET_NAMESPACE_POLICY_SUFFIX =
+      "-VolumeAccess";
+  public static final String DEFAULT_TENANT_BUCKET_POLICY_SUFFIX =
+      "-BucketAccess";
+  // Predefined tenant roles
+  // Tenant user role. All tenant users are assigned this role by default
+  public static final String DEFAULT_TENANT_ROLE_USER_SUFFIX = "-UserRole";
+  // Tenant admin role. All tenant admins are assigned this role
+  public static final String DEFAULT_TENANT_ROLE_ADMIN_SUFFIX = "-AdminRole";
 
   // For OM metrics saving to a file
   public static final String OM_METRICS_FILE = "omMetrics";
diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index 679e274..59e07bc 100644
--- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -33,11 +33,11 @@ import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
-import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.S3Auth;
@@ -235,9 +235,9 @@ public class ObjectStore {
    * Delete a tenant.
    * @param tenantId tenant name.
    * @throws IOException
-   * @return DeleteTenantInfo
+   * @return DeleteTenantState
    */
-  public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
+  public DeleteTenantState deleteTenant(String tenantId) throws IOException {
     return proxy.deleteTenant(tenantId);
   }
 
@@ -304,10 +304,10 @@ public class ObjectStore {
 
   /**
    * List tenants.
-   * @return TenantInfoList
+   * @return TenantStateList
    * @throws IOException
    */
-  public TenantInfoList listTenant() throws IOException {
+  public TenantStateList listTenant() throws IOException {
     return proxy.listTenant();
   }
 
diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
index 9ab58e4..713fc0c 100644
--- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
+++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
@@ -44,7 +44,7 @@ import org.apache.hadoop.ozone.client.io.OzoneInputStream;
 import org.apache.hadoop.ozone.client.io.OzoneOutputStream;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
-import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadCompleteInfo;
@@ -53,7 +53,7 @@ import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
@@ -615,9 +615,9 @@ public interface ClientProtocol {
    * Delete a tenant.
    * @param tenantId tenant name.
    * @throws IOException
-   * @return DeleteTenantInfo
+   * @return DeleteTenantState
    */
-  DeleteTenantInfo deleteTenant(String tenantId) throws IOException;
+  DeleteTenantState deleteTenant(String tenantId) throws IOException;
 
   /**
    * Assign a user to a tenant.
@@ -675,10 +675,10 @@ public interface ClientProtocol {
 
   /**
    * List tenants.
-   * @return TenantInfoList
+   * @return TenantStateList
    * @throws IOException
    */
-  TenantInfoList listTenant() throws IOException;
+  TenantStateList listTenant() throws IOException;
 
   /**
    * Get KMS client provider.
diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index da19872..1283ce6 100644
--- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -89,7 +89,7 @@ import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.BucketEncryptionKeyInfo;
-import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDeleteKeys;
@@ -114,7 +114,7 @@ import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
@@ -776,7 +776,7 @@ public class RpcClient implements ClientProtocol {
    * {@inheritDoc}
    */
   @Override
-  public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
+  public DeleteTenantState deleteTenant(String tenantId) throws IOException {
     Preconditions.checkArgument(Strings.isNotBlank(tenantId),
         "tenantId cannot be null or empty.");
     return ozoneManagerClient.deleteTenant(tenantId);
@@ -861,11 +861,11 @@ public class RpcClient implements ClientProtocol {
 
   /**
    * List tenants.
-   * @return TenantInfoList
+   * @return TenantStateList
    * @throws IOException
    */
   @Override
-  public TenantInfoList listTenant() throws IOException {
+  public TenantStateList listTenant() throws IOException {
     return ozoneManagerClient.listTenant();
   }
 
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantState.java
similarity index 82%
rename from hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
rename to hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantState.java
index b38c3cd..5fe53ee 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantState.java
@@ -23,7 +23,7 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteT
 /**
  * A class that encapsulates DeleteTenantResponse protobuf message.
  */
-public class DeleteTenantInfo {
+public class DeleteTenantState {
 
   /**
    * Volume name associated to the deleted tenant.
@@ -35,7 +35,7 @@ public class DeleteTenantInfo {
    */
   private final long volRefCount;
 
-  public DeleteTenantInfo(String volumeName, long volRefCount) {
+  public DeleteTenantState(String volumeName, long volRefCount) {
     this.volumeName = volumeName;
     this.volRefCount = volRefCount;
   }
@@ -48,8 +48,8 @@ public class DeleteTenantInfo {
     return volRefCount;
   }
 
-  public static DeleteTenantInfo fromProtobuf(DeleteTenantResponse resp) {
-    return new DeleteTenantInfo(resp.getVolumeName(), resp.getVolRefCount());
+  public static DeleteTenantState fromProtobuf(DeleteTenantResponse resp) {
+    return new DeleteTenantState(resp.getVolumeName(), resp.getVolRefCount());
   }
 
   public DeleteTenantResponse getProtobuf() {
@@ -59,8 +59,8 @@ public class DeleteTenantInfo {
         .build();
   }
 
-  public static DeleteTenantInfo.Builder newBuilder() {
-    return new DeleteTenantInfo.Builder();
+  public static DeleteTenantState.Builder newBuilder() {
+    return new DeleteTenantState.Builder();
   }
 
   /**
@@ -84,8 +84,8 @@ public class DeleteTenantInfo {
       return this;
     }
 
-    public DeleteTenantInfo build() {
-      return new DeleteTenantInfo(volumeName, volRefCount);
+    public DeleteTenantState build() {
+      return new DeleteTenantState(volumeName, volRefCount);
     }
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
index fcc6d8c..8535369 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
@@ -18,6 +18,8 @@
 package org.apache.hadoop.ozone.om.helpers;
 
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 
@@ -43,8 +45,8 @@ public final class OmDBAccessIdInfo {
    */
   private final boolean isDelegatedAdmin;
 
-  // This implies above String fields should NOT contain the split key.
-  public static final String SERIALIZATION_SPLIT_KEY = ";";
+  private static final Logger LOG =
+      LoggerFactory.getLogger(OmDBAccessIdInfo.class);
 
   public OmDBAccessIdInfo(String tenantId, String userPrincipal,
                           boolean isAdmin, boolean isDelegatedAdmin) {
@@ -61,25 +63,26 @@ public final class OmDBAccessIdInfo {
   /**
    * Convert OmDBAccessIdInfo to protobuf to be persisted to DB.
    */
-  public OzoneManagerProtocolProtos.OmDBAccessInfo getProtobuf() {
-    return OzoneManagerProtocolProtos.OmDBAccessInfo.newBuilder()
+  public OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo getProtobuf() {
+    return OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo.newBuilder()
+        .setTenantId(tenantId)
         .setUserPrincipal(userPrincipal)
         .setIsAdmin(isAdmin)
         .setIsDelegatedAdmin(isDelegatedAdmin)
-        .setTenantId(tenantId)
         .build();
   }
 
   /**
-   * Convert byte array to OmDBAccessIdInfo.
+   * Convert protobuf to OmDBAccessIdInfo.
    */
   public static OmDBAccessIdInfo getFromProtobuf(
-      OzoneManagerProtocolProtos.OmDBAccessInfo infoProto) throws IOException {
+      OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo infoProto)
+      throws IOException {
     return new Builder()
-        .setKerberosPrincipal(infoProto.getUserPrincipal())
+        .setTenantId(infoProto.getTenantId())
+        .setUserPrincipal(infoProto.getUserPrincipal())
         .setIsAdmin(infoProto.getIsAdmin())
         .setIsDelegatedAdmin(infoProto.getIsDelegatedAdmin())
-        .setTenantId(infoProto.getTenantId())
         .build();
   }
 
@@ -101,7 +104,7 @@ public final class OmDBAccessIdInfo {
   @SuppressWarnings("checkstyle:hiddenfield")
   public static final class Builder {
     private String tenantId;
-    private String kerberosPrincipal;
+    private String userPrincipal;
     private boolean isAdmin;
     private boolean isDelegatedAdmin;
 
@@ -110,8 +113,8 @@ public final class OmDBAccessIdInfo {
       return this;
     }
 
-    public Builder setKerberosPrincipal(String kerberosPrincipal) {
-      this.kerberosPrincipal = kerberosPrincipal;
+    public Builder setUserPrincipal(String userPrincipal) {
+      this.userPrincipal = userPrincipal;
       return this;
     }
 
@@ -126,8 +129,8 @@ public final class OmDBAccessIdInfo {
     }
 
     public OmDBAccessIdInfo build() {
-      return new OmDBAccessIdInfo(tenantId, kerberosPrincipal,
-          isAdmin, isDelegatedAdmin);
+      return new OmDBAccessIdInfo(
+          tenantId, userPrincipal, isAdmin, isDelegatedAdmin);
     }
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBTenantInfo.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBTenantInfo.java
deleted file mode 100644
index 3b82782..0000000
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBTenantInfo.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.hadoop.ozone.om.helpers;
-
-import com.google.common.base.Preconditions;
-import org.apache.hadoop.hdds.StringUtils;
-
-import java.util.Objects;
-
-/**
- * This class is used for storing Ozone tenant info.
- */
-public final class OmDBTenantInfo implements Comparable<OmDBTenantInfo> {
-  /**
-   * Name of the tenant.
-   */
-  private final String tenantId;
-  /**
-   * Name of the bucket namespace (volume name).
-   */
-  private final String bucketNamespaceName;
-  /**
-   * Name of the account namespace.
-   */
-  private final String accountNamespaceName;
-  /**
-   * Name of the user policy group.
-   */
-  private final String userPolicyGroupName;
-  /**
-   * Name of the bucket policy group.
-   */
-  private final String bucketPolicyGroupName;
-  // Implies above names should NOT contain the split key.
-  public static final String TENANT_INFO_SPLIT_KEY = ";";
-
-  public OmDBTenantInfo(String tenantId,
-      String bucketNamespaceName, String accountNamespaceName,
-      String userPolicyGroupName, String bucketPolicyGroupName) {
-    this.tenantId = tenantId;
-    this.bucketNamespaceName = bucketNamespaceName;
-    this.accountNamespaceName = accountNamespaceName;
-    this.userPolicyGroupName = userPolicyGroupName;
-    this.bucketPolicyGroupName = bucketPolicyGroupName;
-  }
-
-  private OmDBTenantInfo(String tenantInfoString) {
-    String[] tInfo = tenantInfoString.split(TENANT_INFO_SPLIT_KEY);
-    Preconditions.checkState(tInfo.length == 5,
-        "Incorrect tenantInfoString");
-
-    tenantId = tInfo[0];
-    bucketNamespaceName = tInfo[1];
-    accountNamespaceName = tInfo[2];
-    userPolicyGroupName = tInfo[3];
-    bucketPolicyGroupName = tInfo[4];
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    OmDBTenantInfo that = (OmDBTenantInfo) o;
-    return Objects.equals(tenantId, that.tenantId)
-        && Objects.equals(bucketNamespaceName, that.bucketNamespaceName)
-        && Objects.equals(accountNamespaceName, that.accountNamespaceName)
-        && Objects.equals(userPolicyGroupName, that.userPolicyGroupName)
-        && Objects.equals(bucketPolicyGroupName, that.bucketPolicyGroupName);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(tenantId, bucketNamespaceName, accountNamespaceName,
-        userPolicyGroupName, bucketPolicyGroupName);
-  }
-
-  @Override
-  public int compareTo(OmDBTenantInfo o) {
-    return this.getTenantId().compareTo(o.getTenantId());
-  }
-
-  public String getTenantId() {
-    return tenantId;
-  }
-
-  private String generateTenantInfo() {
-    StringBuilder sb = new StringBuilder();
-    sb.append(tenantId).append(TENANT_INFO_SPLIT_KEY);
-    sb.append(bucketNamespaceName).append(TENANT_INFO_SPLIT_KEY);
-    sb.append(accountNamespaceName).append(TENANT_INFO_SPLIT_KEY);
-    sb.append(userPolicyGroupName).append(TENANT_INFO_SPLIT_KEY);
-    sb.append(bucketPolicyGroupName);
-    return sb.toString();
-  }
-
-  /**
-   * Convert OmDBTenantInfo to byteArray to be persisted to DB.
-   * @return byte[]
-   */
-  public byte[] convertToByteArray() {
-    return StringUtils.string2Bytes(generateTenantInfo());
-  }
-
-  /**
-   * Convert byte array to OmDBTenantInfo.
-   * @param bytes
-   * @return OmDBTenantInfo
-   */
-  public static OmDBTenantInfo getFromByteArray(byte[] bytes) {
-    String tInfo = StringUtils.bytes2String(bytes);
-    return new OmDBTenantInfo(tInfo);
-  }
-
-  /**
-   * Returns the bucket namespace name. a.k.a. volume name.
-   *
-   * Note: This returns an empty string ("") if the tenant is somehow not
-   * associated with a volume. Should never return null.
-   */
-  public String getBucketNamespaceName() {
-    return bucketNamespaceName;
-  }
-
-  public String getAccountNamespaceName() {
-    return accountNamespaceName;
-  }
-
-  public String getUserPolicyGroupName() {
-    return userPolicyGroupName;
-  }
-
-  public String getBucketPolicyGroupName() {
-    return bucketPolicyGroupName;
-  }
-
-  /**
-   * Builder for OmDBTenantInfo.
-   */
-  @SuppressWarnings("checkstyle:hiddenfield")
-  public static final class Builder {
-    private String tenantId;
-    private String bucketNamespaceName;
-    private String accountNamespaceName;
-    private String userPolicyGroupName;
-    private String bucketPolicyGroupName;
-
-    private Builder() {
-    }
-
-    public Builder setTenantId(String tenantId) {
-      this.tenantId = tenantId;
-      return this;
-    }
-
-    public Builder setBucketNamespaceName(String bucketNamespaceName) {
-      this.bucketNamespaceName = bucketNamespaceName;
-      return this;
-    }
-
-    public Builder setAccountNamespaceName(String accountNamespaceName) {
-      this.accountNamespaceName = accountNamespaceName;
-      return this;
-    }
-
-    public Builder setUserPolicyGroupName(String userPolicyGroupName) {
-      this.userPolicyGroupName = userPolicyGroupName;
-      return this;
-    }
-
-    public Builder setBucketPolicyGroupName(String bucketPolicyGroupName) {
-      this.bucketPolicyGroupName = bucketPolicyGroupName;
-      return this;
-    }
-
-    public OmDBTenantInfo build() {
-      return new OmDBTenantInfo(tenantId, bucketNamespaceName,
-          accountNamespaceName, userPolicyGroupName, bucketPolicyGroupName);
-    }
-  }
-}
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBTenantState.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBTenantState.java
new file mode 100644
index 0000000..57f7209
--- /dev/null
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBTenantState.java
@@ -0,0 +1,205 @@
+/*
+ * 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.hadoop.ozone.om.helpers;
+
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
+
+import java.util.Objects;
+
+/**
+ * This class is used for storing Ozone tenant state info.
+ */
+public final class OmDBTenantState implements Comparable<OmDBTenantState> {
+  /**
+   * Name of the tenant.
+   */
+  private final String tenantId;
+  /**
+   * Name of the bucket namespace (volume).
+   */
+  private final String bucketNamespaceName;
+  /**
+   * Name of the user role of this tenant.
+   */
+  private final String userRoleName;
+  /**
+   * Name of the admin role of this tenant.
+   */
+  private final String adminRoleName;
+  /**
+   * Name of the volume access policy of this tenant.
+   */
+  private final String bucketNamespacePolicyName;
+  /**
+   * Name of the bucket access policy of this tenant.
+   */
+  private final String bucketPolicyName;
+
+  public OmDBTenantState(String tenantId, String bucketNamespaceName,
+      String userRoleName, String adminRoleName,
+      String bucketNamespacePolicyName, String bucketPolicyName) {
+    this.tenantId = tenantId;
+    this.bucketNamespaceName = bucketNamespaceName;
+    this.userRoleName = userRoleName;
+    this.adminRoleName = adminRoleName;
+    this.bucketNamespacePolicyName = bucketNamespacePolicyName;
+    this.bucketPolicyName = bucketPolicyName;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    OmDBTenantState that = (OmDBTenantState) o;
+    return Objects.equals(tenantId, that.tenantId)
+        && Objects.equals(bucketNamespaceName, that.bucketNamespaceName)
+        && Objects.equals(userRoleName, that.userRoleName)
+        && Objects.equals(adminRoleName, that.adminRoleName)
+        && Objects.equals(
+            bucketNamespacePolicyName, that.bucketNamespacePolicyName)
+        && Objects.equals(bucketPolicyName, that.bucketPolicyName);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(tenantId, bucketNamespaceName,
+        userRoleName, adminRoleName,
+        bucketNamespacePolicyName, bucketPolicyName);
+  }
+
+  @Override
+  public int compareTo(OmDBTenantState o) {
+    return this.getTenantId().compareTo(o.getTenantId());
+  }
+
+  public String getTenantId() {
+    return tenantId;
+  }
+
+  /**
+   * Returns the bucket namespace name. a.k.a. volume name.
+   *
+   * Note: This returns an empty string ("") if the tenant is somehow not
+   * associated with a volume. Should never return null.
+   */
+  public String getBucketNamespaceName() {
+    return bucketNamespaceName;
+  }
+
+  public String getUserRoleName() {
+    return userRoleName;
+  }
+
+  public String getAdminRoleName() {
+    return adminRoleName;
+  }
+
+  public String getBucketNamespacePolicyName() {
+    return bucketNamespacePolicyName;
+  }
+
+  public String getBucketPolicyName() {
+    return bucketPolicyName;
+  }
+
+  /**
+   * Convert OmDBTenantState to protobuf to be persisted to DB.
+   */
+  public OzoneManagerProtocolProtos.TenantState getProtobuf() {
+    return OzoneManagerProtocolProtos.TenantState.newBuilder()
+        .setTenantId(tenantId)
+        .setBucketNamespaceName(bucketNamespaceName)
+        .setUserRoleName(userRoleName)
+        .setAdminRoleName(adminRoleName)
+        .setBucketNamespacePolicyName(bucketNamespacePolicyName)
+        .setBucketPolicyName(bucketPolicyName)
+        .build();
+  }
+
+  /**
+   * Convert protobuf to OmDBTenantState.
+   */
+  public static OmDBTenantState getFromProtobuf(
+      OzoneManagerProtocolProtos.TenantState proto) {
+    return new Builder()
+        .setTenantId(proto.getTenantId())
+        .setBucketNamespaceName(proto.getBucketNamespaceName())
+        .setUserRoleName(proto.getUserRoleName())
+        .setAdminRoleName(proto.getAdminRoleName())
+        .setBucketNamespacePolicyName(proto.getBucketNamespacePolicyName())
+        .setBucketPolicyName(proto.getBucketPolicyName())
+        .build();
+  }
+
+  /**
+   * Builder for OmDBTenantState.
+   */
+  @SuppressWarnings("checkstyle:hiddenfield")
+  public static final class Builder {
+    private String tenantId;
+    private String bucketNamespaceName;
+    private String userRoleName;
+    private String adminRoleName;
+    private String bucketNamespacePolicyName;
+    private String bucketPolicyName;
+
+    private Builder() {
+    }
+
+    public Builder setTenantId(String tenantId) {
+      this.tenantId = tenantId;
+      return this;
+    }
+
+    public Builder setBucketNamespaceName(String bucketNamespaceName) {
+      this.bucketNamespaceName = bucketNamespaceName;
+      return this;
+    }
+
+    public Builder setUserRoleName(String userRoleName) {
+      this.userRoleName = userRoleName;
+      return this;
+    }
+
+    public Builder setAdminRoleName(String adminRoleName) {
+      this.adminRoleName = adminRoleName;
+      return this;
+    }
+
+    public Builder setBucketNamespacePolicyName(
+        String bucketNamespacePolicyName) {
+      this.bucketNamespacePolicyName = bucketNamespacePolicyName;
+      return this;
+    }
+
+    public Builder setBucketPolicyName(String bucketPolicyName) {
+      this.bucketPolicyName = bucketPolicyName;
+      return this;
+    }
+
+    public OmDBTenantState build() {
+      return new OmDBTenantState(tenantId, bucketNamespaceName,
+          userRoleName, adminRoleName,
+          bucketNamespacePolicyName, bucketPolicyName);
+    }
+  }
+}
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBUserPrincipalInfo.java
similarity index 54%
rename from hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java
rename to hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBUserPrincipalInfo.java
index c5274fd..75a609b 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBUserPrincipalInfo.java
@@ -17,40 +17,28 @@
  */
 package org.apache.hadoop.ozone.om.helpers;
 
-import org.apache.hadoop.hdds.StringUtils;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * This class is used for storing info related to the Kerberos principal.
  *
- * For now this is merely used to store a list of accessIds associates with the
- * principal, but can be extended to store more fields later.
+ * For now this only stores a list of accessIds associates with the user
+ * principal.
  */
-public final class OmDBKerberosPrincipalInfo {
+public final class OmDBUserPrincipalInfo {
 
   /**
    * A set of accessIds.
    */
   private final Set<String> accessIds;
 
-  // This implies above String fields should NOT contain the split key.
-  // TODO: Reject user input accessId if it contains the split key.
-  public static final String SERIALIZATION_SPLIT_KEY = ";";
-
-  public OmDBKerberosPrincipalInfo(Set<String> accessIds) {
+  public OmDBUserPrincipalInfo(Set<String> accessIds) {
     this.accessIds = new HashSet<>(accessIds);
   }
 
-  private OmDBKerberosPrincipalInfo(String serialized) {
-    accessIds = Arrays.stream(serialized.split(SERIALIZATION_SPLIT_KEY))
-        // Remove any empty accessId strings when deserializing
-        .filter(e -> !e.isEmpty()).collect(Collectors.toSet());
-  }
-
   public Set<String> getAccessIds() {
     return accessIds;
   }
@@ -67,28 +55,27 @@ public final class OmDBKerberosPrincipalInfo {
     return accessIds.contains(accessId);
   }
 
-  private String serialize() {
-    return String.join(SERIALIZATION_SPLIT_KEY, accessIds);
-  }
-
   /**
-   * Convert OmDBKerberosPrincipalInfo to byteArray to be persisted to DB.
-   * @return byte[]
+   * Convert OmDBUserPrincipalInfo to protobuf to be persisted to DB.
    */
-  public byte[] convertToByteArray() {
-    return StringUtils.string2Bytes(serialize());
+  public OzoneManagerProtocolProtos.TenantUserPrincipalInfo getProtobuf() {
+    return OzoneManagerProtocolProtos.TenantUserPrincipalInfo.newBuilder()
+        .addAllAccessIds(accessIds)
+        .build();
   }
 
   /**
-   * Convert byte array to OmDBKerberosPrincipalInfo.
+   * Convert protobuf to OmDBUserPrincipalInfo.
    */
-  public static OmDBKerberosPrincipalInfo getFromByteArray(byte[] bytes) {
-    String tInfo = StringUtils.bytes2String(bytes);
-    return new OmDBKerberosPrincipalInfo(tInfo);
+  public static OmDBUserPrincipalInfo getFromProtobuf(
+      OzoneManagerProtocolProtos.TenantUserPrincipalInfo proto) {
+    return new Builder()
+        .setAccessIds(new HashSet<>(proto.getAccessIdsList()))
+        .build();
   }
 
   /**
-   * Builder for OmDBKerberosPrincipalInfo.
+   * Builder for OmDBUserPrincipalInfo.
    */
   @SuppressWarnings("checkstyle:hiddenfield")
   public static final class Builder {
@@ -99,8 +86,8 @@ public final class OmDBKerberosPrincipalInfo {
       return this;
     }
 
-    public OmDBKerberosPrincipalInfo build() {
-      return new OmDBKerberosPrincipalInfo(accessIds);
+    public OmDBUserPrincipalInfo build() {
+      return new OmDBUserPrincipalInfo(accessIds);
     }
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantInfoList.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantStateList.java
similarity index 64%
rename from hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantInfoList.java
rename to hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantStateList.java
index c37f989..70df804 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantInfoList.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantStateList.java
@@ -18,38 +18,39 @@
 package org.apache.hadoop.ozone.om.helpers;
 
 import org.apache.commons.lang3.NotImplementedException;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantState;
 
 import java.util.List;
 import java.util.Objects;
 
 /**
- * Utility class to handle protobuf message TenantInfo conversion.
+ * Utility class to handle protobuf message TenantState conversion.
  */
-public class TenantInfoList {
+public class TenantStateList {
 
-  // A list of TenantAccessIdInfo from protobuf.
-  private final List<TenantInfo> tenantInfoList;
+  // A list of TenantState from protobuf.
+  private final List<TenantState> tenantStateList;
 
-  public List<TenantInfo> getTenantInfoList() {
-    return tenantInfoList;
+  public List<TenantState> getTenantStateList() {
+    return tenantStateList;
   }
 
-  public TenantInfoList(List<TenantInfo> tenantInfoList) {
-    this.tenantInfoList = tenantInfoList;
+  public TenantStateList(List<TenantState> tenantStateList) {
+    this.tenantStateList = tenantStateList;
   }
 
-  public static TenantInfoList fromProtobuf(List<TenantInfo> tenantInfoList) {
-    return new TenantInfoList(tenantInfoList);
+  public static TenantStateList fromProtobuf(
+      List<TenantState> tenantStateList) {
+    return new TenantStateList(tenantStateList);
   }
 
-  public TenantInfo getProtobuf() {
+  public TenantState getProtobuf() {
     throw new NotImplementedException("getProtobuf() not implemented");
   }
 
   @Override
   public String toString() {
-    return "tenantInfoList=" + tenantInfoList;
+    return "tenantStateList=" + tenantStateList;
   }
 
   @Override
@@ -60,12 +61,12 @@ public class TenantInfoList {
     if (o == null || getClass() != o.getClass()) {
       return false;
     }
-    TenantInfoList that = (TenantInfoList) o;
-    return tenantInfoList.equals(that.tenantInfoList);
+    TenantStateList that = (TenantStateList) o;
+    return tenantStateList.equals(that.tenantStateList);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(tenantInfoList);
+    return Objects.hash(tenantStateList);
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserInfoValue.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserInfoValue.java
index a0ac396..5ca5dcb 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserInfoValue.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserInfoValue.java
@@ -17,54 +17,43 @@
  */
 package org.apache.hadoop.ozone.om.helpers;
 
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantAccessIdInfo;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantUserInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoResponse;
 
 import java.util.List;
 import java.util.Objects;
 
 /**
- * Utility class to handle protobuf message TenantUserInfo conversion.
+ * Utility class to handle TenantGetUserInfoResponse protobuf message.
  */
 public class TenantUserInfoValue {
 
-  // Usually this is the Kerberos principal of a user.
-  private final String userPrincipal;
+  // A list of ExtendedUserAccessIdInfo from protobuf.
+  private final List<ExtendedUserAccessIdInfo> accessIdInfoList;
 
-  // A list of TenantAccessIdInfo from protobuf.
-  private final List<TenantAccessIdInfo> accessIdInfoList;
-
-  public String getUserPrincipal() {
-    return userPrincipal;
-  }
-
-  public List<TenantAccessIdInfo> getAccessIdInfoList() {
+  public List<ExtendedUserAccessIdInfo> getAccessIdInfoList() {
     return accessIdInfoList;
   }
 
-  public TenantUserInfoValue(String kerberosID,
-      List<TenantAccessIdInfo> accessIdInfoList) {
-    this.userPrincipal = kerberosID;
+  public TenantUserInfoValue(List<ExtendedUserAccessIdInfo> accessIdInfoList) {
     this.accessIdInfoList = accessIdInfoList;
   }
 
   public static TenantUserInfoValue fromProtobuf(
-      TenantUserInfo tenantUserInfo) {
-    return new TenantUserInfoValue(tenantUserInfo.getUserPrincipal(),
-        tenantUserInfo.getAccessIdInfoList());
+      TenantGetUserInfoResponse tenantUserInfo) {
+    return new TenantUserInfoValue(tenantUserInfo.getAccessIdInfoList());
   }
 
-  public TenantUserInfo getProtobuf() {
-    final TenantUserInfo.Builder builder = TenantUserInfo.newBuilder();
-    builder.setUserPrincipal(this.userPrincipal);
+  public TenantGetUserInfoResponse getProtobuf() {
+    final TenantGetUserInfoResponse.Builder builder =
+        TenantGetUserInfoResponse.newBuilder();
     accessIdInfoList.forEach(builder::addAccessIdInfo);
     return builder.build();
   }
 
   @Override
   public String toString() {
-    return "userPrincipal=" + userPrincipal +
-        "\naccessIdInfoList=" + accessIdInfoList;
+    return "accessIdInfoList=" + accessIdInfoList;
   }
 
   @Override
@@ -76,12 +65,11 @@ public class TenantUserInfoValue {
       return false;
     }
     TenantUserInfoValue that = (TenantUserInfoValue) o;
-    return userPrincipal.equals(that.userPrincipal) &&
-        accessIdInfoList.equals(that.accessIdInfoList);
+    return accessIdInfoList.equals(that.accessIdInfoList);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(userPrincipal, accessIdInfoList);
+    return Objects.hash(accessIdInfoList);
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserList.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserList.java
index 58253ec..05d1e5b 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserList.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/TenantUserList.java
@@ -22,41 +22,33 @@ import java.util.List;
 import java.util.Objects;
 
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantListUserResponse;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantUserAccessId;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserAccessIdInfo;
 
 /**
  * Class to encapsulate the list of users and corresponding accessIds
  * associated with a tenant.
  */
 public class TenantUserList {
+  /**
+   * List of user principal -> access ID pairs.
+   */
+  private final List<UserAccessIdInfo> userAccessIds;
 
-  private final String tenantId;
-
-  private final List<TenantUserAccessId> userAccessIds;
-  
-  public TenantUserList(String tenantId,
-                        List<TenantUserAccessId> userAccessIds) {
-    this.tenantId = tenantId;
+  public TenantUserList(List<UserAccessIdInfo> userAccessIds) {
     this.userAccessIds = userAccessIds;
   }
 
-  public String getTenantId() {
-    return tenantId;
-  }
-
-  public List<TenantUserAccessId> getUserAccessIds() {
+  public List<UserAccessIdInfo> getUserAccessIds() {
     return userAccessIds;
   }
 
   public static TenantUserList fromProtobuf(TenantListUserResponse response) {
-    return new TenantUserList(response.getTenantId(),
-        response.getUserAccessIdInfoList());
+    return new TenantUserList(response.getUserAccessIdInfoList());
   }
 
   @Override
   public String toString() {
-    return "tenantId=" + tenantId +
-        "\nuserAccessIds=" + userAccessIds;
+    return "userAccessIds=" + userAccessIds;
   }
 
   @Override
@@ -68,12 +60,11 @@ public class TenantUserList {
       return false;
     }
     TenantUserList that = (TenantUserList) o;
-    return tenantId.equals(that.tenantId) &&
-        userAccessIds.equals(that.userAccessIds);
+    return userAccessIds.equals(that.userAccessIds);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(tenantId, userAccessIds);
+    return Objects.hash(userAccessIds);
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerDummyPlugin.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerDummyPlugin.java
index 582839c..f73f050 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerDummyPlugin.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerDummyPlugin.java
@@ -47,7 +47,7 @@ public class MultiTenantAccessAuthorizerDummyPlugin implements
   @Override
   public String assignUser(BasicUserPrincipal principal, String existingRole,
       boolean isAdmin) throws IOException {
-    return "assignUser-roleId-returned";
+    return "assignUser-roleName-returned";
   }
 
   @Override
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
index a7e3487..f4d5952 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
@@ -347,6 +347,7 @@ public class MultiTenantAccessAuthorizerRangerPlugin implements
     String policyID;
     try {
       JsonObject jObject = new JsonParser().parse(policyInfo).getAsJsonObject();
+      // TODO: Use policy name instead of id
       policyID = jObject.get("id").getAsString();
       LOG.debug("policyID is: {}", policyID);
     } catch (JsonParseException e) {
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenant.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenant.java
index 375e260..83ec319 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenant.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenant.java
@@ -24,26 +24,26 @@ import org.apache.hadoop.ozone.om.multitenant.impl.AccountNameSpaceImpl;
 import org.apache.hadoop.ozone.om.multitenant.impl.SingleVolumeTenantNamespace;
 
 /**
- * In-memory tenant info. For DB state, see OmDBTenantInfo.
+ * In-memory tenant info. For DB state, see OmDBTenantState.
  */
 public class OzoneTenant implements Tenant {
-  private final String tenantID;
-  private List<String> tenantRoleIds;
+  private final String tenantId;
+  private List<String> tenantRoleNames;
   private List<AccessPolicy> accessPolicies;
   private final AccountNameSpace accountNameSpace;
   private final BucketNameSpace bucketNameSpace;
 
   public OzoneTenant(String id) {
-    tenantID = id;
+    tenantId = id;
     accessPolicies = new ArrayList<>();
-    tenantRoleIds = new ArrayList<>();
+    tenantRoleNames = new ArrayList<>();
     accountNameSpace = new AccountNameSpaceImpl(id);
     bucketNameSpace = new SingleVolumeTenantNamespace(id);
   }
 
   @Override
   public String getTenantId() {
-    return tenantID;
+    return tenantId;
   }
 
   @Override
@@ -72,17 +72,17 @@ public class OzoneTenant implements Tenant {
   }
 
   @Override
-  public void addTenantAccessRole(String roleId) {
-    tenantRoleIds.add(roleId);
+  public void addTenantAccessRole(String roleName) {
+    tenantRoleNames.add(roleName);
   }
 
   @Override
-  public void removeTenantAccessRole(String roleId) {
-    tenantRoleIds.remove(roleId);
+  public void removeTenantAccessRole(String roleName) {
+    tenantRoleNames.remove(roleName);
   }
 
   @Override
   public List<String> getTenantRoles() {
-    return tenantRoleIds;
+    return tenantRoleNames;
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenantRolePrincipal.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenantRolePrincipal.java
index a3bc905..81f6f6f 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenantRolePrincipal.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/OzoneTenantRolePrincipal.java
@@ -24,24 +24,26 @@ import java.security.Principal;
  * Used to identify a tenant's role in Ranger.
  */
 public final class OzoneTenantRolePrincipal implements Principal {
-  private final String tenantID;
-  private final String roleName;
+  private final String tenantId;
+  private final String roleNameSuffix;
 
-  public static OzoneTenantRolePrincipal getUserRole(String tenantID) {
-    return new OzoneTenantRolePrincipal(tenantID, "UserRole");
+  public static OzoneTenantRolePrincipal getUserRole(String tenantId) {
+    return new OzoneTenantRolePrincipal(
+        tenantId, OzoneConsts.DEFAULT_TENANT_ROLE_USER_SUFFIX);
   }
 
-  public static OzoneTenantRolePrincipal getAdminRole(String tenantID) {
-    return new OzoneTenantRolePrincipal(tenantID, "AdminRole");
+  public static OzoneTenantRolePrincipal getAdminRole(String tenantId) {
+    return new OzoneTenantRolePrincipal(
+        tenantId, OzoneConsts.DEFAULT_TENANT_ROLE_ADMIN_SUFFIX);
   }
 
-  private OzoneTenantRolePrincipal(String tenantID, String roleName) {
-    this.tenantID = tenantID;
-    this.roleName = roleName;
+  private OzoneTenantRolePrincipal(String tenantId, String roleNameSuffix) {
+    this.tenantId = tenantId;
+    this.roleNameSuffix = roleNameSuffix;
   }
 
-  public String getTenantID() {
-    return tenantID;
+  public String getTenantId() {
+    return tenantId;
   }
 
   @Override
@@ -51,6 +53,6 @@ public final class OzoneTenantRolePrincipal implements Principal {
 
   @Override
   public String getName() {
-    return tenantID + OzoneConsts.TENANT_ID_ROLE_DELIMITER + roleName;
+    return tenantId + roleNameSuffix;
   }
 }
\ No newline at end of file
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index 80c3ac9..5d548d3 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -27,7 +27,7 @@ import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.DBUpdates;
-import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDeleteKeys;
@@ -50,7 +50,7 @@ import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
@@ -596,7 +596,7 @@ public interface OzoneManagerProtocol
    * @return DeleteTenantResponse
    * @throws IOException
    */
-  default DeleteTenantInfo deleteTenant(String tenantId)
+  default DeleteTenantState deleteTenant(String tenantId)
       throws IOException {
     throw new UnsupportedOperationException("OzoneManager does not require " +
         "this to be implemented, as write requests use a new approach");
@@ -671,10 +671,10 @@ public interface OzoneManagerProtocol
 
   /**
    * List tenants.
-   * @return TenantInfoList
+   * @return TenantStateList
    * @throws IOException
    */
-  TenantInfoList listTenant() throws IOException;
+  TenantStateList listTenant() throws IOException;
 
   /**
    * OzoneFS api to get file status for an entry.
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index ca23c82..7a48f28 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -34,7 +34,7 @@ import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.DBUpdates;
-import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantState;
 import org.apache.hadoop.ozone.om.helpers.KeyValueUtil;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
@@ -59,7 +59,7 @@ import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.S3Auth;
@@ -988,7 +988,7 @@ public final class OzoneManagerProtocolClientSideTranslatorPB
   }
 
   @Override
-  public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
+  public DeleteTenantState deleteTenant(String tenantId) throws IOException {
     final DeleteTenantRequest request = DeleteTenantRequest.newBuilder()
         .setTenantId(tenantId)
         .build();
@@ -998,7 +998,7 @@ public final class OzoneManagerProtocolClientSideTranslatorPB
     final OMResponse omResponse = submitRequest(omRequest);
     final DeleteTenantResponse resp =
         handleError(omResponse).getDeleteTenantResponse();
-    return DeleteTenantInfo.fromProtobuf(resp);
+    return DeleteTenantState.fromProtobuf(resp);
   }
 
   /**
@@ -1105,7 +1105,7 @@ public final class OzoneManagerProtocolClientSideTranslatorPB
     final TenantGetUserInfoResponse resp = handleError(omResponse)
         .getTenantGetUserInfoResponse();
 
-    return TenantUserInfoValue.fromProtobuf(resp.getTenantUserInfo());
+    return TenantUserInfoValue.fromProtobuf(resp);
   }
 
   @Override
@@ -1144,7 +1144,7 @@ public final class OzoneManagerProtocolClientSideTranslatorPB
    * {@inheritDoc}
    */
   @Override
-  public TenantInfoList listTenant() throws IOException {
+  public TenantStateList listTenant() throws IOException {
 
     final ListTenantRequest request = ListTenantRequest.newBuilder()
         .build();
@@ -1155,7 +1155,7 @@ public final class OzoneManagerProtocolClientSideTranslatorPB
     final ListTenantResponse resp = handleError(omResponse)
         .getListTenantResponse();
 
-    return TenantInfoList.fromProtobuf(resp.getTenantInfoList());
+    return TenantStateList.fromProtobuf(resp.getTenantStateList());
   }
 
   /**
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java
index f3aa9f4..56798bb 100644
--- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java
@@ -805,6 +805,7 @@ public class TestOzoneTenantShell {
     checkOutput(out, "", true);
     checkOutput(err, "Assigned admin", false);
 
+    // Set secret should succeed now
     ugiBob.doAs((PrivilegedExceptionAction<Void>) () -> {
       executeHA(tenantShell, new String[] {
           "user", "setsecret", tenantName + "$alice",
diff --git a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index fc57bf4..7f9e792 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -1406,32 +1406,53 @@ message SetS3SecretResponse {
     optional string secretKey = 2;
 }
 
-message TenantInfo {
+message TenantState {
     optional string tenantId = 1;
-    optional string bucketNamespaceName = 2;
-    optional string accountNamespaceName = 3;
-    optional string userPolicyGroupName = 4;
-    optional string bucketPolicyGroupName = 5;
+    optional string bucketNamespaceName = 2;        // Volume name
+    optional string userRoleName = 3;
+    optional string adminRoleName = 4;
+    optional string bucketNamespacePolicyName = 5;  // VolumeAccessPolicy name
+    optional string bucketPolicyName = 6;           // BucketAccessPolicy name
 }
 
-message TenantUserAccessId {
+message TenantUserPrincipalInfo {
+    repeated string accessIds = 1;
+}
+
+// Stores a basic user-accessId pair, used in TenantListUserResponse
+message UserAccessIdInfo {
     optional string userPrincipal = 1;
     optional string accessId = 2;
-    optional bool isAdmin = 3;
-    optional bool isDelegatedAdmin = 4;
 }
 
+// Multi-purpose message for storing or transferring extra access ID information
+//
+// This is an extension to the S3Secret protobuf message, carrying supplementary
+//   information to the existing accessId (kerberosID) field.
+// For now, all fields are related to multi-tenancy. New fields can be added
+//   when necessary in the future. e.g. when implementing new features.
+//
+// Usage 1: Stored as value (OmDBAccessIdInfo) in TenantAccessIdTable.
+//   In this case, accessId field is not set to avoid duplication,
+//   because the key of TenantAccessIdTable is already accessId.
+//
+// Usage 2: Used when transferring the result of `ozone tenant user info`
+//   See TenantUserInfoValue.
+//
+message ExtendedUserAccessIdInfo {
+    optional string userPrincipal = 1;
+    optional string accessId = 2;  // OmDBAccessIdInfo doesn't use this field
+    optional string tenantId = 3;
+    optional bool isAdmin = 4;
+    optional bool isDelegatedAdmin = 5;
+}
 
 message ListTenantRequest {
 
 }
 
 message ListTenantResponse {
-    repeated TenantInfo tenantInfo = 1;
-}
-
-message TenantGetUserInfoRequest {
-    optional string userPrincipal = 1;
+    repeated TenantState tenantState = 1;
 }
 
 message TenantListUserRequest {
@@ -1439,28 +1460,18 @@ message TenantListUserRequest {
     optional string prefix = 2;
 }
 
-message TenantGetUserInfoResponse {
-    optional TenantUserInfo tenantUserInfo = 1;
-}
-
 message TenantListUserResponse {
-    optional string tenantId = 1;
-    repeated TenantUserAccessId userAccessIdInfo = 2;
+    repeated UserAccessIdInfo userAccessIdInfo = 1;
 }
 
-message TenantUserInfo {
+message TenantGetUserInfoRequest {
     optional string userPrincipal = 1;
-    repeated TenantAccessIdInfo accessIdInfo = 2;
 }
 
-message TenantAccessIdInfo {
-    optional string accessId = 1;
-    optional string tenantId = 2;
-    optional bool isAdmin = 3;
-    optional bool isDelegatedAdmin = 4;
+message TenantGetUserInfoResponse {
+    repeated ExtendedUserAccessIdInfo accessIdInfo = 1;
 }
 
-
 message LayoutVersion {
   required uint64 version = 1;
 }
@@ -1530,13 +1541,6 @@ message TenantRevokeAdminResponse {
 
 }
 
-message OmDBAccessInfo {
-  optional string tenantId = 1;
-  optional string userPrincipal = 2;
-  optional bool isAdmin = 3;
-  optional bool isDelegatedAdmin = 4;
-}
-
 message GetS3VolumeContextResponse {
   optional VolumeInfo volumeInfo = 1;
   // Piggybacked username (principal) response to be used for KMS client operations
diff --git a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
index 2b5283f..517d973 100644
--- a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
+++ b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
@@ -30,12 +30,12 @@ import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
 import org.apache.hadoop.ozone.common.BlockGroup;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
 import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
@@ -361,15 +361,9 @@ public interface OMMetadataManager extends DBStoreHAManager {
 
   Table<String, OmDBAccessIdInfo> getTenantAccessIdTable();
 
-  Table<String, OmDBKerberosPrincipalInfo> getPrincipalToAccessIdsTable();
+  Table<String, OmDBUserPrincipalInfo> getPrincipalToAccessIdsTable();
 
-  Table<String, OmDBTenantInfo> getTenantStateTable();
-
-  Table<String, String> getTenantGroupTable();
-
-  Table<String, String> getTenantRoleTable();
-
-  Table<String, String> getTenantPolicyTable();
+  Table<String, OmDBTenantState> getTenantStateTable();
 
   /**
    * Gets the OM Meta table.
diff --git a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBAccessIdInfoCodec.java b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBAccessIdInfoCodec.java
index b3926fc..7717036 100644
--- a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBAccessIdInfoCodec.java
+++ b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBAccessIdInfoCodec.java
@@ -46,12 +46,12 @@ public class OmDBAccessIdInfoCodec implements Codec<OmDBAccessIdInfo> {
     checkNotNull(rawData, "Null byte array can't be converted to " +
         "real object.");
     return OmDBAccessIdInfo.getFromProtobuf(
-        OzoneManagerProtocolProtos.OmDBAccessInfo.parseFrom(rawData));
+        OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo.parseFrom(rawData));
   }
 
   @Override
   public OmDBAccessIdInfo copyObject(OmDBAccessIdInfo object) {
-    // TODO: Not really a "copy". See OMTransactionInfoCodec
+    // Note: Not really a "copy". See OMTransactionInfoCodec
     return object;
   }
 }
diff --git a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBTenantInfoCodec.java b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBTenantStateCodec.java
similarity index 65%
rename from hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBTenantInfoCodec.java
rename to hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBTenantStateCodec.java
index d023362..7bb57da 100644
--- a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBTenantInfoCodec.java
+++ b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBTenantStateCodec.java
@@ -18,7 +18,8 @@
 package org.apache.hadoop.ozone.om.codec;
 
 import org.apache.hadoop.hdds.utils.db.Codec;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,29 +28,30 @@ import java.io.IOException;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Codec to encode OmDBTenantInfo as byte array.
+ * Codec to encode OmDBTenantState as byte array.
  */
-public class OmDBTenantInfoCodec implements Codec<OmDBTenantInfo> {
+public class OmDBTenantStateCodec implements Codec<OmDBTenantState> {
   private static final Logger LOG =
-      LoggerFactory.getLogger(OmDBTenantInfoCodec.class);
+      LoggerFactory.getLogger(OmDBTenantStateCodec.class);
 
   @Override
-  public byte[] toPersistedFormat(OmDBTenantInfo object) throws IOException {
+  public byte[] toPersistedFormat(OmDBTenantState object) throws IOException {
     checkNotNull(object, "Null object can't be converted to byte array.");
-    return object.convertToByteArray();
+    return object.getProtobuf().toByteArray();
   }
 
   @Override
-  public OmDBTenantInfo fromPersistedFormat(byte[] rawData)
+  public OmDBTenantState fromPersistedFormat(byte[] rawData)
       throws IOException {
     checkNotNull(rawData, "Null byte array can't be converted to " +
         "real object.");
-    return OmDBTenantInfo.getFromByteArray(rawData);
+    return OmDBTenantState.getFromProtobuf(
+        OzoneManagerProtocolProtos.TenantState.parseFrom(rawData));
   }
 
   @Override
-  public OmDBTenantInfo copyObject(OmDBTenantInfo object) {
-    // TODO: Not really a "copy". from OMTransactionInfoCodec
+  public OmDBTenantState copyObject(OmDBTenantState object) {
+    // Note: Not really a "copy". from OMTransactionInfoCodec
     return object;
   }
 }
diff --git a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBKerberosPrincipalInfoCodec.java b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBUserPrincipalInfoCodec.java
similarity index 63%
rename from hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBKerberosPrincipalInfoCodec.java
rename to hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBUserPrincipalInfoCodec.java
index 9ddfe1a..dd08e4f 100644
--- a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBKerberosPrincipalInfoCodec.java
+++ b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/codec/OmDBUserPrincipalInfoCodec.java
@@ -18,7 +18,8 @@
 package org.apache.hadoop.ozone.om.codec;
 
 import org.apache.hadoop.hdds.utils.db.Codec;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,32 +28,33 @@ import java.io.IOException;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Codec to encode OmDBKerberosPrincipalInfo as byte array.
+ * Codec to encode OmDBUserPrincipalInfo as byte array.
  */
-public class OmDBKerberosPrincipalInfoCodec
-    implements Codec<OmDBKerberosPrincipalInfo> {
+public class OmDBUserPrincipalInfoCodec
+    implements Codec<OmDBUserPrincipalInfo> {
   private static final Logger LOG =
-      LoggerFactory.getLogger(OmDBKerberosPrincipalInfoCodec.class);
+      LoggerFactory.getLogger(OmDBUserPrincipalInfoCodec.class);
 
   @Override
-  public byte[] toPersistedFormat(OmDBKerberosPrincipalInfo object)
+  public byte[] toPersistedFormat(OmDBUserPrincipalInfo object)
       throws IOException {
     checkNotNull(object, "Null object can't be converted to byte array.");
-    return object.convertToByteArray();
+    return object.getProtobuf().toByteArray();
   }
 
   @Override
-  public OmDBKerberosPrincipalInfo fromPersistedFormat(byte[] rawData)
+  public OmDBUserPrincipalInfo fromPersistedFormat(byte[] rawData)
       throws IOException {
     checkNotNull(rawData, "Null byte array can't be converted to " +
         "real object.");
-    return OmDBKerberosPrincipalInfo.getFromByteArray(rawData);
+    return OmDBUserPrincipalInfo.getFromProtobuf(
+        OzoneManagerProtocolProtos.TenantUserPrincipalInfo.parseFrom(rawData));
   }
 
   @Override
-  public OmDBKerberosPrincipalInfo copyObject(
-      OmDBKerberosPrincipalInfo object) {
-    // TODO: Not really a "copy". See OMTransactionInfoCodec
+  public OmDBUserPrincipalInfo copyObject(
+      OmDBUserPrincipalInfo object) {
+    // Note: Not really a "copy". See OMTransactionInfoCodec
     return object;
   }
 }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
index 5cade68..270e326 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
@@ -21,11 +21,13 @@ import java.util.List;
 
 import com.google.common.base.Optional;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.multitenant.AccessPolicy;
 import org.apache.hadoop.ozone.om.multitenant.AccountNameSpace;
 import org.apache.hadoop.ozone.om.multitenant.BucketNameSpace;
 import org.apache.hadoop.ozone.om.multitenant.Tenant;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.http.auth.BasicUserPrincipal;
 
 /**
@@ -78,7 +80,7 @@ public interface OMMultiTenantManager {
    * @return Tenant interface.
    * @throws IOException
    */
-  Tenant getTenantInfo(String tenantID) throws IOException;
+  Tenant getTenant(String tenantID) throws IOException;
 
   /**
    * Given a TenantID String, deactivate the Tenant. If the Tenant has active
@@ -177,12 +179,15 @@ public interface OMMultiTenantManager {
   void deactivateUser(String accessID) throws IOException;
 
   /**
-   * Check if a user is a tenant Admin.
-   * @param user user name.
-   * @param tenantId tenant name.
-   * @return
+   * Returns true if user is the tenant's admin or Ozone admin, false otherwise.
+   * @param callerUgi caller's UserGroupInformation
+   * @param tenantId tenant name
+   * @param delegated if set to true, checks if the user is a delegated tenant
+   *                  admin; if set to false, checks if the user is a tenant
+   *                  admin, delegated or not
    */
-  boolean isTenantAdmin(String user, String tenantId);
+  boolean isTenantAdmin(UserGroupInformation callerUgi, String tenantId,
+      boolean delegated);
 
   /**
    * Check if a tenant exists.
@@ -217,6 +222,42 @@ public interface OMMultiTenantManager {
   Optional<String> getTenantForAccessID(String accessID) throws IOException;
 
   /**
+   * Get default user role name given tenant name.
+   * @param tenantId tenant name
+   * @return user role name. e.g. tenant1-UserRole
+   */
+  static String getDefaultUserRoleName(String tenantId) {
+    return tenantId + OzoneConsts.DEFAULT_TENANT_ROLE_USER_SUFFIX;
+  }
+
+  /**
+   * Get default admin role name given tenant name.
+   * @param tenantId tenant name
+   * @return admin role name. e.g. tenant1-AdminRole
+   */
+  static String getDefaultAdminRoleName(String tenantId) {
+    return tenantId + OzoneConsts.DEFAULT_TENANT_ROLE_ADMIN_SUFFIX;
+  }
+
+  /**
+   * Get default bucket namespace (volume) policy name given tenant name.
+   * @param tenantId tenant name
+   * @return bucket namespace (volume) policy name. e.g. tenant1-VolumeAccess
+   */
+  static String getDefaultBucketNamespacePolicyName(String tenantId) {
+    return tenantId + OzoneConsts.DEFAULT_TENANT_BUCKET_NAMESPACE_POLICY_SUFFIX;
+  }
+
+  /**
+   * Get default bucket policy name given tenant name.
+   * @param tenantId tenant name
+   * @return bucket policy name. e.g. tenant1-BucketAccess
+   */
+  static String getDefaultBucketPolicyName(String tenantId) {
+    return tenantId + OzoneConsts.DEFAULT_TENANT_BUCKET_POLICY_SUFFIX;
+  }
+
+  /**
    * Given a user, make him an admin of the corresponding Tenant.
    * @param accessID
    * @param delegated
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
index e7ff438..51987a1 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
@@ -51,11 +51,12 @@ import org.apache.hadoop.hdds.utils.db.Table.KeyValue;
 import org.apache.hadoop.hdds.utils.db.TableIterator;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.multitenant.AccessPolicy;
 import org.apache.hadoop.ozone.om.multitenant.AccountNameSpace;
 import org.apache.hadoop.ozone.om.multitenant.BucketNameSpace;
-import org.apache.hadoop.ozone.om.multitenant.CachedTenantInfo;
+import org.apache.hadoop.ozone.om.multitenant.CachedTenantState;
 import org.apache.hadoop.ozone.om.multitenant.OzoneTenant;
 import org.apache.hadoop.ozone.om.multitenant.MultiTenantAccessAuthorizer;
 import org.apache.hadoop.ozone.om.multitenant.MultiTenantAccessAuthorizerDummyPlugin;
@@ -64,10 +65,11 @@ import org.apache.hadoop.ozone.om.multitenant.OzoneOwnerPrincipal;
 import org.apache.hadoop.ozone.om.multitenant.OzoneTenantRolePrincipal;
 import org.apache.hadoop.ozone.om.multitenant.RangerAccessPolicy;
 import org.apache.hadoop.ozone.om.multitenant.Tenant;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantUserAccessId;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserAccessIdInfo;
 import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.ozone.security.acl.OzoneObjInfo;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.http.auth.BasicUserPrincipal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -89,25 +91,27 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
       "ozone.om.tenant.dev.skip.ranger";
 
   private MultiTenantAccessAuthorizer authorizer;
+  private final OzoneManager ozoneManager;
   private final OMMetadataManager omMetadataManager;
   private final OzoneConfiguration conf;
   private final ReentrantReadWriteLock controlPathLock;
-  private final Map<String, CachedTenantInfo> tenantCache;
+  private final Map<String, CachedTenantState> tenantCache;
 
-  OMMultiTenantManagerImpl(OMMetadataManager mgr, OzoneConfiguration conf)
+  OMMultiTenantManagerImpl(OzoneManager ozoneManager, OzoneConfiguration conf)
       throws IOException {
     this.conf = conf;
-    controlPathLock = new ReentrantReadWriteLock();
-    omMetadataManager = mgr;
-    tenantCache = new ConcurrentHashMap<>();
+    this.controlPathLock = new ReentrantReadWriteLock();
+    this.ozoneManager = ozoneManager;
+    this.omMetadataManager = ozoneManager.getMetadataManager();
+    this.tenantCache = new ConcurrentHashMap<>();
     boolean devSkipRanger = conf.getBoolean(OZONE_OM_TENANT_DEV_SKIP_RANGER,
         false);
     if (devSkipRanger) {
-      authorizer = new MultiTenantAccessAuthorizerDummyPlugin();
+      this.authorizer = new MultiTenantAccessAuthorizerDummyPlugin();
     } else {
-      authorizer = new MultiTenantAccessAuthorizerRangerPlugin();
+      this.authorizer = new MultiTenantAccessAuthorizerRangerPlugin();
     }
-    authorizer.init(conf);
+    this.authorizer.init(conf);
     loadUsersFromDB();
   }
 
@@ -200,7 +204,7 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
         tenant.addTenantAccessPolicy(tenantBucketCreatePolicy);
       }
 
-      tenantCache.put(tenantID, new CachedTenantInfo(tenantID));
+      tenantCache.put(tenantID, new CachedTenantState(tenantID));
     } catch (Exception e) {
       try {
         removeTenantAccessFromAuthorizer(tenant);
@@ -215,7 +219,7 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
   }
 
   @Override
-  public Tenant getTenantInfo(String tenantID) throws IOException {
+  public Tenant getTenant(String tenantID) throws IOException {
     // Todo : fix this.
     return null;
   }
@@ -276,10 +280,10 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
 
       LOG.info("Adding user '{}' to tenant '{}' in-memory state.",
           principal.getName(), tenantId);
-      CachedTenantInfo cachedTenantInfo =
+      CachedTenantState cachedTenantState =
           tenantCache.getOrDefault(tenantId,
-              new CachedTenantInfo(tenantId));
-      cachedTenantInfo.getTenantUsers().add(userAccessIdPair);
+              new CachedTenantState(tenantId));
+      cachedTenantState.getTenantUsers().add(userAccessIdPair);
 
       final OzoneTenantRolePrincipal roleTenantAllUsers =
           OzoneTenantRolePrincipal.getUserRole(tenantId);
@@ -378,9 +382,64 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
 
   }
 
-  @Override
-  public boolean isTenantAdmin(String user, String tenantId) {
-    return true;
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isTenantAdmin(UserGroupInformation callerUgi,
+      String tenantId, boolean delegated) {
+    if (callerUgi == null) {
+      return false;
+    } else {
+      return isTenantAdmin(
+              callerUgi.getShortUserName(), tenantId, delegated)
+          || isTenantAdmin(
+              callerUgi.getUserName(), tenantId, delegated)
+          || ozoneManager.isAdmin(callerUgi.getShortUserName())
+          || ozoneManager.isAdmin(callerUgi.getUserName());
+    }
+  }
+
+  /**
+   * Internal isTenantAdmin method that takes a username String instead of UGI.
+   */
+  private boolean isTenantAdmin(String username, String tenantId,
+      boolean delegated) {
+    if (StringUtils.isEmpty(username) || StringUtils.isEmpty(tenantId)) {
+      return false;
+    }
+
+    try {
+      final OmDBUserPrincipalInfo principalInfo =
+          omMetadataManager.getPrincipalToAccessIdsTable().get(username);
+
+      if (principalInfo == null) {
+        // The user is not assigned to any tenant
+        return false;
+      }
+
+      // Find accessId assigned to the specified tenant
+      for (final String accessId : principalInfo.getAccessIds()) {
+        final OmDBAccessIdInfo accessIdInfo =
+            omMetadataManager.getTenantAccessIdTable().get(accessId);
+        // accessIdInfo could be null since we may not have a lock on the tenant
+        if (accessIdInfo == null) {
+          return false;
+        }
+        if (tenantId.equals(accessIdInfo.getTenantId())) {
+          if (!delegated) {
+            return accessIdInfo.getIsAdmin();
+          } else {
+            return accessIdInfo.getIsAdmin()
+                && accessIdInfo.getIsDelegatedAdmin();
+          }
+        }
+      }
+    } catch (IOException e) {
+      LOG.error("Error while retrieving value for key '" + username
+          + "' in PrincipalToAccessIdsTable");
+    }
+
+    return false;
   }
 
   @Override
@@ -396,23 +455,24 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
       throw new IOException("Tenant '" + tenantID + "' not found!");
     }
 
-    List<TenantUserAccessId> userAccessIds = new ArrayList<>();
-    CachedTenantInfo cachedTenantInfo = tenantCache.get(tenantID);
-    if (cachedTenantInfo == null) {
+    List<UserAccessIdInfo> userAccessIds = new ArrayList<>();
+    CachedTenantState cachedTenantState = tenantCache.get(tenantID);
+    if (cachedTenantState == null) {
       throw new IOException("Inconsistent in memory Tenant cache '" + tenantID
           + "' not found in cache, but present in OM DB!");
     }
 
-    cachedTenantInfo.getTenantUsers().stream()
+    cachedTenantState.getTenantUsers().stream()
         .filter(
             k -> StringUtils.isEmpty(prefix) || k.getKey().startsWith(prefix))
         .forEach(
             k -> userAccessIds.add(
-                TenantUserAccessId.newBuilder()
+                UserAccessIdInfo.newBuilder()
                     .setUserPrincipal(k.getKey())
                     .setAccessId(k.getValue())
                     .build()));
-    return new TenantUserList(tenantID, userAccessIds);
+
+    return new TenantUserList(userAccessIds);
   }
 
   @Override
@@ -431,7 +491,6 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
     return null;
   }
 
-
   @Override
   public void assignTenantAdmin(String accessID, boolean delegated)
       throws IOException {
@@ -529,41 +588,45 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
 
   }
 
-  private AccessPolicy newDefaultVolumeAccessPolicy(String volumeName,
-      OzoneTenantRolePrincipal userPrinc, OzoneTenantRolePrincipal adminPrinc)
+  private AccessPolicy newDefaultVolumeAccessPolicy(String tenantId,
+      OzoneTenantRolePrincipal userRole, OzoneTenantRolePrincipal adminRole)
       throws IOException {
 
-    AccessPolicy policy = new RangerAccessPolicy(
-        // principal already contains volume name
-        volumeName + " - VolumeAccess");
+    final String volumeAccessPolicyName =
+        OMMultiTenantManager.getDefaultBucketNamespacePolicyName(tenantId);
+    AccessPolicy policy = new RangerAccessPolicy(volumeAccessPolicyName);
     OzoneObjInfo obj = OzoneObjInfo.Builder.newBuilder()
-        .setResType(VOLUME).setStoreType(OZONE).setVolumeName(volumeName)
+        .setResType(VOLUME).setStoreType(OZONE).setVolumeName(tenantId)
         .setBucketName("").setKeyName("").build();
     // Tenant users have READ, LIST and READ_ACL access on the volume
-    policy.addAccessPolicyElem(obj, userPrinc, READ, ALLOW);
-    policy.addAccessPolicyElem(obj, userPrinc, LIST, ALLOW);
-    policy.addAccessPolicyElem(obj, userPrinc, READ_ACL, ALLOW);
+    policy.addAccessPolicyElem(obj, userRole, READ, ALLOW);
+    policy.addAccessPolicyElem(obj, userRole, LIST, ALLOW);
+    policy.addAccessPolicyElem(obj, userRole, READ_ACL, ALLOW);
     // Tenant admins have ALL access on the volume
-    policy.addAccessPolicyElem(obj, adminPrinc, ALL, ALLOW);
+    policy.addAccessPolicyElem(obj, adminRole, ALL, ALLOW);
     return policy;
   }
 
-  private AccessPolicy newDefaultBucketAccessPolicy(String volumeName,
-      OzoneTenantRolePrincipal userPrinc) throws IOException {
-    AccessPolicy policy = new RangerAccessPolicy(
-        // principal already contains volume name
-        volumeName + " - BucketAccess");
+  private AccessPolicy newDefaultBucketAccessPolicy(String tenantId,
+      OzoneTenantRolePrincipal userRole) throws IOException {
+
+    final String bucketAccessPolicyName =
+        OMMultiTenantManager.getDefaultBucketPolicyName(tenantId);
+    AccessPolicy policy = new RangerAccessPolicy(bucketAccessPolicyName);
     OzoneObjInfo obj = OzoneObjInfo.Builder.newBuilder()
-        .setResType(BUCKET).setStoreType(OZONE).setVolumeName(volumeName)
+        .setResType(BUCKET).setStoreType(OZONE).setVolumeName(tenantId)
         .setBucketName("*").setKeyName("").build();
     // Tenant users have permission to CREATE buckets
-    policy.addAccessPolicyElem(obj, userPrinc, CREATE, ALLOW);
-    // Bucket owner have ALL access on their own buckets. TODO: Tentative
+    policy.addAccessPolicyElem(obj, userRole, CREATE, ALLOW);
+    // Bucket owner have ALL access on their own buckets
     policy.addAccessPolicyElem(obj, new OzoneOwnerPrincipal(), ALL, ALLOW);
     return policy;
   }
 
-  // TODO: Fine-tune this once we have bucket ownership.
+  // TODO: This policy doesn't seem necessary as the bucket-level policy has
+  //  already granted the key-level access.
+  //  Not sure if that is the intended behavior in Ranger though.
+  //  Still, could add this KeyAccess policy as well in Ranger, doesn't hurt.
   private AccessPolicy newDefaultKeyAccessPolicy(String volumeName,
       String bucketName) throws IOException {
     AccessPolicy policy = new RangerAccessPolicy(
@@ -630,9 +693,9 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
         String tenantId = value.getTenantId();
         String user = value.getUserPrincipal();
 
-        CachedTenantInfo cachedTenantInfo = tenantCache
-            .computeIfAbsent(tenantId, k -> new CachedTenantInfo(tenantId));
-        cachedTenantInfo.getTenantUsers().add(
+        CachedTenantState cachedTenantState = tenantCache
+            .computeIfAbsent(tenantId, k -> new CachedTenantState(tenantId));
+        cachedTenantState.getTenantUsers().add(
             new ImmutablePair<>(user, accessId));
         userCount++;
       }
@@ -644,7 +707,7 @@ public class OMMultiTenantManagerImpl implements OMMultiTenantManager {
   }
 
   @VisibleForTesting
-  Map<String, CachedTenantInfo> getTenantCache() {
+  Map<String, CachedTenantState> getTenantCache() {
     return tenantCache;
   }
 }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
index 5b690e6..7c388ca 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
@@ -50,12 +50,12 @@ import org.apache.hadoop.ozone.common.BlockGroup;
 import org.apache.hadoop.hdds.utils.TransactionInfoCodec;
 import org.apache.hadoop.ozone.om.codec.OmBucketInfoCodec;
 import org.apache.hadoop.ozone.om.codec.OmDBAccessIdInfoCodec;
-import org.apache.hadoop.ozone.om.codec.OmDBKerberosPrincipalInfoCodec;
+import org.apache.hadoop.ozone.om.codec.OmDBUserPrincipalInfoCodec;
 import org.apache.hadoop.ozone.om.codec.OmDirectoryInfoCodec;
 import org.apache.hadoop.ozone.om.codec.OmKeyInfoCodec;
 import org.apache.hadoop.ozone.om.codec.OmMultipartKeyInfoCodec;
 import org.apache.hadoop.ozone.om.codec.OmPrefixInfoCodec;
-import org.apache.hadoop.ozone.om.codec.OmDBTenantInfoCodec;
+import org.apache.hadoop.ozone.om.codec.OmDBTenantStateCodec;
 import org.apache.hadoop.ozone.om.codec.OmVolumeArgsCodec;
 import org.apache.hadoop.ozone.om.codec.RepeatedOmKeyInfoCodec;
 import org.apache.hadoop.ozone.om.codec.S3SecretValueCodec;
@@ -65,14 +65,14 @@ import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
 import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartUpload;
 import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
@@ -137,17 +137,11 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
    *
    * Multi-Tenant Tables:
    * |----------------------------------------------------------------------|
-   * | tenantAccessIdTable       | accessId -> OmDBAccessIdInfo             |
-   * |----------------------------------------------------------------------|
-   * | principalToAccessIdsTable | Principal -> OmDBKerberosPrincipalInfo   |
-   * |----------------------------------------------------------------------|
-   * | tenantStateTable          | tenantId -> OmDBTenantInfo               |
+   * | tenantStateTable          | tenantId -> OmDBTenantState              |
    * |----------------------------------------------------------------------|
-   * | tenantGroupTable          | accessId -> [tenant group A, B, ...]     |
-   * |----------------------------------------------------------------------|
-   * | tenantRoleTable           | accessId -> roles [admin, roleB, ...]    |
+   * | tenantAccessIdTable       | accessId -> OmDBAccessIdInfo             |
    * |----------------------------------------------------------------------|
-   * | tenantPolicyTable         | policyGroup -> [policyId1, policyId2]    |
+   * | principalToAccessIdsTable | userPrincipal -> OmDBUserPrincipalInfo   |
    * |----------------------------------------------------------------------|
    *
    * Simple Tables:
@@ -198,9 +192,6 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
   public static final String PRINCIPAL_TO_ACCESS_IDS_TABLE =
       "principalToAccessIdsTable";
   public static final String TENANT_STATE_TABLE = "tenantStateTable";
-  public static final String TENANT_GROUP_TABLE = "tenantGroupTable";
-  public static final String TENANT_ROLE_TABLE = "tenantRoleTable";
-  public static final String TENANT_POLICY_TABLE = "tenantPolicyTable";
 
   static final String[] ALL_TABLES = new String[] {
       USER_TABLE,
@@ -221,10 +212,7 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
       META_TABLE,
       TENANT_ACCESS_ID_TABLE,
       PRINCIPAL_TO_ACCESS_IDS_TABLE,
-      TENANT_STATE_TABLE,
-      TENANT_GROUP_TABLE,
-      TENANT_ROLE_TABLE,
-      TENANT_POLICY_TABLE
+      TENANT_STATE_TABLE
   };
 
   private DBStore store;
@@ -248,13 +236,10 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
   private Table transactionInfoTable;
   private Table metaTable;
 
-  // Tables for multi-tenancy
+  // Tables required for multi-tenancy
   private Table tenantAccessIdTable;
   private Table principalToAccessIdsTable;
   private Table tenantStateTable;
-  private Table tenantGroupTable;
-  private Table tenantRoleTable;
-  private Table tenantPolicyTable;
 
   private boolean isRatisEnabled;
   private boolean ignorePipelineinKey;
@@ -463,9 +448,6 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
         .addTable(TENANT_ACCESS_ID_TABLE)
         .addTable(PRINCIPAL_TO_ACCESS_IDS_TABLE)
         .addTable(TENANT_STATE_TABLE)
-        .addTable(TENANT_GROUP_TABLE)
-        .addTable(TENANT_ROLE_TABLE)
-        .addTable(TENANT_POLICY_TABLE)
         .addCodec(OzoneTokenIdentifier.class, new TokenIdentifierCodec())
         .addCodec(OmKeyInfo.class, new OmKeyInfoCodec(true))
         .addCodec(RepeatedOmKeyInfo.class,
@@ -478,10 +460,10 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
         .addCodec(OmPrefixInfo.class, new OmPrefixInfoCodec())
         .addCodec(TransactionInfo.class, new TransactionInfoCodec())
         .addCodec(OmDirectoryInfo.class, new OmDirectoryInfoCodec())
-        .addCodec(OmDBTenantInfo.class, new OmDBTenantInfoCodec())
+        .addCodec(OmDBTenantState.class, new OmDBTenantStateCodec())
         .addCodec(OmDBAccessIdInfo.class, new OmDBAccessIdInfoCodec())
-        .addCodec(OmDBKerberosPrincipalInfo.class,
-            new OmDBKerberosPrincipalInfoCodec());
+        .addCodec(OmDBUserPrincipalInfo.class,
+            new OmDBUserPrincipalInfoCodec());
   }
 
   /**
@@ -563,31 +545,16 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
         String.class, OmDBAccessIdInfo.class);
     checkTableStatus(tenantAccessIdTable, TENANT_ACCESS_ID_TABLE);
 
-    // User principal -> OmDBKerberosPrincipalInfo (A list of accessIds)
+    // User principal -> OmDBUserPrincipalInfo (a list of accessIds)
     principalToAccessIdsTable = this.store.getTable(
         PRINCIPAL_TO_ACCESS_IDS_TABLE,
-        String.class, OmDBKerberosPrincipalInfo.class);
+        String.class, OmDBUserPrincipalInfo.class);
     checkTableStatus(principalToAccessIdsTable, PRINCIPAL_TO_ACCESS_IDS_TABLE);
 
     // tenant name -> tenant (tenant states)
     tenantStateTable = this.store.getTable(TENANT_STATE_TABLE,
-        String.class, OmDBTenantInfo.class);
+        String.class, OmDBTenantState.class);
     checkTableStatus(tenantStateTable, TENANT_STATE_TABLE);
-
-    // accessId -> list of tenant groups the user belongs to
-    tenantGroupTable = this.store.getTable(TENANT_GROUP_TABLE,
-        String.class, String.class /* TODO: Use custom list */);
-    checkTableStatus(tenantGroupTable, TENANT_GROUP_TABLE);
-
-    // accessId -> list of roles in a tenant. e.g. admin for "finance"
-    tenantRoleTable = this.store.getTable(TENANT_ROLE_TABLE,
-        String.class, String.class /* TODO: Use custom list */);
-    checkTableStatus(tenantRoleTable, TENANT_ROLE_TABLE);
-
-    // tenant policy name -> list of tenant policies
-    tenantPolicyTable = this.store.getTable(TENANT_POLICY_TABLE,
-        String.class, String.class /* TODO: Use custom list */);
-    checkTableStatus(tenantPolicyTable, TENANT_POLICY_TABLE);
   }
 
   /**
@@ -1332,31 +1299,16 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
   }
 
   @Override
-  public Table<String, OmDBKerberosPrincipalInfo>
+  public Table<String, OmDBUserPrincipalInfo>
       getPrincipalToAccessIdsTable() {
     return principalToAccessIdsTable;
   }
 
   @Override
-  public Table<String, OmDBTenantInfo> getTenantStateTable() {
+  public Table<String, OmDBTenantState> getTenantStateTable() {
     return tenantStateTable;
   }
 
-  @Override
-  public Table<String, String> getTenantGroupTable() {
-    return tenantGroupTable;
-  }
-
-  @Override
-  public Table<String, String> getTenantRoleTable() {
-    return tenantRoleTable;
-  }
-
-  @Override
-  public Table<String, String> getTenantPolicyTable() {
-    return tenantPolicyTable;
-  }
-
   /**
    * Update store used by subclass.
    *
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index cac903a..5e3430d 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -117,8 +117,8 @@ import org.apache.hadoop.ozone.om.helpers.OMNodeDetails;
 import org.apache.hadoop.ozone.om.helpers.DBUpdates;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
 import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadList;
@@ -129,7 +129,7 @@ import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.OMInterServiceProtocol;
@@ -157,8 +157,8 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyArgs
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRoleInfo;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3Authentication;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServicePort;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantAccessIdInfo;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantState;
 import org.apache.hadoop.ozone.protocolPB.OMInterServiceProtocolServerSideImpl;
 import org.apache.hadoop.ozone.protocolPB.OMAdminProtocolServerSideImpl;
 import org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos.PersistedUserVolumeInfo;
@@ -650,8 +650,7 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
   private void instantiateServices(boolean withNewSnapshot) throws IOException {
 
     metadataManager = new OmMetadataManagerImpl(configuration);
-    multiTenantManager = new OMMultiTenantManagerImpl(metadataManager,
-        configuration);
+    multiTenantManager = new OMMultiTenantManagerImpl(this, configuration);
     OzoneAclUtils.setOMMultiTenantManager(multiTenantManager);
     volumeManager = new VolumeManagerImpl(metadataManager, configuration);
     bucketManager = new BucketManagerImpl(metadataManager, getKmsProvider(),
@@ -2953,7 +2952,7 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
   /**
    * List tenants.
    */
-  public TenantInfoList listTenant() throws IOException {
+  public TenantStateList listTenant() throws IOException {
 
     final UserGroupInformation ugi = getRemoteUser();
     if (!isAdmin(ugi)) {
@@ -2964,7 +2963,7 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
       throw omEx;
     }
 
-    final Table<String, OmDBTenantInfo> tenantStateTable =
+    final Table<String, OmDBTenantState> tenantStateTable =
         metadataManager.getTenantStateTable();
 
     // Won't iterate cache here, mainly because we can't acquire a read lock
@@ -2973,30 +2972,32 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
     // are flushed to the table. This should be acceptable for a list tenant
     // request.
 
-    final TableIterator<String, ? extends KeyValue<String, OmDBTenantInfo>>
+    final TableIterator<String, ? extends KeyValue<String, OmDBTenantState>>
         iterator = tenantStateTable.iterator();
 
-    final List<TenantInfo> tenantInfoList = new ArrayList<>();
+    final List<TenantState> tenantStateList = new ArrayList<>();
 
     // Iterate table
     while (iterator.hasNext()) {
-      final Table.KeyValue<String, OmDBTenantInfo> dbEntry = iterator.next();
+      final Table.KeyValue<String, OmDBTenantState> dbEntry = iterator.next();
       final String tenantId = dbEntry.getKey();
-      final OmDBTenantInfo omDBTenantInfo = dbEntry.getValue();
-      assert (tenantId.equals(omDBTenantInfo.getTenantId()));
-      tenantInfoList.add(TenantInfo.newBuilder()
-          .setTenantId(omDBTenantInfo.getTenantId())
-          .setBucketNamespaceName(omDBTenantInfo.getBucketNamespaceName())
-          .setAccountNamespaceName(omDBTenantInfo.getAccountNamespaceName())
-          .setUserPolicyGroupName(omDBTenantInfo.getUserPolicyGroupName())
-          .setBucketNamespaceName(omDBTenantInfo.getBucketPolicyGroupName())
+      final OmDBTenantState omDBTenantState = dbEntry.getValue();
+      assert (tenantId.equals(omDBTenantState.getTenantId()));
+      tenantStateList.add(TenantState.newBuilder()
+          .setTenantId(omDBTenantState.getTenantId())
+          .setBucketNamespaceName(omDBTenantState.getBucketNamespaceName())
+          .setUserRoleName(omDBTenantState.getUserRoleName())
+          .setAdminRoleName(omDBTenantState.getAdminRoleName())
+          .setBucketNamespacePolicyName(
+              omDBTenantState.getBucketNamespacePolicyName())
+          .setBucketPolicyName(omDBTenantState.getBucketPolicyName())
           .build());
     }
 
     AUDIT.logReadSuccess(buildAuditMessageForSuccess(
         OMAction.LIST_TENANT, new LinkedHashMap<>()));
 
-    return new TenantInfoList(tenantInfoList);
+    return new TenantStateList(tenantStateList);
   }
 
   /**
@@ -3009,14 +3010,14 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
       return null;
     }
 
-    final List<TenantAccessIdInfo> accessIdInfoList = new ArrayList<>();
+    final List<ExtendedUserAccessIdInfo> accessIdInfoList = new ArrayList<>();
 
     // Won't iterate cache here for a similar reason as in OM#listTenant
     //  tenantGetUserInfo lists all accessIds assigned to a user across
     //  multiple tenants.
 
     // Retrieve the list of accessIds associated to this user principal
-    final OmDBKerberosPrincipalInfo kerberosPrincipalInfo =
+    final OmDBUserPrincipalInfo kerberosPrincipalInfo =
         metadataManager.getPrincipalToAccessIdsTable().get(userPrincipal);
     if (kerberosPrincipalInfo == null) {
       return null;
@@ -3039,7 +3040,8 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
           return;
         }
         assert (accessIdInfo.getUserPrincipal().equals(userPrincipal));
-        accessIdInfoList.add(TenantAccessIdInfo.newBuilder()
+        accessIdInfoList.add(ExtendedUserAccessIdInfo.newBuilder()
+            .setUserPrincipal(userPrincipal)
             .setAccessId(accessId)
             .setTenantId(accessIdInfo.getTenantId())
             .setIsAdmin(accessIdInfo.getIsAdmin())
@@ -3059,7 +3061,7 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
     AUDIT.logReadSuccess(buildAuditMessageForSuccess(
         OMAction.TENANT_GET_USER_INFO, auditMap));
 
-    return new TenantUserInfoValue(userPrincipal, accessIdInfoList);
+    return new TenantUserInfoValue(accessIdInfoList);
   }
 
   @Override
@@ -3078,7 +3080,7 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
 
     final String volumeName = OMTenantRequestHelper.getTenantVolumeName(
             getMetadataManager(), tenantId);
-    // TODO: Maybe use multiTenantManager.getTenantInfo(tenantId)
+    // TODO: Maybe use multiTenantManager.getTenantState(tenantId)
     //  .getTenantBucketNameSpace() after refactoring
 
     final Map<String, String> auditMap = new LinkedHashMap<>();
@@ -3089,11 +3091,11 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
     boolean lockAcquired =
         metadataManager.getLock().acquireReadLock(VOLUME_LOCK, volumeName);
     try {
-      String userName = getRemoteUser().getUserName();
-      if (!multiTenantManager.isTenantAdmin(userName, tenantId)
-          && !omAdminUsernames.contains(userName)) {
-        throw new IOException("Only tenant and ozone admins can access this " +
-            "API. '" + userName + "' is not an admin.");
+      final UserGroupInformation ugi = ProtobufRpcEngine.Server.getRemoteUser();
+      if (!multiTenantManager.isTenantAdmin(ugi, tenantId, false)) {
+        throw new OMException("Only tenant and ozone admins can access this " +
+            "API. '" + ugi.getShortUserName() + "' is not an admin.",
+            PERMISSION_DENIED);
       }
       final TenantUserList userList =
           multiTenantManager.listUsersInTenant(tenantId, prefix);
@@ -3128,10 +3130,10 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
       if (optionalTenantId.isPresent()) {
         final String tenantId = optionalTenantId.get();
 
-        OmDBTenantInfo tenantInfo =
+        OmDBTenantState tenantState =
             metadataManager.getTenantStateTable().get(tenantId);
-        if (tenantInfo != null) {
-          s3Volume = tenantInfo.getBucketNamespaceName();
+        if (tenantState != null) {
+          s3Volume = tenantState.getBucketNamespaceName();
         } else {
           String message = "Unable to find tenant '" + tenantId
               + "' details for access ID " + accessId
@@ -3807,58 +3809,6 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
     }
   }
 
-  public boolean isTenantAdmin(UserGroupInformation callerUgi,
-                               String tenantId, Boolean delegated) {
-    if (callerUgi == null) {
-      return false;
-    } else {
-      return isTenantAdmin(callerUgi.getShortUserName(), tenantId, delegated)
-          || isTenantAdmin(callerUgi.getUserName(), tenantId, delegated);
-    }
-  }
-
-  /**
-   * Returns true if user is a tenant's admin, false otherwise.
-   * @param username User name string.
-   * @param tenantId Tenant name string.
-   * @param delegated True if operation requires delegated admin permission.
-   */
-  public boolean isTenantAdmin(String username,
-      String tenantId, Boolean delegated) {
-    if (StringUtils.isEmpty(username) || StringUtils.isEmpty(tenantId)) {
-      return false;
-    }
-
-    try {
-      final OmDBKerberosPrincipalInfo principalInfo =
-          getMetadataManager().getPrincipalToAccessIdsTable().get(username);
-
-      if (principalInfo == null) {
-        // The user is not assigned to any tenant
-        return false;
-      }
-
-      // Find accessId assigned to the specified tenant
-      for (final String accessId : principalInfo.getAccessIds()) {
-        final OmDBAccessIdInfo accessIdInfo =
-            getMetadataManager().getTenantAccessIdTable().get(accessId);
-        if (tenantId.equals(accessIdInfo.getTenantId())) {
-          if (!delegated) {
-            return accessIdInfo.getIsAdmin();
-          } else {
-            return accessIdInfo.getIsAdmin()
-                && accessIdInfo.getIsDelegatedAdmin();
-          }
-        }
-      }
-    } catch (IOException e) {
-      LOG.error("Error while retrieving value for key '" + username
-          + "' in PrincipalToAccessIdsTable");
-    }
-
-    return false;
-  }
-
   /**
    * Returns true if OzoneNativeAuthorizer is enabled and false if otherwise.
    *
@@ -3914,10 +3864,8 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
     if (isAclEnabled) {
       UserGroupInformation ugi = Server.getRemoteUser();
       if (getS3Auth() != null) {
-        ugi = UserGroupInformation
-            .createRemoteUser(
-                OzoneAclUtils.accessIdToUserPrincipal(
-                    getS3Auth().getAccessId()));
+        ugi = UserGroupInformation.createRemoteUser(
+            OzoneAclUtils.accessIdToUserPrincipal(getS3Auth().getAccessId()));
       }
       InetAddress remoteIp = Server.getRemoteIp();
       resolved = resolveBucketLink(requested, new HashSet<>(),
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
index cb6cd6c..ef688ee 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
@@ -28,9 +28,9 @@ import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
@@ -199,51 +199,23 @@ public class OMDBDefinition implements DBDefinition {
                     OmDBAccessIdInfo.class,  // tenantId, secret, principal
                     new OmDBAccessIdInfoCodec());
 
-  public static final DBColumnFamilyDefinition<String,
-            OmDBKerberosPrincipalInfo>
+  public static final DBColumnFamilyDefinition<String, OmDBUserPrincipalInfo>
             PRINCIPAL_TO_ACCESS_IDS_TABLE =
             new DBColumnFamilyDefinition<>(
                     OmMetadataManagerImpl.PRINCIPAL_TO_ACCESS_IDS_TABLE,
-                    String.class,  // Kerberos principal
+                    String.class,  // User principal
                     new StringCodec(),
-                    OmDBKerberosPrincipalInfo.class,  // List of accessIds
-                    new OmDBKerberosPrincipalInfoCodec());
+                    OmDBUserPrincipalInfo.class,  // List of accessIds
+                    new OmDBUserPrincipalInfoCodec());
 
-  public static final DBColumnFamilyDefinition<String, OmDBTenantInfo>
+  public static final DBColumnFamilyDefinition<String, OmDBTenantState>
             TENANT_STATE_TABLE =
             new DBColumnFamilyDefinition<>(
                     OmMetadataManagerImpl.TENANT_STATE_TABLE,
-                    String.class,
-                    new StringCodec(),
-                    OmDBTenantInfo.class,
-                    new OmDBTenantInfoCodec());
-
-  public static final DBColumnFamilyDefinition<String, String>
-            TENANT_GROUP_TABLE =
-            new DBColumnFamilyDefinition<>(
-                    OmMetadataManagerImpl.TENANT_GROUP_TABLE,
-                    String.class,
-                    new StringCodec(),
-                    String.class,
-                    new StringCodec());
-
-  public static final DBColumnFamilyDefinition<String, String>
-            TENANT_ROLE_TABLE =
-            new DBColumnFamilyDefinition<>(
-                    OmMetadataManagerImpl.TENANT_ROLE_TABLE,
-                    String.class,
-                    new StringCodec(),
-                    String.class,
-                    new StringCodec());
-
-  public static final DBColumnFamilyDefinition<String, String>
-            TENANT_POLICY_TABLE =
-            new DBColumnFamilyDefinition<>(
-                    OmMetadataManagerImpl.TENANT_POLICY_TABLE,
-                    String.class,
+                    String.class,  // tenantId (tenant name)
                     new StringCodec(),
-                    String.class,
-                    new StringCodec());
+                    OmDBTenantState.class,
+                    new OmDBTenantStateCodec());
 
   // End tables for S3 multi-tenancy
 
@@ -265,8 +237,7 @@ public class OMDBDefinition implements DBDefinition {
         S3_SECRET_TABLE, TRANSACTION_INFO_TABLE, DIRECTORY_TABLE,
         FILE_TABLE, OPEN_FILE_TABLE, DELETED_DIR_TABLE, META_TABLE,
         TENANT_ACCESS_ID_TABLE,
-        PRINCIPAL_TO_ACCESS_IDS_TABLE, TENANT_STATE_TABLE, TENANT_GROUP_TABLE,
-        TENANT_ROLE_TABLE, TENANT_POLICY_TABLE };
+        PRINCIPAL_TO_ACCESS_IDS_TABLE, TENANT_STATE_TABLE};
   }
 }
 
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/CachedTenantInfo.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/CachedTenantState.java
similarity index 94%
rename from hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/CachedTenantInfo.java
rename to hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/CachedTenantState.java
index b93eea2..5dc512f 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/CachedTenantInfo.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/CachedTenantState.java
@@ -25,12 +25,12 @@ import org.apache.commons.lang3.tuple.Pair;
 /**
  * A collection of things that we want to maintain about a tenant in memory.
  */
-public class CachedTenantInfo {
+public class CachedTenantState {
 
   private String tenantId;
   private Set<Pair<String, String>> tenantUserAccessIds;
 
-  public CachedTenantInfo(String tenantId) {
+  public CachedTenantState(String tenantId) {
     this.tenantId = tenantId;
     tenantUserAccessIds = new HashSet<>();
   }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignAdminRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignAdminRequest.java
index 0967388..640d3ae 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignAdminRequest.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignAdminRequest.java
@@ -159,7 +159,8 @@ public class OMTenantAssignAdminRequest extends OMClientRequest {
         OmResponseUtil.getOMResponseBuilder(getOmRequest());
 
     final Map<String, String> auditMap = new HashMap<>();
-    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
+    final OMMetadataManager omMetadataManager =
+        ozoneManager.getMetadataManager();
 
     final TenantAssignAdminRequest request =
         getOmRequest().getTenantAssignAdminRequest();
@@ -179,35 +180,29 @@ public class OMTenantAssignAdminRequest extends OMClientRequest {
       acquiredVolumeLock = omMetadataManager.getLock().acquireWriteLock(
           VOLUME_LOCK, volumeName);
 
-      final OmDBAccessIdInfo oldAccessIdInfo =
+      final OmDBAccessIdInfo dbAccessIdInfo =
           omMetadataManager.getTenantAccessIdTable().get(accessId);
 
-      if (oldAccessIdInfo == null) {
+      if (dbAccessIdInfo == null) {
         throw new OMException("OmDBAccessIdInfo entry is missing for accessId '"
-            + accessId + "'.", OMException.ResultCodes.METADATA_ERROR);
+            + accessId + "'", OMException.ResultCodes.METADATA_ERROR);
       }
 
-      assert (oldAccessIdInfo.getTenantId().equals(tenantId));
+      assert (dbAccessIdInfo.getTenantId().equals(tenantId));
 
       // Update tenantAccessIdTable
       final OmDBAccessIdInfo newOmDBAccessIdInfo =
           new OmDBAccessIdInfo.Builder()
-          .setTenantId(oldAccessIdInfo.getTenantId())
-          .setKerberosPrincipal(oldAccessIdInfo.getUserPrincipal())
-          .setIsAdmin(true)
-          .setIsDelegatedAdmin(delegated)
-          .build();
+              .setTenantId(dbAccessIdInfo.getTenantId())
+              .setUserPrincipal(dbAccessIdInfo.getUserPrincipal())
+              .setIsAdmin(true)
+              .setIsDelegatedAdmin(delegated)
+              .build();
       omMetadataManager.getTenantAccessIdTable().addCacheEntry(
           new CacheKey<>(accessId),
           new CacheValue<>(Optional.of(newOmDBAccessIdInfo),
               transactionLogIndex));
 
-      // TODO: Update tenantRoleTable?
-//      final String roleName = "role_admin";
-//      omMetadataManager.getTenantRoleTable().addCacheEntry(
-//          new CacheKey<>(accessId),
-//          new CacheValue<>(Optional.of(roleName), transactionLogIndex));
-
       omResponse.setTenantAssignAdminResponse(
           TenantAssignAdminResponse.newBuilder()
               .build());
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
index c96eedc..a270dbd 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
@@ -30,7 +30,7 @@ import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
 import org.apache.hadoop.ozone.om.request.OMClientRequest;
@@ -54,7 +54,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.TreeSet;
 
-import static org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo.SERIALIZATION_SPLIT_KEY;
 import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.S3_SECRET_LOCK;
 import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.VOLUME_LOCK;
 import static org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantRequestHelper.checkTenantAdmin;
@@ -90,12 +89,8 @@ import static org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature.MULTITENANCY_SC
              Example of accessId: finance$bob@EXAMPLE.COM
       - Value: OmDBAccessIdInfo. Has tenantId, kerberosPrincipal, sharedSecret.
     - New entry or update existing entry in principalToAccessIdsTable:
-      - Key: Kerberos principal of the user.
-      - Value: OmDBKerberosPrincipalInfo. Has accessIds.
-    - tenantGroupTable: Add this new user to the default tenant group.
-      - Key: finance$bob
-      - Value: finance-users
-    - tenantRoleTable: TBD. No-Op for now.
+      - Key: User principal. Usually the short name of the Kerberos principal.
+      - Value: OmDBUserPrincipalInfo. Has accessIds.
     - Release VOLUME_LOCK write lock
  */
 
@@ -148,13 +143,6 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
           OMException.ResultCodes.INVALID_ACCESS_ID);
     }
 
-    // Check accessId validity.
-    if (accessId.contains(SERIALIZATION_SPLIT_KEY)) {
-      throw new OMException("Invalid accessId '" + accessId +
-          "'. accessId should not contain '" + SERIALIZATION_SPLIT_KEY + "'",
-          OMException.ResultCodes.INVALID_ACCESS_ID);
-    }
-
     checkTenantExistence(ozoneManager.getMetadataManager(), tenantId);
 
     // Below call implies user existence check in authorizer.
@@ -231,8 +219,9 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
 
     boolean acquiredVolumeLock = false;
     boolean acquiredS3SecretLock = false;
-    Map<String, String> auditMap = new HashMap<>();
-    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
+    final Map<String, String> auditMap = new HashMap<>();
+    final OMMetadataManager omMetadataManager =
+        ozoneManager.getMetadataManager();
 
     final TenantAssignUserAccessIdRequest request =
         getOmRequest().getTenantAssignUserAccessIdRequest();
@@ -265,7 +254,7 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
             OMException.ResultCodes.TENANT_USER_ACCESS_ID_ALREADY_EXISTS);
       }
 
-      OmDBKerberosPrincipalInfo principalInfo = omMetadataManager
+      OmDBUserPrincipalInfo principalInfo = omMetadataManager
           .getPrincipalToAccessIdsTable().getIfExist(userPrincipal);
       // Reject if the user is already assigned to the tenant
       if (principalInfo != null) {
@@ -295,7 +284,7 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
       // Add to tenantAccessIdTable
       final OmDBAccessIdInfo omDBAccessIdInfo = new OmDBAccessIdInfo.Builder()
           .setTenantId(tenantId)
-          .setKerberosPrincipal(userPrincipal)
+          .setUserPrincipal(userPrincipal)
           .setIsAdmin(false)
           .setIsDelegatedAdmin(false)
           .build();
@@ -305,7 +294,7 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
 
       // Add to principalToAccessIdsTable
       if (principalInfo == null) {
-        principalInfo = new OmDBKerberosPrincipalInfo.Builder()
+        principalInfo = new OmDBUserPrincipalInfo.Builder()
             .setAccessIds(new TreeSet<>(Collections.singleton(accessId)))
             .build();
       } else {
@@ -316,21 +305,6 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
           new CacheValue<>(Optional.of(principalInfo),
               transactionLogIndex));
 
-      // Add to tenantGroupTable
-      // TODO: TenantGroupTable is unused for now.
-      final String defaultGroupName =
-          tenantId + OzoneConsts.DEFAULT_TENANT_USER_GROUP_SUFFIX;
-      omMetadataManager.getTenantGroupTable().addCacheEntry(
-          new CacheKey<>(accessId),
-          new CacheValue<>(Optional.of(defaultGroupName), transactionLogIndex));
-
-      // Add to tenantRoleTable
-      // TODO: TenantRoleTable is unused for now.
-      final String roleName = "user";
-      omMetadataManager.getTenantRoleTable().addCacheEntry(
-          new CacheKey<>(accessId),
-          new CacheValue<>(Optional.of(roleName), transactionLogIndex));
-
       // Add S3SecretTable cache entry
       acquiredS3SecretLock = omMetadataManager.getLock()
           .acquireWriteLock(S3_SECRET_LOCK, accessId);
@@ -357,8 +331,8 @@ public class OMTenantAssignUserAccessIdRequest extends OMClientRequest {
                   .setAwsSecret(awsSecret).setKerberosID(accessId))
               .build());
       omClientResponse = new OMTenantAssignUserAccessIdResponse(
-          omResponse.build(), s3SecretValue, userPrincipal, defaultGroupName,
-          roleName, accessId, omDBAccessIdInfo, principalInfo);
+          omResponse.build(), s3SecretValue, userPrincipal,
+          accessId, omDBAccessIdInfo, principalInfo);
     } catch (IOException ex) {
       handleRequestFailure(ozoneManager);
       exception = ex;
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantCreateRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantCreateRequest.java
index 17e739c..14e03ea 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantCreateRequest.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantCreateRequest.java
@@ -27,9 +27,10 @@ import org.apache.hadoop.ozone.OmUtils;
 import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.audit.OMAction;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.OMMultiTenantManager;
 import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.multitenant.AccessPolicy;
 import org.apache.hadoop.ozone.om.multitenant.Tenant;
@@ -78,7 +79,7 @@ import static org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature.MULTITENANCY_SC
     - If tenant already exists, throw exception to client; else continue
   - tenantStateTable: New entry
     - Key: tenant name. e.g. finance
-    - Value: new OmDBTenantInfo for the tenant
+    - Value: new OmDBTenantState for the tenant
       - tenantId: finance
       - bucketNamespaceName: finance
       - accountNamespaceName: finance
@@ -157,8 +158,6 @@ public class OMTenantCreateRequest extends OMVolumeRequest {
         .setOwnerName(owner)
         .build();
 
-    // TODO: Shall we check volume existence here as well?
-
     // Generate volume modification time
     long initialTime = Time.now();
     final VolumeInfo updatedVolumeInfo = volumeInfo.toBuilder()
@@ -181,7 +180,8 @@ public class OMTenantCreateRequest extends OMVolumeRequest {
         .setCreateTenantRequest(
             CreateTenantRequest.newBuilder()
                 .setTenantDefaultPolicyName(tenantDefaultPolicies)
-                .setTenantId(tenantId))
+                .setTenantId(tenantId)
+                .setVolumeName(volumeName))
         .setCreateVolumeRequest(
             CreateVolumeRequest.newBuilder().setVolumeInfo(updatedVolumeInfo))
         // TODO: Can the three lines below be ignored?
@@ -231,6 +231,8 @@ public class OMTenantCreateRequest extends OMVolumeRequest {
     final VolumeInfo volumeInfo =
         getOmRequest().getCreateVolumeRequest().getVolumeInfo();
     final String volumeName = volumeInfo.getVolume();
+    Preconditions.checkState(request.getVolumeName().equals(volumeName),
+        "CreateTenantRequest's volumeName value should match VolumeInfo's");
     final String dbVolumeKey = omMetadataManager.getVolumeKey(volumeName);
     IOException exception = null;
 
@@ -289,36 +291,27 @@ public class OMTenantCreateRequest extends OMVolumeRequest {
       // Create tenant
       // Add to tenantStateTable. Redundant assignment for clarity
       final String bucketNamespaceName = volumeName;
-      final String accountNamespaceName = tenantId;  // TODO: Double check
-      final String userPolicyGroupName =
-          tenantId + OzoneConsts.DEFAULT_TENANT_USER_POLICY_SUFFIX;
-      final String bucketPolicyGroupName =
-          tenantId + OzoneConsts.DEFAULT_TENANT_BUCKET_POLICY_SUFFIX;
-      final OmDBTenantInfo omDBTenantInfo = new OmDBTenantInfo(
-          tenantId, bucketNamespaceName, accountNamespaceName,
-          userPolicyGroupName, bucketPolicyGroupName);
+      // Populate policy ID list
+      final String bucketNamespacePolicyName =
+          OMMultiTenantManager.getDefaultBucketNamespacePolicyName(tenantId);
+      final String bucketPolicyName =
+          OMMultiTenantManager.getDefaultBucketPolicyName(tenantId);
+      final String userRoleName =
+          OMMultiTenantManager.getDefaultUserRoleName(tenantId);
+      final String adminRoleName =
+          OMMultiTenantManager.getDefaultAdminRoleName(tenantId);
+      final OmDBTenantState omDBTenantState = new OmDBTenantState(
+          tenantId, bucketNamespaceName, userRoleName, adminRoleName,
+          bucketNamespacePolicyName, bucketPolicyName);
       omMetadataManager.getTenantStateTable().addCacheEntry(
           new CacheKey<>(tenantId),
-          new CacheValue<>(Optional.of(omDBTenantInfo), transactionLogIndex));
-
-      // Add to tenantPolicyTable
-      omMetadataManager.getTenantPolicyTable().addCacheEntry(
-          new CacheKey<>(userPolicyGroupName),
-          new CacheValue<>(Optional.of(tenantDefaultPolicies),
-              transactionLogIndex));
-      final String bucketPolicyId =
-          bucketPolicyGroupName + OzoneConsts.DEFAULT_TENANT_POLICY_ID_SUFFIX;
-      omMetadataManager.getTenantPolicyTable().addCacheEntry(
-          new CacheKey<>(bucketPolicyGroupName),
-          new CacheValue<>(Optional.of(bucketPolicyId), transactionLogIndex));
+          new CacheValue<>(Optional.of(omDBTenantState), transactionLogIndex));
 
       omResponse.setCreateTenantResponse(
           CreateTenantResponse.newBuilder()
               .build());
-      omClientResponse = new OMTenantCreateResponse(
-          omResponse.build(),
-          omVolumeArgs, volumeList,
-          omDBTenantInfo, tenantDefaultPolicies, bucketPolicyId);
+      omClientResponse = new OMTenantCreateResponse(omResponse.build(),
+          omVolumeArgs, volumeList, omDBTenantState);
 
     } catch (IOException ex) {
       // Error handling. Clean up Ranger policies when necessary.
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantDeleteRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantDeleteRequest.java
index 2db50a8..e1a9ee9 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantDeleteRequest.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantDeleteRequest.java
@@ -27,7 +27,7 @@ import org.apache.hadoop.ozone.audit.OMAction;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
 import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
@@ -105,11 +105,11 @@ public class OMTenantDeleteRequest extends OMVolumeRequest {
       }
 
       // Reading the TenantStateTable without lock as we don't have or need
-      // a TENANT_LOCK. The assumption is that OmDBTenantInfo is read-only
+      // a TENANT_LOCK. The assumption is that OmDBTenantState is read-only
       // once it is set during tenant creation.
-      final OmDBTenantInfo dbTenantInfo =
+      final OmDBTenantState dbTenantState =
           omMetadataManager.getTenantStateTable().get(tenantId);
-      volumeName = dbTenantInfo.getBucketNamespaceName();
+      volumeName = dbTenantState.getBucketNamespaceName();
       assert (volumeName != null);
 
       LOG.debug("Tenant '{}' has volume '{}'", tenantId, volumeName);
@@ -130,22 +130,11 @@ public class OMTenantDeleteRequest extends OMVolumeRequest {
             TENANT_NOT_EMPTY);
       }
 
-      // Invalidate cache entries
+      // Invalidate cache entry
       omMetadataManager.getTenantStateTable().addCacheEntry(
           new CacheKey<>(tenantId),
           new CacheValue<>(Optional.absent(), transactionLogIndex));
 
-      final String userPolicyGroupName = dbTenantInfo.getUserPolicyGroupName();
-      omMetadataManager.getTenantPolicyTable().addCacheEntry(
-          new CacheKey<>(userPolicyGroupName),
-          new CacheValue<>(Optional.absent(), transactionLogIndex));
-
-      final String bucketPolicyGroupName =
-          dbTenantInfo.getBucketPolicyGroupName();
-      omMetadataManager.getTenantPolicyTable().addCacheEntry(
-          new CacheKey<>(bucketPolicyGroupName),
-          new CacheValue<>(Optional.absent(), transactionLogIndex));
-
       // Decrement volume refCount
       if (decVolumeRefCount) {
         // Check Acl
@@ -182,8 +171,7 @@ public class OMTenantDeleteRequest extends OMVolumeRequest {
 
       omClientResponse = new OMTenantDeleteResponse(
           omResponse.setDeleteTenantResponse(deleteTenantResponse).build(),
-          volumeName, omVolumeArgs, tenantId, userPolicyGroupName,
-          bucketPolicyGroupName);
+          volumeName, omVolumeArgs, tenantId);
 
     } catch (IOException ex) {
       exception = ex;
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRequestHelper.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRequestHelper.java
index b880675..56b3842 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRequestHelper.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRequestHelper.java
@@ -28,8 +28,8 @@ import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantUserAccessId;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserAccessIdInfo;
 import org.apache.hadoop.security.UserGroupInformation;
 
 import java.io.IOException;
@@ -59,16 +59,17 @@ public final class OMTenantRequestHelper {
   }
 
   /**
-   * Passes check if caller is an Ozone cluster admin or tenant delegated admin,
-   * throws OMException otherwise.
+   * Check if caller is an Ozone cluster admin or tenant (delegated) admin.
+   * Throws PERMISSION_DENIED if the check failed.
+   *
    * @throws OMException PERMISSION_DENIED
    */
   static void checkTenantAdmin(OzoneManager ozoneManager, String tenantId)
       throws OMException {
 
     final UserGroupInformation ugi = ProtobufRpcEngine.Server.getRemoteUser();
-    if (!ozoneManager.isAdmin(ugi) &&
-        !ozoneManager.isTenantAdmin(ugi, tenantId, true)) {
+    if (!ozoneManager.getMultiTenantManager().isTenantAdmin(
+        ugi, tenantId, true)) {
       throw new OMException("User '" + ugi.getUserName() +
           "' is neither an Ozone admin nor a delegated admin of tenant '" +
           tenantId + "'.", OMException.ResultCodes.PERMISSION_DENIED);
@@ -93,7 +94,7 @@ public final class OMTenantRequestHelper {
           throw omEx;
         }
       }
-      throw new OMException("Error while retrieving OmDBTenantInfo for tenant "
+      throw new OMException("Error while retrieving OmDBTenantState for tenant "
           + "'" + tenantId + "': " + ex.getMessage(),
           OMException.ResultCodes.METADATA_ERROR);
     }
@@ -107,16 +108,16 @@ public final class OMTenantRequestHelper {
   public static String getTenantVolumeName(OMMetadataManager omMetadataManager,
                                            String tenantId) throws IOException {
 
-    final OmDBTenantInfo tenantInfo =
+    final OmDBTenantState tenantState =
         omMetadataManager.getTenantStateTable().get(tenantId);
 
-    if (tenantInfo == null) {
+    if (tenantState == null) {
       throw new OMException("Potential DB error or race condition. "
-          + "OmDBTenantInfo entry is missing for tenant '" + tenantId + "'.",
+          + "OmDBTenantState entry is missing for tenant '" + tenantId + "'.",
           ResultCodes.TENANT_NOT_FOUND);
     }
 
-    final String volumeName = tenantInfo.getBucketNamespaceName();
+    final String volumeName = tenantState.getBucketNamespaceName();
 
     if (volumeName == null) {
       throw new OMException("Potential DB error. volumeName "
@@ -152,8 +153,9 @@ public final class OMTenantRequestHelper {
           OzoneManager ozoneManager, String accessId,
           UserGroupInformation ugi) throws IOException {
 
-    final OmDBAccessIdInfo accessIdInfo = ozoneManager.getMetadataManager()
-            .getTenantAccessIdTable().get(accessId);
+    final OMMetadataManager metadataManager = ozoneManager.getMetadataManager();
+    final OmDBAccessIdInfo accessIdInfo =
+        metadataManager.getTenantAccessIdTable().get(accessId);
 
     if (accessIdInfo == null) {
       // Doesn't have the accessId entry in TenantAccessIdTable.
@@ -182,8 +184,10 @@ public final class OMTenantRequestHelper {
       return true;
     }
 
-    // Check if ugi is an admin of this tenant
-    if (ozoneManager.isTenantAdmin(ugi, tenantId, true)) {
+    // Check if ugi is a tenant admin (or an Ozone cluster admin)
+    final OMMultiTenantManager multiTenantManager =
+        ozoneManager.getMultiTenantManager();
+    if (multiTenantManager.isTenantAdmin(ugi, tenantId, false)) {
       return true;
     }
 
@@ -237,7 +241,7 @@ public final class OMTenantRequestHelper {
     //  (apart from it being populated on OM startup) right now.
     //  So unless tenantCache is updated on follower nodes later as well,
     //  we can't use listUsersInTenant to check tenant emptiness in followers.
-    final List<TenantUserAccessId> tenantUserAccessIdsList =
+    final List<UserAccessIdInfo> tenantUserAccessIdsList =
         tenantManager.listUsersInTenant(tenantId, "").getUserAccessIds();
     return tenantUserAccessIdsList.size() == 0;
   }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeAdminRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeAdminRequest.java
index 5757b0f..ef72019 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeAdminRequest.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeAdminRequest.java
@@ -142,14 +142,15 @@ public class OMTenantRevokeAdminRequest extends OMClientRequest {
         OmResponseUtil.getOMResponseBuilder(getOmRequest());
 
     final Map<String, String> auditMap = new HashMap<>();
-    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
+    final OMMetadataManager omMetadataManager =
+        ozoneManager.getMetadataManager();
 
     final TenantRevokeAdminRequest request =
         getOmRequest().getTenantRevokeAdminRequest();
     final String accessId = request.getAccessId();
     final String tenantId = request.getTenantId();
 
-    boolean acquiredVolumeLock = false;  // TODO: use tenant lock instead, maybe
+    boolean acquiredVolumeLock = false;
     IOException exception = null;
 
     String volumeName = null;
@@ -161,35 +162,29 @@ public class OMTenantRevokeAdminRequest extends OMClientRequest {
       acquiredVolumeLock = omMetadataManager.getLock().acquireWriteLock(
           VOLUME_LOCK, volumeName);
 
-      final OmDBAccessIdInfo oldAccessIdInfo =
+      final OmDBAccessIdInfo dbAccessIdInfo =
           omMetadataManager.getTenantAccessIdTable().get(accessId);
 
-      if (oldAccessIdInfo == null) {
+      if (dbAccessIdInfo == null) {
         throw new OMException("OmDBAccessIdInfo entry is missing for accessId '"
-            + accessId + "'.", OMException.ResultCodes.METADATA_ERROR);
+            + accessId + "'", OMException.ResultCodes.METADATA_ERROR);
       }
 
-      assert (oldAccessIdInfo.getTenantId().equals(tenantId));
+      assert (dbAccessIdInfo.getTenantId().equals(tenantId));
 
       // Update tenantAccessIdTable
       final OmDBAccessIdInfo newOmDBAccessIdInfo =
           new OmDBAccessIdInfo.Builder()
-          .setTenantId(oldAccessIdInfo.getTenantId())
-          .setKerberosPrincipal(oldAccessIdInfo.getUserPrincipal())
-          .setIsAdmin(false)
-          .setIsDelegatedAdmin(false)
-          .build();
+              .setTenantId(dbAccessIdInfo.getTenantId())
+              .setUserPrincipal(dbAccessIdInfo.getUserPrincipal())
+              .setIsAdmin(false)
+              .setIsDelegatedAdmin(false)
+              .build();
       omMetadataManager.getTenantAccessIdTable().addCacheEntry(
           new CacheKey<>(accessId),
           new CacheValue<>(Optional.of(newOmDBAccessIdInfo),
               transactionLogIndex));
 
-      // Update tenantRoleTable?
-//      final String roleName = "role_admin";
-//      omMetadataManager.getTenantRoleTable().addCacheEntry(
-//          new CacheKey<>(accessId),
-//          new CacheValue<>(Optional.of(roleName), transactionLogIndex));
-
       omResponse.setTenantRevokeAdminResponse(
           TenantRevokeAdminResponse.newBuilder()
               .build());
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeUserAccessIdRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeUserAccessIdRequest.java
index e8f4f51..6105fc7 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeUserAccessIdRequest.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantRevokeUserAccessIdRequest.java
@@ -30,7 +30,7 @@ import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
 import org.apache.hadoop.ozone.om.request.OMClientRequest;
 import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
@@ -177,7 +177,7 @@ public class OMTenantRevokeUserAccessIdRequest extends OMClientRequest {
       assert (omDBAccessIdInfo != null);
       userPrincipal = omDBAccessIdInfo.getUserPrincipal();
       assert (userPrincipal != null);
-      OmDBKerberosPrincipalInfo principalInfo = omMetadataManager
+      OmDBUserPrincipalInfo principalInfo = omMetadataManager
           .getPrincipalToAccessIdsTable().getIfExist(userPrincipal);
       assert (principalInfo != null);
       principalInfo.removeAccessId(accessId);
@@ -193,16 +193,6 @@ public class OMTenantRevokeUserAccessIdRequest extends OMClientRequest {
           new CacheKey<>(accessId),
           new CacheValue<>(Optional.absent(), transactionLogIndex));
 
-      // Remove from tenantGroupTable
-      omMetadataManager.getTenantGroupTable().addCacheEntry(
-          new CacheKey<>(accessId),
-          new CacheValue<>(Optional.absent(), transactionLogIndex));
-
-      // Remove from tenantRoleTable
-      omMetadataManager.getTenantRoleTable().addCacheEntry(
-          new CacheKey<>(accessId),
-          new CacheValue<>(Optional.absent(), transactionLogIndex));
-
       // Remove from S3SecretTable.
       // Note: S3SecretTable will be deprecated in the future.
       acquiredS3SecretLock = omMetadataManager.getLock()
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignAdminResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignAdminResponse.java
index 7b5c4a4..710c74a 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignAdminResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignAdminResponse.java
@@ -36,7 +36,6 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ACCESS_ID_
  */
 @CleanupTableInfo(cleanupTables = {
     TENANT_ACCESS_ID_TABLE
-//    TENANT_ROLE_TABLE
 })
 public class OMTenantAssignAdminResponse extends OMClientResponse {
 
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignUserAccessIdResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignUserAccessIdResponse.java
index 50c5aa1..e2f273f 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignUserAccessIdResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantAssignUserAccessIdResponse.java
@@ -22,7 +22,7 @@ import com.google.common.annotations.VisibleForTesting;
 import org.apache.hadoop.hdds.utils.db.BatchOperation;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.response.CleanupTableInfo;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
@@ -35,8 +35,6 @@ import java.io.IOException;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.PRINCIPAL_TO_ACCESS_IDS_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.S3_SECRET_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ACCESS_ID_TABLE;
-import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_GROUP_TABLE;
-import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ROLE_TABLE;
 
 /**
  * Response for OMAssignUserToTenantRequest.
@@ -44,35 +42,29 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ROLE_TABLE
 @CleanupTableInfo(cleanupTables = {
     S3_SECRET_TABLE,
     TENANT_ACCESS_ID_TABLE,
-    PRINCIPAL_TO_ACCESS_IDS_TABLE,
-    TENANT_GROUP_TABLE,
-    TENANT_ROLE_TABLE
+    PRINCIPAL_TO_ACCESS_IDS_TABLE
 })
 public class OMTenantAssignUserAccessIdResponse extends OMClientResponse {
 
   private S3SecretValue s3SecretValue;
-  private String principal, groupName, roleName, accessId;
+  private String principal, accessId;
   private OmDBAccessIdInfo omDBAccessIdInfo;
-  private OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo;
+  private OmDBUserPrincipalInfo omDBUserPrincipalInfo;
 
   @SuppressWarnings("checkstyle:parameternumber")
   public OMTenantAssignUserAccessIdResponse(@Nonnull OMResponse omResponse,
       @Nonnull S3SecretValue s3SecretValue,
       @Nonnull String principal,
-      @Nonnull String groupName,
-      @Nonnull String roleName,
       @Nonnull String accessId,
       @Nonnull OmDBAccessIdInfo omDBAccessIdInfo,
-      @Nonnull OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo
+      @Nonnull OmDBUserPrincipalInfo omDBUserPrincipalInfo
   ) {
     super(omResponse);
     this.s3SecretValue = s3SecretValue;
     this.principal = principal;
-    this.groupName = groupName;
-    this.roleName = roleName;
     this.accessId = accessId;
     this.omDBAccessIdInfo = omDBAccessIdInfo;
-    this.omDBKerberosPrincipalInfo = omDBKerberosPrincipalInfo;
+    this.omDBUserPrincipalInfo = omDBUserPrincipalInfo;
   }
 
   /**
@@ -98,11 +90,7 @@ public class OMTenantAssignUserAccessIdResponse extends OMClientResponse {
     omMetadataManager.getTenantAccessIdTable().putWithBatch(
         batchOperation, accessId, omDBAccessIdInfo);
     omMetadataManager.getPrincipalToAccessIdsTable().putWithBatch(
-        batchOperation, principal, omDBKerberosPrincipalInfo);
-    omMetadataManager.getTenantGroupTable().putWithBatch(
-        batchOperation, accessId, groupName);
-    omMetadataManager.getTenantRoleTable().putWithBatch(
-        batchOperation, accessId, roleName);
+        batchOperation, principal, omDBUserPrincipalInfo);
   }
 
   @VisibleForTesting
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantCreateResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantCreateResponse.java
index abca5c5..11172cb 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantCreateResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantCreateResponse.java
@@ -21,7 +21,7 @@ package org.apache.hadoop.ozone.om.response.s3.tenant;
 import com.google.common.annotations.VisibleForTesting;
 import org.apache.hadoop.hdds.utils.db.BatchOperation;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.response.CleanupTableInfo;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
@@ -31,7 +31,6 @@ import org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos;
 import javax.annotation.Nonnull;
 import java.io.IOException;
 
-import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_POLICY_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_STATE_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.VOLUME_TABLE;
 
@@ -40,30 +39,23 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.VOLUME_TABLE;
  */
 @CleanupTableInfo(cleanupTables = {
     TENANT_STATE_TABLE,
-    TENANT_POLICY_TABLE,
     VOLUME_TABLE
 })
 public class OMTenantCreateResponse extends OMClientResponse {
 
   private OzoneManagerStorageProtos.PersistedUserVolumeInfo userVolumeInfo;
   private OmVolumeArgs omVolumeArgs;
-
-  private OmDBTenantInfo omTenantInfo;
-  private String userPolicyId, bucketPolicyId;
+  private OmDBTenantState omTenantState;
 
   public OMTenantCreateResponse(@Nonnull OMResponse omResponse,
       @Nonnull OmVolumeArgs omVolumeArgs,
       @Nonnull OzoneManagerStorageProtos.PersistedUserVolumeInfo userVolumeInfo,
-      @Nonnull OmDBTenantInfo omTenantInfo,
-      @Nonnull String userPolicyId,
-      @Nonnull String bucketPolicyId
+      @Nonnull OmDBTenantState omTenantState
   ) {
     super(omResponse);
     this.omVolumeArgs = omVolumeArgs;
     this.userVolumeInfo = userVolumeInfo;
-    this.omTenantInfo = omTenantInfo;
-    this.userPolicyId = userPolicyId;
-    this.bucketPolicyId = bucketPolicyId;
+    this.omTenantState = omTenantState;
   }
 
   /**
@@ -79,19 +71,9 @@ public class OMTenantCreateResponse extends OMClientResponse {
   public void addToDBBatch(OMMetadataManager omMetadataManager,
       BatchOperation batchOperation) throws IOException {
 
-    final String tenantId = omTenantInfo.getTenantId();
+    final String tenantId = omTenantState.getTenantId();
     omMetadataManager.getTenantStateTable().putWithBatch(
-        batchOperation, tenantId, omTenantInfo);
-
-    final String userPolicyGroupName =
-        omTenantInfo.getUserPolicyGroupName();
-    omMetadataManager.getTenantPolicyTable().putWithBatch(
-        batchOperation, userPolicyGroupName, userPolicyId);
-
-    final String bucketPolicyGroupName =
-        omTenantInfo.getBucketPolicyGroupName();
-    omMetadataManager.getTenantPolicyTable().putWithBatch(
-        batchOperation, bucketPolicyGroupName, bucketPolicyId);
+        batchOperation, tenantId, omTenantState);
 
     // From OMVolumeCreateResponse
     String dbVolumeKey =
@@ -106,7 +88,7 @@ public class OMTenantCreateResponse extends OMClientResponse {
   }
 
   @VisibleForTesting
-  public OmDBTenantInfo getOmDBTenantInfo() {
-    return omTenantInfo;
+  public OmDBTenantState getOmDBTenantState() {
+    return omTenantState;
   }
 }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantDeleteResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantDeleteResponse.java
index becbb16..6e7bddc 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantDeleteResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantDeleteResponse.java
@@ -30,7 +30,6 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import java.io.IOException;
 
-import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_POLICY_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_STATE_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.VOLUME_TABLE;
 
@@ -39,7 +38,6 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.VOLUME_TABLE;
  */
 @CleanupTableInfo(cleanupTables = {
     TENANT_STATE_TABLE,
-    TENANT_POLICY_TABLE,
     VOLUME_TABLE
 })
 public class OMTenantDeleteResponse extends OMClientResponse {
@@ -47,21 +45,15 @@ public class OMTenantDeleteResponse extends OMClientResponse {
   private String volumeName;
   private OmVolumeArgs omVolumeArgs;
   private String tenantId;
-  private String userPolicyGroupName;
-  private String bucketPolicyGroupName;
 
   public OMTenantDeleteResponse(@Nonnull OMResponse omResponse,
                                 @Nonnull String volumeName,
                                 @Nullable OmVolumeArgs omVolumeArgs,
-                                @Nonnull String tenantId,
-                                @Nonnull String userPolicyGroupName,
-                                @Nonnull String bucketPolicyGroupName) {
+                                @Nonnull String tenantId) {
     super(omResponse);
     this.volumeName = volumeName;
     this.omVolumeArgs = omVolumeArgs;
     this.tenantId = tenantId;
-    this.userPolicyGroupName = userPolicyGroupName;
-    this.bucketPolicyGroupName = bucketPolicyGroupName;
   }
 
   /**
@@ -80,12 +72,6 @@ public class OMTenantDeleteResponse extends OMClientResponse {
     omMetadataManager.getTenantStateTable().deleteWithBatch(
         batchOperation, tenantId);
 
-    omMetadataManager.getTenantPolicyTable().deleteWithBatch(
-        batchOperation, userPolicyGroupName);
-
-    omMetadataManager.getTenantPolicyTable().deleteWithBatch(
-        batchOperation, bucketPolicyGroupName);
-
     if (volumeName.length() > 0) {
       Preconditions.checkNotNull(omVolumeArgs);
       Preconditions.checkState(omVolumeArgs.getVolume().equals(volumeName));
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeAdminResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeAdminResponse.java
index d2faa36..71d9884 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeAdminResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeAdminResponse.java
@@ -36,7 +36,6 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ACCESS_ID_
  */
 @CleanupTableInfo(cleanupTables = {
     TENANT_ACCESS_ID_TABLE
-//    TENANT_ROLE_TABLE
 })
 public class OMTenantRevokeAdminResponse extends OMClientResponse {
 
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeUserAccessIdResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeUserAccessIdResponse.java
index 86b23cd..ff13722 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeUserAccessIdResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantRevokeUserAccessIdResponse.java
@@ -20,7 +20,7 @@ package org.apache.hadoop.ozone.om.response.s3.tenant;
 
 import org.apache.hadoop.hdds.utils.db.BatchOperation;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
-import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
 import org.apache.hadoop.ozone.om.response.CleanupTableInfo;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
@@ -32,8 +32,6 @@ import java.io.IOException;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.PRINCIPAL_TO_ACCESS_IDS_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.S3_SECRET_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ACCESS_ID_TABLE;
-import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_GROUP_TABLE;
-import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ROLE_TABLE;
 
 /**
  * Response for OMTenantRevokeUserAccessIdRequest.
@@ -41,25 +39,23 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ROLE_TABLE
 @CleanupTableInfo(cleanupTables = {
     S3_SECRET_TABLE,
     TENANT_ACCESS_ID_TABLE,
-    PRINCIPAL_TO_ACCESS_IDS_TABLE,
-    TENANT_GROUP_TABLE,
-    TENANT_ROLE_TABLE
+    PRINCIPAL_TO_ACCESS_IDS_TABLE
 })
 public class OMTenantRevokeUserAccessIdResponse extends OMClientResponse {
 
   private String principal, accessId;
-  private OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo;
+  private OmDBUserPrincipalInfo omDBUserPrincipalInfo;
 
   @SuppressWarnings("checkstyle:parameternumber")
   public OMTenantRevokeUserAccessIdResponse(@Nonnull OMResponse omResponse,
       @Nonnull String accessId,
       @Nonnull String principal,
-      @Nonnull OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo
+      @Nonnull OmDBUserPrincipalInfo omDBUserPrincipalInfo
   ) {
     super(omResponse);
     this.principal = principal;
     this.accessId = accessId;
-    this.omDBKerberosPrincipalInfo = omDBKerberosPrincipalInfo;
+    this.omDBUserPrincipalInfo = omDBUserPrincipalInfo;
   }
 
   /**
@@ -84,14 +80,10 @@ public class OMTenantRevokeUserAccessIdResponse extends OMClientResponse {
 
     omMetadataManager.getTenantAccessIdTable().deleteWithBatch(
         batchOperation, accessId);
-    omMetadataManager.getTenantGroupTable().deleteWithBatch(
-        batchOperation, accessId);
-    omMetadataManager.getTenantRoleTable().deleteWithBatch(
-        batchOperation, accessId);
 
-    if (omDBKerberosPrincipalInfo.getAccessIds().size() > 0) {
+    if (omDBUserPrincipalInfo.getAccessIds().size() > 0) {
       omMetadataManager.getPrincipalToAccessIdsTable().putWithBatch(
-          batchOperation, principal, omDBKerberosPrincipalInfo);
+          batchOperation, principal, omDBUserPrincipalInfo);
     } else {
       // Remove entry from DB if accessId set is empty
       omMetadataManager.getPrincipalToAccessIdsTable().deleteWithBatch(
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
index 3cad217..34574f3 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
@@ -41,7 +41,7 @@ import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.ratis.OzoneManagerDoubleBuffer;
@@ -386,7 +386,7 @@ public class OzoneManagerRequestHandler implements RequestHandler {
     TenantUserInfoValue ret = impl.tenantGetUserInfo(userPrincipal);
     // Note impl.tenantGetUserInfo() throws if errs
     if (ret != null) {
-      resp.setTenantUserInfo(ret.getProtobuf());
+      resp.addAllAccessIdInfo(ret.getAccessIdInfoList());
     }
 
     return resp.build();
@@ -401,7 +401,6 @@ public class OzoneManagerRequestHandler implements RequestHandler {
         impl.listUsersInTenant(request.getTenantId(), request.getPrefix());
     // Note impl.listUsersInTenant() throws if errs
     if (usersInTenant != null) {
-      builder.setTenantId(request.getTenantId());
       builder.addAllUserAccessIdInfo(usersInTenant.getUserAccessIds());
     }
     return builder.build();
@@ -413,8 +412,8 @@ public class OzoneManagerRequestHandler implements RequestHandler {
 
     final ListTenantResponse.Builder resp = ListTenantResponse.newBuilder();
 
-    TenantInfoList ret = impl.listTenant();
-    resp.addAllTenantInfo(ret.getTenantInfoList());
+    TenantStateList ret = impl.listTenant();
+    resp.addAllTenantState(ret.getTenantStateList());
 
     return resp.build();
   }
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOMMultiTenantManagerImpl.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOMMultiTenantManagerImpl.java
index 0b74355..f2ea4af 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOMMultiTenantManagerImpl.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOMMultiTenantManagerImpl.java
@@ -28,12 +28,11 @@ import java.util.List;
 import com.google.common.base.Optional;
 
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
-import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
-import org.apache.hadoop.ozone.om.helpers.OmDBTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBTenantState;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantUserAccessId;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserAccessIdInfo;
 import org.apache.http.auth.BasicUserPrincipal;
 import org.apache.ozone.test.LambdaTestUtils;
 import org.junit.Assert;
@@ -41,6 +40,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import org.mockito.Mockito;
 
 /**
  * Tests for Multi Tenant Manager APIs.
@@ -62,22 +62,28 @@ public class TestOMMultiTenantManagerImpl {
     OMMetadataManager omMetadataManager = new OmMetadataManagerImpl(conf);
 
     final String bucketNamespaceName = tenantName;
-    final String accountNamespaceName = tenantName;
-    final String userPolicyGroupName =
-        tenantName + OzoneConsts.DEFAULT_TENANT_USER_POLICY_SUFFIX;
-    final String bucketPolicyGroupName =
-        tenantName + OzoneConsts.DEFAULT_TENANT_BUCKET_POLICY_SUFFIX;
-
-    final OmDBTenantInfo omDBTenantInfo = new OmDBTenantInfo(
-        tenantName, bucketNamespaceName, accountNamespaceName,
-        userPolicyGroupName, bucketPolicyGroupName);
-    omMetadataManager.getTenantStateTable().put(tenantName, omDBTenantInfo);
+    final String bucketNamespacePolicyName =
+        OMMultiTenantManager.getDefaultBucketNamespacePolicyName(tenantName);
+    final String bucketPolicyName =
+        OMMultiTenantManager.getDefaultBucketPolicyName(tenantName);
+    final String userRoleName =
+        OMMultiTenantManager.getDefaultUserRoleName(tenantName);
+    final String adminRoleName =
+        OMMultiTenantManager.getDefaultAdminRoleName(tenantName);
+    final OmDBTenantState omDBTenantState = new OmDBTenantState(
+        tenantName, bucketNamespaceName, userRoleName, adminRoleName,
+        bucketNamespacePolicyName, bucketPolicyName);
+
+    omMetadataManager.getTenantStateTable().put(tenantName, omDBTenantState);
 
     omMetadataManager.getTenantAccessIdTable().put("seed-accessId1",
-        new OmDBAccessIdInfo(tenantName, "seed-user1",
-            false, false));
+        new OmDBAccessIdInfo(tenantName, "seed-user1", false, false));
+
+    OzoneManager ozoneManager = Mockito.mock(OzoneManager.class);
+    Mockito.when(ozoneManager.getMetadataManager())
+        .thenReturn(omMetadataManager);
 
-    tenantManager = new OMMultiTenantManagerImpl(omMetadataManager, conf);
+    tenantManager = new OMMultiTenantManagerImpl(ozoneManager, conf);
     assertEquals(1, tenantManager.getTenantCache().size());
     assertEquals(1,
         tenantManager.getTenantCache().get(tenantName).getTenantUsers().size());
@@ -91,10 +97,10 @@ public class TestOMMultiTenantManagerImpl {
 
     TenantUserList tenantUserList =
         tenantManager.listUsersInTenant(tenantName, "");
-    List<TenantUserAccessId> userAccessIds = tenantUserList.getUserAccessIds();
+    List<UserAccessIdInfo> userAccessIds = tenantUserList.getUserAccessIds();
     assertEquals(2, userAccessIds.size());
 
-    for (TenantUserAccessId userAccessId : userAccessIds) {
+    for (final UserAccessIdInfo userAccessId : userAccessIds) {
       String user = userAccessId.getUserPrincipal();
       if (user.equals("user1")) {
         assertEquals("accessId1", userAccessId.getAccessId());
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
index 4813254..b6899c0 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
@@ -329,6 +329,9 @@ public class TestS3GetSecretRequest {
 
     // This effectively makes alice an admin.
     when(ozoneManager.isAdmin(ugiAlice)).thenReturn(true);
+    when(omMultiTenantManager.isTenantAdmin(ugiAlice, TENANT_ID, true))
+        .thenReturn(true);
+
     // Init LayoutVersionManager to prevent NPE in checkLayoutFeature
     final OMLayoutVersionManager lvm =
         new OMLayoutVersionManager(OMLayoutVersionManager.maxLayoutVersion());
@@ -354,13 +357,13 @@ public class TestS3GetSecretRequest {
     // Check response
     Assert.assertTrue(omTenantCreateResponse.getOMResponse().getSuccess());
     Assert.assertEquals(TENANT_ID,
-        omTenantCreateResponse.getOmDBTenantInfo().getTenantId());
+        omTenantCreateResponse.getOmDBTenantState().getTenantId());
 
 
     // 2. AssignUserToTenantRequest: Assign "bob@EXAMPLE.COM" to "finance".
     ++txLogIndex;
 
-    // Additional mock setup needed for pass accessId check
+    // Additional mock setup needed to pass accessId check
     when(ozoneManager.getMultiTenantManager()).thenReturn(omMultiTenantManager);
     when(omMultiTenantManager.getDefaultAccessId(TENANT_ID, USER_BOB))
         .thenReturn(ACCESS_ID_BOB);
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java
index dfc28a5..6c816cb 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java
@@ -21,7 +21,7 @@ import org.apache.hadoop.hdds.cli.GenericCli;
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneClient;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantAccessIdInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ExtendedUserAccessIdInfo;
 import org.apache.hadoop.ozone.shell.OzoneAddress;
 import picocli.CommandLine;
 
@@ -61,7 +61,7 @@ public class GetUserInfoHandler extends TenantHandler {
       try {
         final TenantUserInfoValue tenantUserInfo =
             objStore.tenantGetUserInfo(userPrincipal);
-        List<TenantAccessIdInfo> accessIdInfoList =
+        List<ExtendedUserAccessIdInfo> accessIdInfoList =
             tenantUserInfo.getAccessIdInfoList();
         if (accessIdInfoList.size() == 0) {
           err().println("User '" + userPrincipal +
@@ -70,7 +70,7 @@ public class GetUserInfoHandler extends TenantHandler {
         }
         out().println("User '" + userPrincipal + "' is assigned to:");
 
-        for (TenantAccessIdInfo accessIdInfo : accessIdInfoList) {
+        for (ExtendedUserAccessIdInfo accessIdInfo : accessIdInfoList) {
           // Get admin info
           final String adminInfoString;
           if (accessIdInfo.getIsAdmin()) {
@@ -80,7 +80,8 @@ public class GetUserInfoHandler extends TenantHandler {
             adminInfoString = "";
           }
           out().format("- Tenant '%s'%s with accessId '%s'%n",
-              accessIdInfo.getTenantId(), adminInfoString,
+              accessIdInfo.getTenantId(),
+              adminInfoString,
               accessIdInfo.getAccessId());
         }
 
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
index 0248578..22c3cb2 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
@@ -18,7 +18,7 @@
 package org.apache.hadoop.ozone.shell.tenant;
 
 import org.apache.hadoop.ozone.client.OzoneClient;
-import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantState;
 import org.apache.hadoop.ozone.shell.OzoneAddress;
 import picocli.CommandLine;
 
@@ -41,7 +41,7 @@ public class TenantDeleteHandler extends TenantHandler {
   protected void execute(OzoneClient client, OzoneAddress address)
       throws IOException {
     try {
-      final DeleteTenantInfo resp =
+      final DeleteTenantState resp =
           client.getObjectStore().deleteTenant(tenantId);
       out().println("Deleted tenant '" + tenantId + "'.");
       long volumeRefCount = resp.getVolRefCount();
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java
index 51d4fc1..1661781 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java
@@ -19,7 +19,7 @@ package org.apache.hadoop.ozone.shell.tenant;
 
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneClient;
-import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
+import org.apache.hadoop.ozone.om.helpers.TenantStateList;
 import org.apache.hadoop.ozone.shell.OzoneAddress;
 import picocli.CommandLine;
 
@@ -52,32 +52,35 @@ public class TenantListHandler extends TenantHandler {
   protected void execute(OzoneClient client, OzoneAddress address) {
     final ObjectStore objStore = client.getObjectStore();
     try {
-      TenantInfoList tenantInfoList = objStore.listTenant();
+      TenantStateList tenantStateList = objStore.listTenant();
 
       if (printHeader) {
-        // default console width 80 / 5 = 16. +1 for extra room. Change later?
-        out().format(longFormat ? "%-17s" : "%s%n",
+        // Assuming default terminal width 120 / 6 ~= 20. +1 for space
+        out().format(longFormat ? "%-21s" : "%s%n",
             "Tenant");
         if (longFormat) {
-          out().format("%-17s%-17s%-17s%s%n",
+          out().format("%-21s%-21s%-21s%-21s%s%n",
               "BucketNS",
-              "AccountNS",
-              "UserPolicy",
+              "UserRole",
+              "AdminRole",
+              "BucketNSPolicy",
               "BucketPolicy");
         }
       }
 
-      tenantInfoList.getTenantInfoList().forEach(tenantInfo -> {
-        out().format(longFormat ? "%-17s" : "%s%n",
-            tenantInfo.getTenantId());
+      tenantStateList.getTenantStateList().forEach(tenantState -> {
+        out().format(longFormat ? "%-21s" : "%s%n",
+            tenantState.getTenantId());
         if (longFormat) {
-          out().format("%-17s%-17s%-17s%s%n",
-              tenantInfo.getBucketNamespaceName(),
-              tenantInfo.getAccountNamespaceName(),
-              tenantInfo.getUserPolicyGroupName(),
-              tenantInfo.getBucketPolicyGroupName());
+          out().format("%-21s%-21s%-21s%-21s%s%n",
+              tenantState.getBucketNamespaceName(),
+              tenantState.getUserRoleName(),
+              tenantState.getAdminRoleName(),
+              tenantState.getBucketNamespacePolicyName(),
+              tenantState.getBucketPolicyName());
         }
       });
+
     } catch (IOException e) {
       LOG.error("Failed to list tenants: {}", e.getMessage());
     }
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java
index e51d187..71acded 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java
@@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneClient;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantUserAccessId;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserAccessIdInfo;
 import org.apache.hadoop.ozone.shell.OzoneAddress;
 import org.apache.hadoop.ozone.shell.s3.S3Handler;
 
@@ -62,7 +62,7 @@ public class TenantListUsersHandler extends S3Handler {
     try {
       TenantUserList usersInTenant =
           objStore.listUsersInTenant(tenantId, prefix);
-      for (TenantUserAccessId accessIdInfo : usersInTenant.getUserAccessIds()) {
+      for (UserAccessIdInfo accessIdInfo : usersInTenant.getUserAccessIds()) {
         out().println("- User '" + accessIdInfo.getUserPrincipal() +
             "' with accessId '" + accessIdInfo.getAccessId() + "'");
       }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org