[authorization] Remove the Sentry integration

As discussed on the dev mailing list. This patch removes Sentry now
that Kudu 1.12.0 is released. This will allow upgrading the HMS
inegration Hive dependency to 3+.

In the authorization tests that used a HarnessEnum including Sentry
I left the enum to simplify adding any variants in the future.

Change-Id: If40a6f2c88721ff3721cf148a9c609102705ae8b
Reviewed-on: http://gerrit.cloudera.org:8080/15880
Tested-by: Kudu Jenkins
Reviewed-by: Hao Hao <hao.hao@cloudera.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d2bb441..077305b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1322,7 +1322,7 @@
 ############################################################
 if (UNIX)
   add_custom_target(generated-headers
-    DEPENDS pb-gen krpc-gen hms_thrift sentry_thrift gen_version_info)
+    DEPENDS pb-gen krpc-gen hms_thrift gen_version_info)
 endif (UNIX)
 
 ############################################################
@@ -1439,7 +1439,6 @@
 add_subdirectory(src/kudu/rebalance)
 add_subdirectory(src/kudu/rpc)
 add_subdirectory(src/kudu/security)
-add_subdirectory(src/kudu/sentry)
 add_subdirectory(src/kudu/server)
 add_subdirectory(src/kudu/subprocess)
 add_subdirectory(src/kudu/tablet)
diff --git a/build-support/dist_test.py b/build-support/dist_test.py
index aa20d70..1696ea8 100755
--- a/build-support/dist_test.py
+++ b/build-support/dist_test.py
@@ -102,13 +102,12 @@
      # Tests that require tooling require this.
      "build/latest/bin/kudu",
 
-     # The HMS and Sentry tests require the Hadoop, Hive, and Sentry libraries.
+     # The HMS tests require the Hadoop, and Hive libraries.
      # These files are just symlinks, but dist-test will copy the entire
      # directories they point to. The symlinks themselves won't be recreated,
      # so we point to them with environment variables in run_dist_test.py.
      "build/latest/bin/hive-home",
      "build/latest/bin/hadoop-home",
-     "build/latest/bin/sentry-home",
 
      # Add the Kudu echo subprocess.
      "build/latest/bin/kudu-subprocess.jar",
diff --git a/build-support/run_dist_test.py b/build-support/run_dist_test.py
index cfb2c75..cca701b 100755
--- a/build-support/run_dist_test.py
+++ b/build-support/run_dist_test.py
@@ -147,10 +147,9 @@
       env[var_name] = os.environ.get(var_name, "") + " external_symbolizer_path=" + symbolizer_path
 
   # Add environment variables for Java dependencies. These environment variables
-  # are used in mini_hms.cc and mini_sentry.cc.
+  # are used in mini_hms.cc and mini_ranger.cc.
   env['HIVE_HOME'] = glob.glob(os.path.join(ROOT, "thirdparty/src/hive-*"))[0]
   env['HADOOP_HOME'] = glob.glob(os.path.join(ROOT, "thirdparty/src/hadoop-*"))[0]
-  env['SENTRY_HOME'] = glob.glob(os.path.join(ROOT, "thirdparty/src/sentry-*"))[0]
   env['RANGER_HOME'] = glob.glob(os.path.join(ROOT, "thirdparty/src/ranger-*"))[0]
   env['JAVA_HOME'] = glob.glob("/usr/lib/jvm/java-1.8.0-*")[0]
 
diff --git a/src/kudu/hms/mini_hms.cc b/src/kudu/hms/mini_hms.cc
index ad63331..fefe53c 100644
--- a/src/kudu/hms/mini_hms.cc
+++ b/src/kudu/hms/mini_hms.cc
@@ -70,19 +70,6 @@
   protection_ = protection;
 }
 
-void MiniHms::EnableSentry(const HostPort& sentry_address,
-                           string sentry_service_principal,
-                           int sentry_client_rpc_retry_num,
-                           int sentry_client_rpc_retry_interval_ms) {
-  CHECK(!hms_process_);
-  DCHECK(!sentry_service_principal.empty());
-  VLOG(1) << Substitute("Enabling Sentry, at $0, for HMS", sentry_address.ToString());
-  sentry_address_ = sentry_address.ToString();
-  sentry_service_principal_ = std::move(sentry_service_principal);
-  sentry_client_rpc_retry_num_ = sentry_client_rpc_retry_num;
-  sentry_client_rpc_retry_interval_ms_ = sentry_client_rpc_retry_interval_ms;
-}
-
 void MiniHms::EnableKuduPlugin(bool enable) {
   enable_kudu_plugin_ = enable;
 }
@@ -107,11 +94,9 @@
   string hadoop_home;
   string hive_home;
   string java_home;
-  string sentry_home;
   RETURN_NOT_OK(FindHomeDir("hadoop", bin_dir, &hadoop_home));
   RETURN_NOT_OK(FindHomeDir("hive", bin_dir, &hive_home));
   RETURN_NOT_OK(FindHomeDir("java", bin_dir, &java_home));
-  RETURN_NOT_OK(FindHomeDir("sentry", bin_dir, &sentry_home));
 
   if (data_root_.empty()) {
     data_root_ = GetTestDataDirectory();
@@ -122,9 +107,9 @@
   RETURN_NOT_OK(CreateLogConfig());
 
   // Comma-separated list of additional jars to add to the HMS classpath, including
-  // the HMS plugins of Kudu and Sentry.
-  string aux_jars = Substitute("$0/hms-plugin.jar,$1/hcatalog/share/hcatalog/*,$2/lib/*",
-                               bin_dir, hive_home, sentry_home);
+  // the Kudu HMS plugins.
+  string aux_jars = Substitute("$0/hms-plugin.jar,$1/hcatalog/share/hcatalog/*",
+                               bin_dir, hive_home);
 
   // List of JVM environment options to pass to the HMS.
   string java_options =
@@ -220,10 +205,6 @@
   return Substitute("thrift://127.0.0.1:$0", port_);
 }
 
-bool MiniHms::IsAuthorizationEnabled() const {
-  return !sentry_address_.empty() && IsKerberosEnabled();
-}
-
 Status MiniHms::CreateHiveSite() const {
 
   const string listeners = Substitute("org.apache.hive.hcatalog.listener.DbNotificationListener$0",
@@ -273,7 +254,7 @@
 
   <property>
     <name>javax.jdo.option.ConnectionURL</name>
-    <value>jdbc:derby:$2/$9;create=true</value>
+    <value>jdbc:derby:$2/$8;create=true</value>
   </property>
 
   <property>
@@ -325,57 +306,9 @@
     <name>hive.log4j.file</name>
     <value>$7</value>
   </property>
-
-  $8
 </configuration>
   )";
 
-  string sentry_properties;
-  if (IsAuthorizationEnabled()) {
-
-    // - hive.sentry.conf.url
-    //     Configuration URL of the Sentry authorization plugin in the HMS.
-    //
-    // - hive.metastore.filter.hook
-    //     Configures the HMS to use the Sentry plugin for filtering
-    //     out information user has no privileges to access for operations
-    //     as SHOWTABLES and SHOWDATABASES.
-    //
-    // - hive.metastore.pre.event.listeners
-    //     Configures the HMS to use the Sentry event listener to
-    //     consult Sentry service for authorization metadata when servicing
-    //     requests.
-    //
-    // - hive.metastore.event.listeners
-    //     Configures the HMS to use the Sentry post-event listener, which
-    //     synchronizes the HMS events with the Sentry service. The Sentry
-    //     service will be made aware of events like table renames and
-    //     update itself accordingly.
-    static const string kHiveSentryFileTemplate = R"(
-<property>
-  <name>hive.sentry.conf.url</name>
-  <value>file://$0/hive-sentry-site.xml</value>
-</property>
-
-<property>
-  <name>hive.metastore.filter.hook</name>
-  <value>org.apache.sentry.binding.metastore.SentryMetaStoreFilterHook</value>
-</property>
-
-<property>
-  <name>hive.metastore.pre.event.listeners</name>
-  <value>org.apache.sentry.binding.metastore.MetastoreAuthzBinding</value>
-</property>
-
-<property>
-  <name>hive.metastore.event.listeners</name>
-  <value>org.apache.sentry.binding.metastore.SentrySyncHMSNotificationsPostEventListener</value>
-</property>
-    )";
-
-    sentry_properties = Substitute(kHiveSentryFileTemplate, data_root_);
-  }
-
   string hive_file_contents = Substitute(kHiveFileTemplate,
                                          listeners,
                                          notification_log_ttl_.ToSeconds(),
@@ -385,70 +318,8 @@
                                          service_principal_,
                                          SaslProtection::name_of(protection_),
                                          JoinPathSegments(data_root_, "hive-log4j2.properties"),
-                                         sentry_properties,
                                          metadb_subdir_);
 
-  if (IsAuthorizationEnabled()) {
-    // - hive.sentry.server
-    //     Server namespace the HMS instance belongs to for defining
-    //     server-level privileges in Sentry.
-    //
-    // - sentry.metastore.service.users
-    //     Set of service users whose access will be excluded from
-    //     Sentry authorization checks.
-    //
-    // - sentry.service.client.rpc.retry-total
-    //     Maximum number of attempts that Sentry RPC client does while
-    //     re-trying a remote call to Sentry.
-    //
-    // - sentry.service.client.rpc.retry.interval.msec
-    //     Time interval between attempts of Sentry's client to retry a remote
-    //     call to Sentry.
-    static const string kSentryFileTemplate = R"(
-<configuration>
-  <property>
-    <name>sentry.service.client.server.rpc-addresses</name>
-    <value>$0</value>
-  </property>
-
-  <property>
-    <name>sentry.service.server.principal</name>
-    <value>$1</value>
-  </property>
-
-  <property>
-    <name>hive.sentry.server</name>
-    <value>$2</value>
-  </property>
-
-  <property>
-    <name>sentry.metastore.service.users</name>
-    <value>kudu</value>
-  </property>
-
-  <property>
-    <name>sentry.service.client.rpc.retry-total</name>
-    <value>$3</value>
-  </property>
-
-  <property>
-    <name>sentry.service.client.rpc.retry.interval.msec</name>
-    <value>$4</value>
-  </property>
-</configuration>
-  )";
-    auto sentry_file_contents = Substitute(
-        kSentryFileTemplate,
-        sentry_address_,
-        sentry_service_principal_,
-        "server1",
-        sentry_client_rpc_retry_num_,
-        sentry_client_rpc_retry_interval_ms_);
-    RETURN_NOT_OK(WriteStringToFile(Env::Default(),
-                                    sentry_file_contents,
-                                    JoinPathSegments(data_root_, "hive-sentry-site.xml")));
-  }
-
   return WriteStringToFile(Env::Default(),
                            hive_file_contents,
                            JoinPathSegments(data_root_, "hive-site.xml"));
diff --git a/src/kudu/hms/mini_hms.h b/src/kudu/hms/mini_hms.h
index 666d05a..1dc64d6 100644
--- a/src/kudu/hms/mini_hms.h
+++ b/src/kudu/hms/mini_hms.h
@@ -46,19 +46,6 @@
                       std::string keytab_file,
                       rpc::SaslProtection::Type protection);
 
-  // Configures the mini HMS to enable the Sentry plugin, passing the
-  // Sentry service's principal to be used in Kerberos environment.
-  //
-  // Parameters 'sentry_client_rpc_retry_num' and
-  // 'sentry_client_rpc_retry_interval_ms' are used to override default settings
-  // of the Sentry client used by HMS plugins. The default values for these two
-  // parameters are set to allow for shorter HMS --> Sentry RPC timeout
-  // (i.e. shorter than with the default Sentry v2.{0,1} client's settings).
-  void EnableSentry(const HostPort& sentry_address,
-                    std::string sentry_service_principal,
-                    int sentry_client_rpc_retry_num = 3,
-                    int sentry_client_rpc_retry_interval_ms = 500);
-
   // Configures the mini HMS to enable or disable the Kudu plugin.
   void EnableKuduPlugin(bool enable);
 
@@ -91,9 +78,6 @@
   // hive.metastore.uris configuration expects.
   std::string uris() const;
 
-  // Returns true when Sentry as well as Kerberos is enabled.
-  bool IsAuthorizationEnabled() const;
-
   // Returns true when Kerberos is enabled.
   bool IsKerberosEnabled() const {
     return !keytab_file_.empty();
@@ -124,12 +108,6 @@
   std::string keytab_file_;
   rpc::SaslProtection::Type protection_ = rpc::SaslProtection::kAuthentication;
 
-  // Sentry configuration
-  std::string sentry_address_;
-  std::string sentry_service_principal_;
-  int sentry_client_rpc_retry_num_;
-  int sentry_client_rpc_retry_interval_ms_;
-
   // Whether to enable the Kudu listener plugin.
   bool enable_kudu_plugin_ = true;
 };
diff --git a/src/kudu/integration-tests/alter_table-randomized-test.cc b/src/kudu/integration-tests/alter_table-randomized-test.cc
index f845358..2d00231 100644
--- a/src/kudu/integration-tests/alter_table-randomized-test.cc
+++ b/src/kudu/integration-tests/alter_table-randomized-test.cc
@@ -42,10 +42,8 @@
 #include "kudu/gutil/stl_util.h"
 #include "kudu/gutil/strings/join.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/cluster_verifier.h"
 #include "kudu/mini-cluster/external_mini_cluster.h"
-#include "kudu/sentry/mini_sentry.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/random.h"
 #include "kudu/util/status.h"
@@ -68,7 +66,6 @@
 using kudu::client::sp::shared_ptr;
 using kudu::cluster::ExternalMiniCluster;
 using kudu::cluster::ExternalMiniClusterOptions;
-using kudu::itest::SentryMode;
 using std::make_pair;
 using std::map;
 using std::pair;
@@ -96,19 +93,16 @@
 const vector<int32_t> kBlockSizes = {0, 2 * 1024 * 1024,
                                      4 * 1024 * 1024, 8 * 1024 * 1024};
 
-// Parameterized based on HmsMode and whether or not to enable Sentry integration.
+// Parameterized based on HmsMode.
 class AlterTableRandomized : public KuduTest,
-                             public ::testing::WithParamInterface<pair<HmsMode, SentryMode>> {
+                             public ::testing::WithParamInterface<HmsMode> {
  public:
   void SetUp() override {
     KuduTest::SetUp();
 
     ExternalMiniClusterOptions opts;
     opts.num_tablet_servers = 3;
-    opts.hms_mode = std::get<0>(GetParam());
-    bool enable_sentry = (std::get<1>(GetParam()) == SentryMode::ENABLED);
-    opts.enable_sentry = enable_sentry;
-    opts.enable_kerberos = enable_sentry;
+    opts.hms_mode = GetParam();
     // This test produces tables with lots of columns. With container preallocation,
     // we end up using quite a bit of disk space. So, we disable it.
     opts.extra_tserver_flags.emplace_back("--log_container_preallocate_bytes=0");
@@ -116,10 +110,6 @@
     ASSERT_OK(cluster_->Start());
 
     ASSERT_OK(cluster_->CreateClient(nullptr, &client_));
-    if (enable_sentry) {
-      itest::SetupAdministratorPrivileges(cluster_->kdc(),
-                                          cluster_->sentry()->address());
-    }
   }
 
   void TearDown() override {
@@ -150,14 +140,9 @@
   shared_ptr<KuduClient> client_;
 };
 
-// Run the test with the HMS/Sentry integration enabled and disabled. Sentry integration
-// should be only enabled when HMS integration is enabled.
-INSTANTIATE_TEST_CASE_P(HmsSentryConfigurations, AlterTableRandomized, ::testing::ValuesIn(
-    vector<pair<HmsMode, SentryMode>> {
-      { HmsMode::NONE, SentryMode::DISABLED },
-      { HmsMode::ENABLE_METASTORE_INTEGRATION, SentryMode::DISABLED },
-      { HmsMode::ENABLE_METASTORE_INTEGRATION, SentryMode::ENABLED },
-    }
+// Run the test with the HMS integration enabled and disabled.
+INSTANTIATE_TEST_CASE_P(HmsConfigurations, AlterTableRandomized, ::testing::ValuesIn(
+    vector<HmsMode> { HmsMode::NONE, HmsMode::ENABLE_METASTORE_INTEGRATION }
 ));
 
 struct RowState {
diff --git a/src/kudu/integration-tests/cluster_itest_util.cc b/src/kudu/integration-tests/cluster_itest_util.cc
index 8975d41..0e8551e 100644
--- a/src/kudu/integration-tests/cluster_itest_util.cc
+++ b/src/kudu/integration-tests/cluster_itest_util.cc
@@ -46,15 +46,10 @@
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
-#include "kudu/master/sentry_authz_provider-test-base.h"
 #include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/rpc/rpc_header.pb.h"
-#include "kudu/security/test/mini_kdc.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
 #include "kudu/tablet/tablet.pb.h"
-#include "kudu/thrift/client.h"
 #include "kudu/tserver/tablet_copy.proxy.h"
 #include "kudu/tserver/tablet_server_test_util.h"
 #include "kudu/tserver/tserver_admin.pb.h"
@@ -72,8 +67,6 @@
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
 
-using ::sentry::TSentryGrantOption;
-using ::sentry::TSentryPrivilege;
 using boost::optional;
 using kudu::client::KuduSchema;
 using kudu::client::KuduSchemaBuilder;
@@ -105,7 +98,6 @@
 using kudu::pb_util::SecureShortDebugString;
 using kudu::rpc::Messenger;
 using kudu::rpc::RpcController;
-using kudu::sentry::SentryClient;
 using kudu::tablet::TabletDataState;
 using kudu::tserver::CreateTsClientProxies;
 using kudu::tserver::ListTabletsResponsePB;
@@ -1335,28 +1327,6 @@
                         value);
 }
 
-Status SetupAdministratorPrivileges(MiniKdc* kdc,
-                                    const HostPort& address) {
-  DCHECK(kdc);
-  RETURN_NOT_OK(kdc->CreateUserPrincipal("kudu"));
-  RETURN_NOT_OK(kdc->Kinit("kudu"));
-
-  thrift::ClientOptions sentry_opts;
-  sentry_opts.service_principal = "sentry";
-  sentry_opts.enable_kerberos = true;
-  unique_ptr<SentryClient> sentry_client(
-      new SentryClient(address, sentry_opts));
-  RETURN_NOT_OK(sentry_client->Start());
-
-  // Create an admin role for the "admin" group specified in mini_sentry.cc.
-  // Grant this role all privileges for the server so the admin user can
-  // perform any operations required in tests.
-  RETURN_NOT_OK(master::CreateRoleAndAddToGroups(sentry_client.get(), "admin-role", "admin"));
-  TSentryPrivilege privilege = master::GetServerPrivilege("ALL", TSentryGrantOption::DISABLED);
-  RETURN_NOT_OK(master::AlterRoleGrantPrivilege(sentry_client.get(), "admin-role", privilege));
-  return kdc->Kinit("test-admin");
-}
-
 Status AlterTableName(const shared_ptr<MasterServiceProxy>& master_proxy,
                       const string& table_id,
                       const string& old_table_name,
diff --git a/src/kudu/integration-tests/cluster_itest_util.h b/src/kudu/integration-tests/cluster_itest_util.h
index 232095f..404af90 100644
--- a/src/kudu/integration-tests/cluster_itest_util.h
+++ b/src/kudu/integration-tests/cluster_itest_util.h
@@ -50,7 +50,6 @@
 class HostPort;
 class MetricEntityPrototype;
 class MetricPrototype;
-class MiniKdc;
 class MonoDelta;
 class Status;
 
@@ -76,12 +75,6 @@
 
 namespace itest {
 
-// Mode to indicate whether external service Sentry is enabled or not.
-enum class SentryMode {
-  DISABLED,
-  ENABLED
-};
-
 struct TServerDetails {
   NodeInstancePB instance_id;
   ServerRegistrationPB registration;
@@ -462,12 +455,6 @@
                          MetricPrototype* metric,
                          int64_t* value);
 
-// Grants the 'test-admin' user Sentry privileges to perform any operation,
-// using 'kdc' to authenticate with the Sentry instance at 'address'. Once
-// called, the 'test-admin' user will be logged in.
-Status SetupAdministratorPrivileges(MiniKdc* kdc,
-                                    const HostPort& address);
-
 // Alter the table name.
 Status AlterTableName(const std::shared_ptr<master::MasterServiceProxy>& master_proxy,
                       const std::string& table_id,
diff --git a/src/kudu/integration-tests/master-stress-test.cc b/src/kudu/integration-tests/master-stress-test.cc
index f8f0b0d..d5b075e 100644
--- a/src/kudu/integration-tests/master-stress-test.cc
+++ b/src/kudu/integration-tests/master-stress-test.cc
@@ -16,6 +16,7 @@
 // under the License.
 
 #include <cstdint>
+#include <functional>
 #include <memory>
 #include <mutex>
 #include <ostream>
@@ -47,8 +48,8 @@
 #include "kudu/master/master.proxy.h"
 #include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
+#include "kudu/rpc/response_callback.h"
 #include "kudu/rpc/rpc_controller.h"
-#include "kudu/sentry/mini_sentry.h"
 #include "kudu/tablet/tablet.pb.h"
 #include "kudu/thrift/client.h"
 #include "kudu/tools/tool_action_common.h"
@@ -91,7 +92,6 @@
 using kudu::cluster::ExternalMiniClusterOptions;
 using kudu::hms::HmsClient;
 using kudu::itest::ListTablets;
-using kudu::itest::SentryMode;
 using kudu::master::ListTablesRequestPB;
 using kudu::master::ListTablesResponsePB;
 using kudu::master::ReplaceTabletRequestPB;
@@ -114,9 +114,9 @@
 static const MonoDelta kDefaultAdminTimeout = MonoDelta::FromSeconds(300);
 static const MonoDelta kTransientStateBackoff = MonoDelta::FromMilliseconds(50);
 
-// Parameterized based on HmsMode and whether or not to enable Sentry integration.
+// Parameterized based on HmsMode.
 class MasterStressTest : public ExternalMiniClusterITestBase,
-                         public ::testing::WithParamInterface<pair<HmsMode, SentryMode>> {
+                         public ::testing::WithParamInterface<HmsMode> {
  public:
   MasterStressTest()
     : done_(1),
@@ -146,10 +146,7 @@
     opts.start_process_timeout = MonoDelta::FromSeconds(60);
     opts.rpc_negotiation_timeout = MonoDelta::FromSeconds(30);
 
-    opts.hms_mode = std::get<0>(GetParam());
-    bool enable_sentry = (std::get<1>(GetParam()) == SentryMode::ENABLED);
-    opts.enable_sentry = enable_sentry;
-    opts.enable_kerberos = enable_sentry;
+    opts.hms_mode = GetParam();
     // Tune down the notification log poll period in order to speed up catalog convergence.
     opts.extra_master_flags.emplace_back("--hive_metastore_notification_log_poll_period_seconds=1");
 
@@ -208,13 +205,8 @@
         new MasterServiceProxy(cluster_->messenger(), addr, addr.host()));
     ASSERT_OK(CreateTabletServerMap(m_proxy, cluster_->messenger(), &ts_map_));
 
-    if (enable_sentry) {
-      itest::SetupAdministratorPrivileges(cluster_->kdc(),
-                                          cluster_->sentry()->address());
-    }
-    if (std::get<0>(GetParam()) == HmsMode::ENABLE_METASTORE_INTEGRATION) {
+    if (GetParam() == HmsMode::ENABLE_METASTORE_INTEGRATION) {
       thrift::ClientOptions hms_opts;
-      hms_opts.enable_kerberos = enable_sentry;
       hms_opts.service_principal = "hive";
       hms_client_.reset(new HmsClient(cluster_->hms()->address(), hms_opts));
       ASSERT_OK(hms_client_->Start());
@@ -533,14 +525,9 @@
   std::unordered_map<string, itest::TServerDetails*> ts_map_;
 };
 
-// Run the test with the HMS/Sentry integration enabled and disabled. Sentry integration
-// should be only enabled when HMS integration is enabled.
-INSTANTIATE_TEST_CASE_P(HmsSentryConfigurations, MasterStressTest, ::testing::ValuesIn(
-    vector<pair<HmsMode, SentryMode>> {
-      { HmsMode::NONE, SentryMode::DISABLED },
-      { HmsMode::ENABLE_METASTORE_INTEGRATION, SentryMode::DISABLED },
-      { HmsMode::ENABLE_METASTORE_INTEGRATION, SentryMode::ENABLED },
-    }
+// Run the test with the HMS integration enabled and disabled.
+INSTANTIATE_TEST_CASE_P(HmsConfigurations, MasterStressTest, ::testing::ValuesIn(
+    vector<HmsMode> { HmsMode::NONE, HmsMode::ENABLE_METASTORE_INTEGRATION }
 ));
 
 TEST_P(MasterStressTest, Test) {
diff --git a/src/kudu/integration-tests/master_authz-itest.cc b/src/kudu/integration-tests/master_authz-itest.cc
index a67b1d2..76f103a 100644
--- a/src/kudu/integration-tests/master_authz-itest.cc
+++ b/src/kudu/integration-tests/master_authz-itest.cc
@@ -15,10 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include <atomic>
-#include <cstdlib>
 #include <functional>
-#include <initializer_list>
 #include <memory>
 #include <ostream>
 #include <string>
@@ -34,32 +31,21 @@
 #include "kudu/client/client.h"
 #include "kudu/client/schema.h"
 #include "kudu/client/shared_ptr.h" // IWYU pragma: keep
-#include "kudu/common/common.pb.h"
 #include "kudu/common/table_util.h"
-#include "kudu/common/wire_protocol.h"
 #include "kudu/gutil/stl_util.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/hms/hms_client.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/hms_itest-base.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
-#include "kudu/master/sentry_authz_provider-test-base.h"
 #include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/ranger/mini_ranger.h"
 #include "kudu/ranger/ranger.pb.h"
-#include "kudu/rpc/rpc_controller.h"
-#include "kudu/rpc/rpc_header.pb.h"
 #include "kudu/rpc/user_credentials.h"
 #include "kudu/security/test/mini_kdc.h"
-#include "kudu/sentry/mini_sentry.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
-#include "kudu/thrift/client.h"
 #include "kudu/util/decimal_util.h"
 #include "kudu/util/monotime.h"
-#include "kudu/util/scoped_cleanup.h"
 #include "kudu/util/slice.h"
 #include "kudu/util/status.h"
 #include "kudu/util/test_macros.h"
@@ -81,26 +67,15 @@
 using kudu::cluster::ExternalMiniCluster;
 using kudu::cluster::ExternalMiniClusterOptions;
 using kudu::hms::HmsClient;
-using kudu::master::AlterRoleGrantPrivilege;
-using kudu::master::CreateRoleAndAddToGroups;
-using kudu::master::GetDatabasePrivilege;
 using kudu::master::GetTableLocationsResponsePB;
 using kudu::master::GetTabletLocationsResponsePB;
-using kudu::master::GetTablePrivilege;
 using kudu::master::MasterServiceProxy;
-using kudu::master::ResetAuthzCacheRequestPB;
-using kudu::master::ResetAuthzCacheResponsePB;
 using kudu::master::VOTER_REPLICA;
 using kudu::ranger::ActionPB;
 using kudu::ranger::AuthorizationPolicy;
 using kudu::ranger::MiniRanger;
 using kudu::ranger::PolicyItem;
-using kudu::rpc::RpcController;
 using kudu::rpc::UserCredentials;
-using kudu::sentry::SentryClient;
-using sentry::TSentryGrantOption;
-using sentry::TSentryPrivilege;
-using std::atomic;
 using std::function;
 using std::move;
 using std::ostream;
@@ -112,13 +87,9 @@
 using strings::Substitute;
 
 namespace {
-const char* const kAdminGroup = "admin";
 const char* const kAdminUser = "test-admin";
-const char* const kUserGroup = "user";
 const char* const kTestUser = "test-user";
 const char* const kImpalaUser = "impala";
-const char* const kDevRole = "developer";
-const char* const kAdminRole = "ad";
 const char* const kDatabaseName = "db";
 const char* const kTableName = "table";
 const char* const kSecondTable = "second_table";
@@ -139,16 +110,11 @@
 };
 
 enum HarnessEnum {
-  kSentry,
-  kSentryWithCache,
   kRanger,
 };
+
 string HarnessEnumToString(HarnessEnum h) {
   switch (h) {
-    case kSentry:
-      return "SentryNoCache";
-    case kSentryWithCache:
-      return "SentryWithCache";
     case kRanger:
       return "Ranger";
   }
@@ -323,7 +289,7 @@
   // Returns a set of opts appropriate for an authorization test.
   ExternalMiniClusterOptions GetClusterOpts() {
     ExternalMiniClusterOptions opts;
-    // Always enable Kerberos, as Sentry/Ranger deployments do not make sense
+    // Always enable Kerberos, as Authz deployments do not make sense
     // in non-Kerberized environments.
     opts.enable_kerberos = true;
     // Add 'impala' as trusted user who may access the cluster without being
@@ -360,149 +326,10 @@
   virtual Status SetUpCredentials() = 0;
 
   // Sets things up so we can begin sending requests to the authorization
-  // services (whether that setup is an actual SentryClient or the ability to
-  // send curl requests to MiniRanger).
+  // services.
   virtual Status SetUpExternalServiceClients(const unique_ptr<ExternalMiniCluster>& cluster) = 0;
 };
 
-// Test Master authorization enforcement with Sentry and HMS
-// integration enabled.
-class SentryITestHarness : public MasterAuthzITestHarness,
-                           public HmsITestHarness {
- public:
-  using MasterAuthzITestHarness::CreateKuduTable;
-  using HmsITestHarness::CheckTable;
-  Status StopAuthzProvider(const unique_ptr<ExternalMiniCluster>& cluster) override {
-    RETURN_NOT_OK(sentry_client_->Stop());
-    RETURN_NOT_OK(cluster->sentry()->Stop());
-    return Status::OK();
-  }
-
-  Status StartAuthzProvider(const unique_ptr<ExternalMiniCluster>& cluster) override {
-    RETURN_NOT_OK(cluster->sentry()->Start());
-    RETURN_NOT_OK(cluster->kdc()->Kinit("kudu"));
-    RETURN_NOT_OK(sentry_client_->Start());
-    return Status::OK();
-  }
-
-  void CheckTableDoesNotExist(const string& database_name, const string& table_name,
-                              shared_ptr<KuduClient> client) override {
-    return HmsITestHarness::CheckTableDoesNotExist(database_name, table_name, client);
-  }
-
-  Status GrantCreateTablePrivilege(const PrivilegeParams& p) override {
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetDatabasePrivilege(p.db_name, "CREATE"));
-  }
-
-  Status GrantDropTablePrivilege(const PrivilegeParams& p) override {
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetTablePrivilege(p.db_name, p.table_name, "DROP"));
-  }
-
-  Status GrantAlterTablePrivilege(const PrivilegeParams& p) override {
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetTablePrivilege(p.db_name, p.table_name, "ALTER"));
-  }
-
-  Status GrantRenameTablePrivilege(const PrivilegeParams& p) override {
-    RETURN_NOT_OK(AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetTablePrivilege(p.db_name, p.table_name, "ALL")));
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetDatabasePrivilege(p.db_name, "CREATE"));
-  }
-
-  Status GrantGetMetadataTablePrivilege(const PrivilegeParams& p) override {
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetTablePrivilege(p.db_name, p.table_name, "METADATA"));
-  }
-
-  Status GrantGetMetadataDatabasePrivilege(const PrivilegeParams& p) override {
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kDevRole,
-        GetDatabasePrivilege(p.db_name, "METADATA"));
-  }
-
-  Status CreateTable(const OperationParams& p,
-                     const shared_ptr<KuduClient>& client) override {
-    Slice hms_database;
-    Slice hms_table;
-    RETURN_NOT_OK(ParseHiveTableIdentifier(p.table_name,
-                                           &hms_database, &hms_table));
-    return MasterAuthzITestHarness::CreateKuduTable(hms_database.ToString(),
-                                                    hms_table.ToString(), client);
-  }
-
-  Status SetUpTables(const unique_ptr<ExternalMiniCluster>& cluster,
-                     const shared_ptr<KuduClient>& client) override {
-    // First create database 'db' in the HMS.
-    RETURN_NOT_OK(CreateDatabase(kDatabaseName));
-    // Then create Kudu tables 'table' and 'second_table', owned by user
-    // 'test-admin'.
-    return MasterAuthzITestHarness::SetUpTables(cluster, client);
-  }
-
-  void TearDown() override {
-    if (sentry_client_) {
-      ASSERT_OK(sentry_client_->Stop());
-    }
-    if (hms_client_) {
-      ASSERT_OK(hms_client_->Stop());
-    }
-  }
-
-  void SetUpExternalMiniServiceOpts(ExternalMiniClusterOptions* opts) override {
-    opts->enable_sentry = true;
-    // Configure the timeout to reduce the run time of tests that involve
-    // re-connections.
-    const string timeout = AllowSlowTests() ? "5" : "2";
-    opts->hms_mode = HmsMode::ENABLE_METASTORE_INTEGRATION;
-    opts->extra_master_flags.emplace_back(
-       Substitute("$0=$1", "--sentry_service_send_timeout_seconds", timeout));
-    opts->extra_master_flags.emplace_back(
-       Substitute("$0=$1", "--sentry_service_recv_timeout_seconds", timeout));
-    // NOTE: this can be overwritten if another value is added to the end.
-    opts->extra_master_flags.emplace_back("--sentry_privileges_cache_capacity_mb=0");
-  }
-
-  Status SetUpExternalServiceClients(const unique_ptr<ExternalMiniCluster>& cluster) override {
-    thrift::ClientOptions hms_opts;
-    hms_opts.enable_kerberos = true;
-    hms_opts.service_principal = "hive";
-    RETURN_NOT_OK(HmsITestHarness::RestartHmsClient(cluster, hms_opts));
-
-    thrift::ClientOptions sentry_opts;
-    sentry_opts.enable_kerberos = true;
-    sentry_opts.service_principal = "sentry";
-    sentry_client_.reset(new SentryClient(cluster->sentry()->address(), sentry_opts));
-    return sentry_client_->Start();
-  }
-
-  Status SetUpCredentials() override {
-    // User to Role mapping:
-    // 1. user -> developer,
-    // 2. admin -> admin.
-    RETURN_NOT_OK(CreateRoleAndAddToGroups(sentry_client_.get(), kDevRole, kUserGroup));
-    RETURN_NOT_OK(CreateRoleAndAddToGroups(sentry_client_.get(), kAdminRole, kAdminGroup));
-
-    // Grant privilege 'ALL' on database 'db' to role admin.
-    TSentryPrivilege privilege = GetDatabasePrivilege(
-        kDatabaseName, "ALL",
-        TSentryGrantOption::DISABLED);
-    return AlterRoleGrantPrivilege(sentry_client_.get(), kAdminRole, privilege);
-  }
-
- protected:
-  unique_ptr<SentryClient> sentry_client_;
-};
-
-class SentryWithCacheITestHarness : public SentryITestHarness {
- public:
-  void SetUpExternalMiniServiceOpts(ExternalMiniClusterOptions* opts) override {
-    NO_FATALS(SentryITestHarness::SetUpExternalMiniServiceOpts(opts));
-    opts->extra_master_flags.emplace_back("--sentry_privileges_cache_capacity_mb=1");
-  }
-};
-
 class RangerITestHarness : public MasterAuthzITestHarness {
  public:
   static constexpr int kSleepAfterNewPolicyMs = 1200;
@@ -628,8 +455,7 @@
   MiniRanger* ranger_;
 };
 
-// Test basic master authorization enforcement with Sentry and HMS integration
-// enabled.
+// Test basic master authorization enforcement.
 class MasterAuthzITestBase : public ExternalMiniClusterITestBase {
  public:
   void SetUp() override {
@@ -638,12 +464,6 @@
 
   void SetUpCluster(HarnessEnum harness) {
     switch (harness) {
-      case kSentry:
-        harness_.reset(new SentryITestHarness());
-        break;
-      case kSentryWithCache:
-        harness_.reset(new SentryWithCacheITestHarness());
-        break;
       case kRanger:
         harness_.reset(new RangerITestHarness());
         break;
@@ -777,7 +597,7 @@
 };
 
 INSTANTIATE_TEST_CASE_P(AuthzProviders, MasterAuthzITest,
-    ::testing::Values(kSentry, kRanger),
+    ::testing::Values(kRanger),
     [] (const testing::TestParamInfo<MasterAuthzITest::ParamType>& info) {
       return HarnessEnumToString(info.param);
     });
@@ -981,7 +801,7 @@
   ASSERT_OK(desc.funcs.grant_privileges(this, privilege_params));
   ASSERT_OK(desc.funcs.do_action(this, action_params));
 
-  // Ensure that operating on a table while the Sentry is unreachable fails.
+  // Ensure that operating on a table while the Authz service is unreachable fails.
   // No such guarantee exists for Ranger, which caches policies in its clients.
   if (std::get<0>(GetParam()) != kRanger) {
     ASSERT_OK(StopAuthzProvider());
@@ -1085,62 +905,13 @@
 INSTANTIATE_TEST_CASE_P(AuthzCombinations,
                         TestAuthzTable,
                         ::testing::Combine(
-                            ::testing::Values(kSentry, kRanger),
+                            ::testing::Values(kRanger),
                             ::testing::ValuesIn(kAuthzCombinations)),
                         [] (const testing::TestParamInfo<TestAuthzTable::ParamType>& info) {
                           return Substitute("$0_$1", HarnessEnumToString(std::get<0>(info.param)),
                                             std::get<1>(info.param).funcs.description);
                         });
 
-class MasterSentryITest : public MasterAuthzITestBase {
- public:
-  void SetUp() override {
-    NO_FATALS(MasterAuthzITestBase::SetUp());
-    NO_FATALS(SetUpCluster(kSentry));
-  }
-};
-
-// Checks the user with table ownership automatically has ALL privilege on the
-// table. User 'test-user' can delete the same table without specifically
-// granting 'DROP ON TABLE'. Note that ownership population between the HMS and
-// the Sentry service happens synchronously, therefore, the table deletion
-// should succeed right after the table creation.
-// NOTE: this behavior is specific to Sentry,  so we don't parameterize.
-TEST_F(MasterSentryITest, TestTableOwnership) {
-  ASSERT_OK(GrantCreateTablePrivilege({ kDatabaseName }));
-  ASSERT_OK(CreateKuduTable(kDatabaseName, "new_table"));
-  NO_FATALS(CheckTable(kDatabaseName, "new_table",
-                       make_optional<const string&>(kTestUser)));
-
-  // TODO(hao): test create a table with a different owner than the client’s username?
-  ASSERT_OK(client_->DeleteTable(Substitute("$0.$1", kDatabaseName, "new_table")));
-  NO_FATALS(CheckTableDoesNotExist(kDatabaseName, "new_table"));
-}
-
-// Checks Sentry privileges are synchronized upon table rename in the HMS.
-TEST_F(MasterSentryITest, TestRenameTablePrivilegeTransfer) {
-  ASSERT_OK(GrantRenameTablePrivilege({ kDatabaseName, kTableName }));
-  ASSERT_OK(RenameTable({ Substitute("$0.$1", kDatabaseName, kTableName),
-                          Substitute("$0.$1", kDatabaseName, "b") }));
-  NO_FATALS(CheckTable(kDatabaseName, "b",
-                       make_optional<const string&>(kAdminUser)));
-
-  unique_ptr<KuduTableAlterer> alterer(client_->NewTableAlterer(
-      Substitute("$0.$1", kDatabaseName, "b")));
-  alterer->DropColumn("int16_val");
-
-  // Note that unlike table creation, there could be a delay between the table renaming
-  // in Kudu and the privilege renaming in Sentry. Because Kudu uses the transactional
-  // listener of the HMS to get notification of table alteration events, while Sentry
-  // uses post event listener (which is executed outside the HMS transaction). There
-  // is a chance that Kudu already finish the table renaming but the privilege renaming
-  // hasn't been reflected in the Sentry service.
-  ASSERT_EVENTUALLY([&] {
-    ASSERT_OK(alterer->Alter());
-  });
-  NO_FATALS(CheckTable(kDatabaseName, "b", make_optional<const string&>(kAdminUser)));
-}
-
 class AuthzErrorHandlingTest :
     public MasterAuthzITestBase,
     public ::testing::WithParamInterface<std::tuple<HarnessEnum, AuthzFuncs>> {
@@ -1166,7 +937,7 @@
   ASSERT_TRUE(s.IsNotAuthorized());
   ASSERT_STR_MATCHES(s.ToString(), "[Uu]nauthorized action");
 
-  // Ensure that operating on a non-existent table fails while Sentry is
+  // Ensure that operating on a non-existent table fails while the Authz service is
   // unreachable. No such guarantee exists for Ranger.
   if (std::get<0>(GetParam()) != kRanger) {
     ASSERT_OK(StopAuthzProvider());
@@ -1178,8 +949,6 @@
     ASSERT_OK(StartAuthzProvider());
   }
   ASSERT_EVENTUALLY([&] {
-    // SentryAuthzProvider throttles reconnections, so it's necessary to wait
-    // out the backoff.
     ASSERT_OK(funcs.grant_privileges(this, privilege_params));
   });
   s = funcs.do_action(this, action_params);
@@ -1227,356 +996,11 @@
 INSTANTIATE_TEST_CASE_P(AuthzFuncCombinations,
                         AuthzErrorHandlingTest,
                         ::testing::Combine(
-                            ::testing::Values(kSentry, kRanger),
+                            ::testing::Values(kRanger),
                             ::testing::ValuesIn(kAuthzFuncCombinations)),
                         [] (const testing::TestParamInfo<AuthzErrorHandlingTest::ParamType>& info) {
                           return Substitute("$0_$1", HarnessEnumToString(std::get<0>(info.param)),
                                             std::get<1>(info.param).description);
                         });
 
-// Class for test scenarios verifying functionality of managing AuthzProvider's
-// privileges cache via Kudu RPC.
-class SentryAuthzProviderCacheITest : public MasterAuthzITestBase {
- public:
-  void SetUp() override {
-    NO_FATALS(MasterAuthzITestBase::SetUp());
-    NO_FATALS(SetUpCluster(kSentryWithCache));
-  }
-
-  Status ResetCache() {
-    // ResetAuthzCache() RPC requires admin/superuser credentials, so this
-    // method calls Kinit(kAdminUser) to authenticate appropriately. However,
-    // it's necessary to return back the credentials of the regular user after
-    // resetting the cache since the rest of the scenario is supposed to run
-    // without superuser credentials.
-    SCOPED_CLEANUP({
-      WARN_NOT_OK(cluster_->kdc()->Kinit(kTestUser),
-                  "could not restore Kerberos credentials");
-    });
-    RETURN_NOT_OK(cluster_->kdc()->Kinit(kAdminUser));
-    std::shared_ptr<MasterServiceProxy> proxy = cluster_->master_proxy();
-    UserCredentials user_credentials;
-    user_credentials.set_real_user(kAdminUser);
-    proxy->set_user_credentials(user_credentials);
-
-    RpcController ctl;
-    ResetAuthzCacheResponsePB res;
-    RETURN_NOT_OK(proxy->ResetAuthzCache(
-        ResetAuthzCacheRequestPB(), &res, &ctl));
-    return res.has_error() ? StatusFromPB(res.error().status()) : Status::OK();
-  }
-};
-
-// This test scenario uses AlterTable() to make sure AuthzProvider's cache
-// empties upon successful ResetAuthzCache() RPC.
-TEST_F(SentryAuthzProviderCacheITest, AlterTable) {
-  const auto table_name = Substitute("$0.$1", kDatabaseName, kTableName);
-  ASSERT_OK(GrantAlterTablePrivilege({ kDatabaseName, kTableName }));
-  {
-    unique_ptr<KuduTableAlterer> table_alterer(
-        client_->NewTableAlterer(table_name)->DropColumn("int8_val"));
-    auto s = table_alterer->Alter();
-    ASSERT_TRUE(s.ok()) << s.ToString();
-  }
-  ASSERT_OK(StopAuthzProvider());
-  {
-    unique_ptr<KuduTableAlterer> table_alterer(
-        client_->NewTableAlterer(table_name)->DropColumn("int16_val"));
-    auto s = table_alterer->Alter();
-    ASSERT_TRUE(s.ok()) << s.ToString();
-  }
-  ASSERT_OK(ResetCache());
-  {
-    // After resetting the cache, it should not be possible to perform another
-    // ALTER TABLE operation: no entries are in the cache, so authz provider
-    // needs to fetch information from Sentry directly.
-    unique_ptr<KuduTableAlterer> table_alterer(
-        client_->NewTableAlterer(table_name)->DropColumn("int32_val"));
-    auto s = table_alterer->Alter();
-    ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
-  }
-
-  // Try to do the same after starting Sentry back. It should be a success.
-  ASSERT_OK(StartAuthzProvider());
-  {
-    unique_ptr<KuduTableAlterer> table_alterer(
-        client_->NewTableAlterer(table_name)->DropColumn("int32_val"));
-    auto s = table_alterer->Alter();
-    ASSERT_TRUE(s.ok()) << s.ToString();
-  }
-}
-
-// This test scenario calls a couple of authz methods of SentryAuthzProvider
-// while resetting its fetcher's cache in parallel using master's
-// ResetAuthzCache() RPC.
-TEST_F(SentryAuthzProviderCacheITest, ResetAuthzCacheConcurrentAlterTable) {
-  constexpr const auto num_threads = 16;
-  const auto run_interval = AllowSlowTests() ? MonoDelta::FromSeconds(8)
-                                             : MonoDelta::FromSeconds(1);
-  ASSERT_OK(GrantCreateTablePrivilege({ kDatabaseName }));
-  for (auto idx = 0; idx < num_threads; ++idx) {
-    ASSERT_OK(CreateTable(Substitute("$0.$1", kDatabaseName, idx)));
-    ASSERT_OK(GrantAlterTablePrivilege({ kDatabaseName, Substitute("$0", idx) }));
-  }
-
-  vector<Status> threads_task_status(num_threads);
-  {
-    atomic<bool> stopped(false);
-    vector<thread> threads;
-
-    SCOPED_CLEANUP({
-      stopped = true;
-      for (auto& thread : threads) {
-        thread.join();
-      }
-    });
-
-    for (auto idx = 0; idx < num_threads; ++idx) {
-      const auto thread_idx = idx;
-      threads.emplace_back([&, thread_idx] () {
-        const auto table_name = Substitute("$0.$1", kDatabaseName, thread_idx);
-
-        while (!stopped) {
-          SleepFor(MonoDelta::FromMicroseconds((rand() % 2 + 1) * thread_idx));
-          {
-            unique_ptr<KuduTableAlterer> table_alterer(
-               client_->NewTableAlterer(table_name));
-            table_alterer->DropColumn("int8_val");
-
-            auto s = table_alterer->Alter();
-            if (!s.ok()) {
-              threads_task_status[thread_idx] = s;
-              return;
-            }
-          }
-
-          SleepFor(MonoDelta::FromMicroseconds((rand() % 3 + 1) * thread_idx));
-          {
-            unique_ptr<KuduTableAlterer> table_alterer(
-                client_->NewTableAlterer(table_name));
-            table_alterer->AddColumn("int8_val")->Type(KuduColumnSchema::INT8);
-            auto s = table_alterer->Alter();
-            if (!s.ok()) {
-              threads_task_status[thread_idx] = s;
-              return;
-            }
-          }
-        }
-      });
-    }
-
-    const auto time_beg = MonoTime::Now();
-    const auto time_end = time_beg + run_interval;
-    while (MonoTime::Now() < time_end) {
-      SleepFor(MonoDelta::FromMilliseconds((rand() % 3)));
-      ASSERT_OK(ResetCache());
-    }
-  }
-  for (auto idx = 0; idx < threads_task_status.size(); ++idx) {
-    SCOPED_TRACE(Substitute("results for thread $0", idx));
-    const auto& s = threads_task_status[idx];
-    EXPECT_TRUE(s.ok()) << s.ToString();
-  }
-}
-
-// This test scenario documents an artifact of the Kudu+HMS+Sentry integration
-// when authz cache is enabled (the cache is enabled by default). In essence,
-// information on the ownership of a table created during a short period of
-// Sentry's unavailability will not ever appear in Sentry. That might be
-// misleading because CreateTable() reports a success to the client. The created
-// table indeed exists and is fully functional otherwise, but the corresponding
-// owner privilege record is absent in Sentry.
-//
-// TODO(aserbin): clarify why it works with HEAD of the master branches
-//                of Sentry/Hive but fails with Sentry 2.1.0 and Hive 2.1.1.
-TEST_F(SentryAuthzProviderCacheITest, DISABLED_CreateTables) {
-  constexpr const char* const kGhostTables[] = { "t10", "t11" };
-
-  // Grant CREATE TABLE and METADATA privileges on the database.
-  ASSERT_OK(GrantCreateTablePrivilege({ kDatabaseName }));
-  ASSERT_OK(GrantGetMetadataDatabasePrivilege({ kDatabaseName }));
-
-  // Make sure it's possible to create a table in the database. This also
-  // populates the privileges cache with information on the privileges
-  // granted on the database.
-  ASSERT_OK(CreateKuduTable(kDatabaseName, "t0"));
-
-  // An attempt to open a not-yet-existing table will fetch the information
-  // on the granted privileges on the table into the privileges cache.
-  for (const auto& t : kGhostTables) {
-    shared_ptr<KuduTable> kudu_table;
-    const auto s = client_->OpenTable(Substitute("$0.$1", kDatabaseName, t),
-                                      &kudu_table);
-    ASSERT_TRUE(s.IsNotFound()) << s.ToString();
-  }
-
-  ASSERT_OK(StopAuthzProvider());
-
-  // CreateTable() with operation timeout longer than HMS --> Sentry
-  // communication timeout successfully completes. After failing to push
-  // the information on the newly created table to Sentry due to the logic
-  // implemented in the SentrySyncHMSNotificationsPostEventListener plugin,
-  // HMS sends success response to Kudu master and Kudu successfully completes
-  // the rest of the steps.
-  ASSERT_OK(CreateKuduTable(kDatabaseName, kGhostTables[0]));
-
-  // In this case, the timeout for the CreateTable RPC is set to be lower than
-  // the HMS --> Sentry communication timeout (see corresponding parameters
-  // of the MiniHms::EnableSentry() method). CreateTable() successfully passes
-  // the authz phase since the information on privileges is cached and no
-  // Sentry RPC calls are attempted. However, since Sentry is down,
-  // CreateTable() takes a long time on the HMS's side and the client's
-  // request times out, while the creation of the table continues in the
-  // background.
-  {
-    const auto s = CreateKuduTable(kDatabaseName, kGhostTables[1],
-                                   MonoDelta::FromSeconds(1));
-    ASSERT_TRUE(s.IsTimedOut()) << s.ToString();
-  }
-
-  // Before starting Sentry, make sure the abandoned request to create the
-  // latter table succeeded even if CreateKuduTable() reported timeout.
-  // This is to make sure HMS stopped trying to push notification
-  // on table creation to Sentry anymore via the metastore plugin
-  // SentrySyncHMSNotificationsPostEventListener.
-  ASSERT_EVENTUALLY([&]{
-    bool exists;
-    ASSERT_OK(client_->TableExists(
-        Substitute("$0.$1", kDatabaseName, kGhostTables[1]), &exists));
-    ASSERT_TRUE(exists);
-  });
-
-  ASSERT_OK(ResetCache());
-
-  // After resetting the cache, it should not be possible to create another
-  // table: authz provider needs to fetch information on privileges directly
-  // from Sentry, but it's still down.
-  {
-    const auto s = CreateKuduTable(kDatabaseName, "t2");
-    ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
-  }
-
-  ASSERT_OK(StartAuthzProvider());
-
-  // Try to create the table after starting Sentry back: it should be a success.
-  ASSERT_OK(CreateKuduTable(kDatabaseName, "t2"));
-
-  // Once table has been created, it should be possible to perform DDL operation
-  // on it since the user is the owner of the table.
-  {
-    unique_ptr<KuduTableAlterer> table_alterer(
-        client_->NewTableAlterer(Substitute("$0.$1", kDatabaseName, "t2")));
-    table_alterer->AddColumn("new_int8_columun")->Type(KuduColumnSchema::INT8);
-    ASSERT_OK(table_alterer->Alter());
-  }
-
-  // Try to run DDL against the tables created during Sentry's downtime. These
-  // should not be authorized since Sentry didn't received information on the
-  // ownership of those tables from HMS during their creation and there isn't
-  // any catch up for those events made after Sentry started.
-  for (const auto& t : kGhostTables) {
-    unique_ptr<KuduTableAlterer> table_alterer(
-        client_->NewTableAlterer(Substitute("$0.$1", kDatabaseName, t)));
-    table_alterer->AddColumn("new_int8_columun")->Type(KuduColumnSchema::INT8);
-    auto s = table_alterer->Alter();
-    ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-    // After granting the ALTER TABLE privilege the alteration should be
-    // successful. One caveat: it's necessary to reset the cache since the cache
-    // will not have the new record till the current entry hasn't yet expired.
-    ASSERT_OK(GrantAlterTablePrivilege({ kDatabaseName, t }));
-    ASSERT_OK(ResetCache());
-    ASSERT_OK(table_alterer->Alter());
-  }
-}
-
-// Basic test to verify access control and functionality of
-// the ResetAuthzCache(); integration with Sentry is not enabled.
-class AuthzCacheControlTest : public ExternalMiniClusterITestBase {
- public:
-  void SetUp() override {
-    ExternalMiniClusterITestBase::SetUp();
-    ExternalMiniClusterOptions opts;
-    opts.enable_kerberos = true;
-    StartClusterWithOpts(opts);
-  }
-
-  // Utility method to call master's ResetAuthzCache RPC under the credentials
-  // of the specified 'user'. The credentials should have been set appropriately
-  // before calling this method (e.g., call kinit if necessary).
-  Status ResetCache(const string& user,
-                    RpcController* ctl,
-                    ResetAuthzCacheResponsePB* resp) {
-    RETURN_NOT_OK(cluster_->kdc()->Kinit(user));
-    std::shared_ptr<MasterServiceProxy> proxy = cluster_->master_proxy();
-    UserCredentials user_credentials;
-    user_credentials.set_real_user(user);
-    proxy->set_user_credentials(user_credentials);
-
-    ResetAuthzCacheRequestPB req;
-    return proxy->ResetAuthzCache(req, resp, ctl);
-  }
-};
-
-TEST_F(AuthzCacheControlTest, ResetCacheNoSentryIntegration) {
-  // Non-admin users (i.e. those not in --superuser_acl) are not allowed
-  // to reset authz cache.
-  for (const auto& user : { "test-user", "joe-interloper", }) {
-    ASSERT_OK(cluster_->kdc()->Kinit(user));
-    ResetAuthzCacheResponsePB resp;
-    RpcController ctl;
-    auto s = ResetCache(user, &ctl, &resp);
-    ASSERT_TRUE(s.IsRemoteError()) << s.ToString();
-    ASSERT_FALSE(resp.has_error());
-
-    const auto* err_status = ctl.error_response();
-    ASSERT_NE(nullptr, err_status);
-    ASSERT_TRUE(err_status->has_code());
-    ASSERT_EQ(rpc::ErrorStatusPB::ERROR_APPLICATION, err_status->code());
-    ASSERT_STR_CONTAINS(err_status->message(),
-                        "unauthorized access to method: ResetAuthzCache");
-  }
-
-  // The cache can be reset with credentials of a super-user. However, in
-  // case if integration with Sentry is not enabled, the AuthzProvider
-  // doesn't have any cache.
-  {
-    ResetAuthzCacheResponsePB resp;
-    RpcController ctl;
-    const auto s = ResetCache("test-admin", &ctl, &resp);
-    ASSERT_TRUE(s.ok()) << s.ToString();
-    ASSERT_EQ(nullptr, ctl.error_response());
-    ASSERT_TRUE(resp.has_error()) << resp.error().DebugString();
-    const auto app_s = StatusFromPB(resp.error().status());
-    ASSERT_TRUE(app_s.IsNotSupported()) << app_s.ToString();
-    ASSERT_STR_CONTAINS(app_s.ToString(),
-                        "provider does not have privileges cache");
-  }
-}
-
-// A test for the ValidateSentryServiceRpcAddresses group flag validator.
-// The only existing test scenario covers only the negative case, while
-// several other Sentry-related (and not) tests provide good coverage
-// for all the positive cases.
-class MasterSentryAndHmsFlagsTest : public KuduTest {
-};
-
-TEST_F(MasterSentryAndHmsFlagsTest, MasterRefuseToStart) {
-  // The code below results in setting the --sentry_service_rpc_addresses flag
-  // to the mini-sentry's RPC address, but leaving the --hive_metastore_uris
-  // flag unset (i.e. its value is an empty string). Such a combination of flag
-  // settings makes it impossible to start Kudu master.
-  cluster::ExternalMiniClusterOptions opts;
-  opts.enable_kerberos = true;
-  opts.enable_sentry = true;
-  opts.hms_mode = HmsMode::NONE;
-
-  cluster::ExternalMiniCluster cluster(std::move(opts));
-  const auto s = cluster.Start();
-  const auto msg = s.ToString();
-  ASSERT_TRUE(s.IsRuntimeError()) << msg;
-  ASSERT_STR_CONTAINS(msg, "failed to start masters: Unable to start Master");
-  ASSERT_STR_CONTAINS(msg, "kudu-master: process exited with non-zero status 1");
-}
-
 } // namespace kudu
diff --git a/src/kudu/integration-tests/master_failover-itest.cc b/src/kudu/integration-tests/master_failover-itest.cc
index 60a1d8e..467079c 100644
--- a/src/kudu/integration-tests/master_failover-itest.cc
+++ b/src/kudu/integration-tests/master_failover-itest.cc
@@ -21,7 +21,6 @@
 #include <ostream> // IWYU pragma: keep
 #include <set>
 #include <string>
-#include <utility>
 #include <vector>
 
 #include <glog/logging.h>
@@ -39,7 +38,6 @@
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/master/sys_catalog.h" // IWYU pragma: keep
 #include "kudu/mini-cluster/external_mini_cluster.h"
-#include "kudu/sentry/mini_sentry.h"
 #include "kudu/util/metrics.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/net/net_util.h" // IWYU pragma: keep
@@ -59,8 +57,6 @@
 using kudu::cluster::ExternalMiniClusterOptions;
 using kudu::cluster::ScopedResumeExternalDaemon;
 using kudu::itest::GetInt64Metric;
-using kudu::itest::SentryMode;
-using std::pair;
 using std::set;
 using std::string;
 using std::unique_ptr;
@@ -76,9 +72,9 @@
 
 const int kNumTabletServerReplicas = 3;
 
-// Parameterized based on HmsMode and whether or not to enable Sentry integration.
+// Parameterized based on HmsMode.
 class MasterFailoverTest : public KuduTest,
-                           public ::testing::WithParamInterface<pair<HmsMode, SentryMode>> {
+                           public ::testing::WithParamInterface<HmsMode> {
  public:
   enum CreateTableMode {
     kWaitForCreate = 0,
@@ -88,9 +84,7 @@
   MasterFailoverTest() {
     opts_.num_masters = 3;
     opts_.num_tablet_servers = kNumTabletServerReplicas;
-    opts_.hms_mode = std::get<0>(GetParam());
-    opts_.enable_sentry = (std::get<1>(GetParam()) == SentryMode::ENABLED);
-    opts_.enable_kerberos = opts_.enable_sentry;
+    opts_.hms_mode = GetParam();
 
     // Reduce various timeouts below as to make the detection of
     // leader master failures (specifically, failures as result of
@@ -134,11 +128,6 @@
     // the global operation timeout.
     builder.default_admin_operation_timeout(MonoDelta::FromSeconds(90));
     ASSERT_OK(cluster_->CreateClient(&builder, &client_));
-
-    if (opts_.enable_sentry) {
-      ASSERT_OK(itest::SetupAdministratorPrivileges(cluster_->kdc(),
-                                                    cluster_->sentry()->address()));
-    }
   }
 
   Status CreateTable(const std::string& table_name, CreateTableMode mode) {
@@ -170,14 +159,9 @@
   shared_ptr<KuduClient> client_;
 };
 
-// Run the test with the HMS/Sentry integration enabled and disabled. Sentry integration
-// should be only enabled when HMS integration is enabled.
-INSTANTIATE_TEST_CASE_P(HmsSentryConfigurations, MasterFailoverTest, ::testing::ValuesIn(
-    vector<pair<HmsMode, SentryMode>> {
-      { HmsMode::NONE, SentryMode::DISABLED },
-      { HmsMode::ENABLE_METASTORE_INTEGRATION, SentryMode::DISABLED },
-      { HmsMode::ENABLE_METASTORE_INTEGRATION, SentryMode::ENABLED },
-  }
+// Run the test with the HMS integration enabled and disabled.
+INSTANTIATE_TEST_CASE_P(HmsConfigurations, MasterFailoverTest, ::testing::ValuesIn(
+    vector<HmsMode> { HmsMode::NONE, HmsMode::ENABLE_METASTORE_INTEGRATION }
 ));
 
 // Test that synchronous CreateTable (issue CreateTable call and then
diff --git a/src/kudu/integration-tests/ts_authz-itest.cc b/src/kudu/integration-tests/ts_authz-itest.cc
index 2641010..d325ce0 100644
--- a/src/kudu/integration-tests/ts_authz-itest.cc
+++ b/src/kudu/integration-tests/ts_authz-itest.cc
@@ -34,7 +34,6 @@
 #include "kudu/client/schema.h"
 #include "kudu/client/shared_ptr.h" // IWYU pragma: keep
 #include "kudu/client/write_op.h"
-#include "kudu/common/common.pb.h"
 #include "kudu/common/partial_row.h"
 #include "kudu/gutil/map-util.h"
 #include "kudu/gutil/stl_util.h"
@@ -42,17 +41,11 @@
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/integration-tests/data_gen_util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/hms_itest-base.h"
-#include "kudu/master/sentry_authz_provider-test-base.h"
 #include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/ranger/mini_ranger.h"
 #include "kudu/ranger/ranger.pb.h"
 #include "kudu/security/test/mini_kdc.h"
-#include "kudu/sentry/mini_sentry.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
 #include "kudu/tablet/transactions/write_transaction.h"
-#include "kudu/thrift/client.h"
 #include "kudu/util/barrier.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/random.h"
@@ -80,19 +73,12 @@
 using kudu::client::KuduTableCreator;
 using kudu::cluster::ExternalMiniCluster;
 using kudu::cluster::ExternalMiniClusterOptions;
-using kudu::master::AlterRoleGrantPrivilege;
-using kudu::master::CreateRoleAndAddToGroups;
-using kudu::master::GetColumnPrivilege;
-using kudu::master::GetDatabasePrivilege;
-using kudu::master::GetTablePrivilege;
 using kudu::ranger::ActionPB;
 using kudu::ranger::AuthorizationPolicy;
 using kudu::ranger::PolicyItem;
 using kudu::ranger::MiniRanger;
-using kudu::sentry::SentryClient;
 using kudu::tablet::WritePrivileges;
 using kudu::tablet::WritePrivilegeType;
-using sentry::TSentryGrantOption;
 using std::pair;
 using std::string;
 using std::thread;
@@ -249,17 +235,13 @@
   return Status::OK();
 }
 
-// Note: groups and users therein are statically provided to MiniSentry (see
-// mini_sentry.cc). We expect Sentry to be aware of users "user[0-2]".
 constexpr int kNumUsers = 3;
-constexpr const char* kAdminGroup = "admin";
 constexpr const char* kAdminUser = "test-admin";
 
 constexpr int kNumTables = 3;
 constexpr int kNumColsPerTable = 3;
 constexpr const char* kDb = "db";
 constexpr const char* kTablePrefix = "table";
-constexpr const char* kAdminRole = "kudu-admin";
 
 constexpr int kAuthzTokenTTLSecs = 1;
 constexpr int kAuthzCacheTTLMultiplier = 3;
@@ -267,7 +249,7 @@
 } // anonymous namespace
 
 // Test harness used to set up a cluster and grant privileges, that is agnostic
-// the underlying authorization service (e.g. Sentry, Ranger).
+// the underlying authorization service (e.g. Ranger).
 class TSAuthzITestHarness {
  public:
   virtual ~TSAuthzITestHarness() {}
@@ -289,7 +271,7 @@
     return opts;
   }
 
-  // Sets up the external services (e.g. Sentry, Ranger).
+  // Sets up the external services (e.g. Ranger).
   virtual void SetUpExternalMiniServiceOpts(ExternalMiniClusterOptions* opts) = 0;
   virtual Status SetUpExternalServiceClients(const unique_ptr<ExternalMiniCluster>& cluster) = 0;
 
@@ -300,8 +282,8 @@
   // Sets up table-related metadata (e.g. HMS database, columns).
   virtual Status SetUpTables() = 0;
 
-  // Grants privileges on the given table/column. These abide by Sentry's
-  // hierarchical definition of privileges, so if granting privileges on a
+  // Grants privileges on the given table/column.
+  // These abide the hierarchical definition of privileges, so if granting privileges on a
   // table, these grant privileges on the table and all columns in that table.
   virtual Status GrantTablePrivilege(const string& db, const string& tbl, const string& user,
                                      const string& action) = 0;
@@ -339,76 +321,6 @@
   vector<string> cols_;
 };
 
-class SentryITestHarness : public TSAuthzITestHarness,
-                           public HmsITestHarness {
- public:
-  void SetUpExternalMiniServiceOpts(ExternalMiniClusterOptions* opts) override {
-    opts->hms_mode = HmsMode::ENABLE_METASTORE_INTEGRATION;
-    opts->enable_sentry = true;
-    opts->extra_master_flags.emplace_back(Substitute("--sentry_privileges_cache_ttl_factor=$0",
-                                                    kAuthzCacheTTLMultiplier));
-  }
-
-  Status SetUpExternalServiceClients(const unique_ptr<ExternalMiniCluster>& cluster) override {
-    // Set up the HMS client so we can set up a database.
-    thrift::ClientOptions hms_opts;
-    hms_opts.enable_kerberos = true;
-    hms_opts.service_principal = "hive";
-    RETURN_NOT_OK(RestartHmsClient(cluster, hms_opts));
-
-    // Set up the Sentry client so we can set up privileges.
-    thrift::ClientOptions sentry_opts;
-    sentry_opts.enable_kerberos = true;
-    sentry_opts.service_principal = "sentry";
-    sentry_client_.reset(new SentryClient(cluster->sentry()->address(), sentry_opts));
-    return sentry_client_->Start();
-  }
-
-  Status SetUpCredentials() override {
-    RETURN_NOT_OK(CreateRoleAndAddToGroups(sentry_client_.get(), kAdminRole, kAdminGroup));
-    RETURN_NOT_OK(AlterRoleGrantPrivilege(sentry_client_.get(), kAdminRole,
-        GetDatabasePrivilege(kDb, "ALL", TSentryGrantOption::DISABLED)));
-
-    // Set up our users such that userN --> groupN --> roleN.
-    // NOTE: The user-group mappings are specified in mini_sentry.cc.
-    for (int i = 0; i < kNumUsers; i++) {
-      const string user = Substitute("user$0", i);
-      const string role = Substitute("role$0", i);
-      const string group = Substitute("group$0", i);
-      RETURN_NOT_OK(CreateRoleAndAddToGroups(sentry_client_.get(), role, group));
-      EmplaceOrDie(&role_by_user_, user, role);
-    }
-    return Status::OK();
-  }
-  Status SetUpTables() override {
-    // Create the database in the HMS.
-    RETURN_NOT_OK(CreateDatabase(kDb));
-    // Finally populate a set of column names to use for our tables.
-    for (int i = 0; i < kNumColsPerTable; i++) {
-      cols_.emplace_back(Substitute("col$0", i));
-    }
-    return Status::OK();
-  }
-  Status GrantTablePrivilege(const string& db, const string& tbl, const string& user,
-                             const string& action) override {
-    const auto& role = FindOrDie(role_by_user_, user);
-    return AlterRoleGrantPrivilege(sentry_client_.get(), role,
-                                   GetTablePrivilege(db, tbl, action));
-  }
-  Status GrantColumnPrivilege(const string& db, const string& tbl, const string& col,
-                              const string& user, const string& action) override {
-    const auto& role = FindOrDie(role_by_user_, user);
-    return AlterRoleGrantPrivilege(sentry_client_.get(), role,
-                                   GetColumnPrivilege(db, tbl, col, action));
-  }
- private:
-  // A Sentry client with which to grant privileges.
-  unique_ptr<SentryClient> sentry_client_;
-
-  // Maintain a mapping between users and roles.
-  unordered_map<string, string> role_by_user_;
-};
-
 namespace {
 ActionPB StringToActionPB(string s) {
   ToLowerCase(&s);
@@ -480,20 +392,17 @@
 
 // TODO(awong): refactor so we can share code between master_authz-itest.
 enum HarnessEnum {
-  kSentry,
   kRanger,
 };
 string HarnessEnumToString(HarnessEnum h) {
   switch (h) {
-    case kSentry:
-      return "Sentry";
     case kRanger:
       return "Ranger";
   }
   return "";
 }
 
-// These tests will use the HMS and Sentry, and thus, are very slow.
+// These tests will use the HMS and an Authz provider, and thus, are very slow.
 // SKIP_IF_SLOW_NOT_ALLOWED() should be the very first thing called in the body
 // of every test based on this test class.
 class TSAuthzITest : public ExternalMiniClusterITestBase,
@@ -502,9 +411,6 @@
   void SetUp() override {
     SKIP_IF_SLOW_NOT_ALLOWED();
     switch (GetParam()) {
-      case kSentry:
-        harness_.reset(new SentryITestHarness());
-        break;
       case kRanger:
         harness_.reset(new RangerITestHarness());
         break;
@@ -667,7 +573,7 @@
   ASSERT_OK(cluster_->CreateClient(nullptr, &user_client));
 
   // Note: we only need privileges on the metadata for OpenTable() calls.
-  // METADATA isn't a first-class Sentry privilege and won't get carried over
+  // METADATA isn't a first-class privilege and won't get carried over
   // on table rename, so we just grant INSERT privileges.
   ASSERT_OK(harness_->GrantTablePrivilege(kDb, kTableName, user, "INSERT"));
 
@@ -692,16 +598,8 @@
     table_alterer->AddColumn(another_column)->Type(KuduColumnSchema::INT32);
     ASSERT_OK(table_alterer->Alter());
   }
-  // Since privileges are cached in Sentry, even though we've granted
-  // privileges, clients will use the cached privilege and not be authorized
-  // for a bit. Provided we waited a bit after granting each privilege, no such
-  // behavior exists in Ranger.
+
   ASSERT_OK(user_client->OpenTable(table_ident, &table));
-  if (GetParam() == kSentry) {
-    Status s = PerformScan({ another_column }, /*prng=*/nullptr, table.get());
-    ASSERT_TRUE(s.IsRemoteError()) << s.ToString();
-    ASSERT_STR_CONTAINS(s.ToString(), "not authorized");
-  }
 
   // Wait the full duration of the cache TTL, and an additional full token TTL.
   // This ensures that the client's token will expire we will get a new one
@@ -709,15 +607,11 @@
   SleepFor(MonoDelta::FromSeconds(kAuthzTokenTTLSecs * (1 + kAuthzCacheTTLMultiplier)));
   ASSERT_OK(PerformScan({ another_column }, /*prng=*/nullptr, table.get()));
 
-  // Now rename the table to something else. There shouldn't be any privileges
-  // cached for the newly-renamed table, so we should immediately be able to
-  // scan it. Sentry automatically renames privileges -- Ranger doesn't, so we
-  // need to explicitly grant privileges on the new table name.
+  // Now rename the table to something else.
+  // We need to explicitly grant privileges on the new table name.
   const string kNewTableName = "newtable";
   const string new_table_ident = Substitute("$0.$1", kDb, kNewTableName);
-  if (GetParam() != kSentry) {
-    ASSERT_OK(harness_->GrantTablePrivilege(kDb, kNewTableName, user, "SELECT"));
-  }
+  ASSERT_OK(harness_->GrantTablePrivilege(kDb, kNewTableName, user, "SELECT"));
   {
     unique_ptr<KuduTableAlterer> table_alterer(client_->NewTableAlterer(table_ident));
     table_alterer->RenameTo(new_table_ident);
@@ -728,7 +622,7 @@
 }
 
 INSTANTIATE_TEST_CASE_P(AuthzProviders, TSAuthzITest,
-    ::testing::Values(kSentry, kRanger),
+    ::testing::Values(kRanger),
     [] (const testing::TestParamInfo<TSAuthzITest::ParamType>& info) {
       return HarnessEnumToString(info.param);
     });
diff --git a/src/kudu/master/CMakeLists.txt b/src/kudu/master/CMakeLists.txt
index 0dc4540..7644535 100644
--- a/src/kudu/master/CMakeLists.txt
+++ b/src/kudu/master/CMakeLists.txt
@@ -47,10 +47,6 @@
   mini_master.cc
   placement_policy.cc
   ranger_authz_provider.cc
-  sentry_authz_provider.cc
-  sentry_client_metrics.cc
-  sentry_privileges_cache_metrics.cc
-  sentry_privileges_fetcher.cc
   sys_catalog.cc
   table_metrics.cc
   ts_descriptor.cc
@@ -65,7 +61,6 @@
   kudu_common
   kudu_hms
   kudu_ranger
-  kudu_sentry
   kudu_subprocess
   kudu_thrift
   kudu_util
@@ -87,8 +82,7 @@
   master_proto
   mini_cluster
   mini_hms
-  mini_kdc
-  mini_sentry)
+  mini_kdc)
 
 ADD_KUDU_TEST(auto_rebalancer-test)
 ADD_KUDU_TEST(catalog_manager-test)
@@ -98,7 +92,6 @@
                           DATA_FILES ../scripts/first_argument.sh)
 ADD_KUDU_TEST(mini_master-test RESOURCE_LOCK "master-web-port")
 ADD_KUDU_TEST(placement_policy-test)
-ADD_KUDU_TEST(sentry_authz_provider-test NUM_SHARDS 8)
 ADD_KUDU_TEST(sys_catalog-test RESOURCE_LOCK "master-web-port")
 ADD_KUDU_TEST(ts_descriptor-test DATA_FILES ../scripts/first_argument.sh)
 ADD_KUDU_TEST(ts_state-test)
diff --git a/src/kudu/master/authz_provider.h b/src/kudu/master/authz_provider.h
index 48023e5..2a6981f 100644
--- a/src/kudu/master/authz_provider.h
+++ b/src/kudu/master/authz_provider.h
@@ -46,11 +46,6 @@
   // Stops the AuthzProvider instance.
   virtual void Stop() = 0;
 
-  // Reset the underlying cache (if any), invalidating all cached entries.
-  // Returns Status::NotSupported() if the provider doesn't support resetting
-  // its cache.
-  virtual Status ResetCache() = 0;
-
   // Checks if the table creation is authorized for the given user.
   // If the table is being created with a different owner than the user,
   // then more strict privilege is required.
diff --git a/src/kudu/master/catalog_manager.cc b/src/kudu/master/catalog_manager.cc
index 05645f8..428bf43 100644
--- a/src/kudu/master/catalog_manager.cc
+++ b/src/kudu/master/catalog_manager.cc
@@ -102,7 +102,6 @@
 #include "kudu/master/master_cert_authority.h"
 #include "kudu/master/placement_policy.h"
 #include "kudu/master/ranger_authz_provider.h"
-#include "kudu/master/sentry_authz_provider.h"
 #include "kudu/master/sys_catalog.h"
 #include "kudu/master/table_metrics.h"
 #include "kudu/master/ts_descriptor.h"
@@ -314,20 +313,8 @@
 
 METRIC_DEFINE_entity(table);
 
-DECLARE_string(sentry_service_rpc_addresses);
 DECLARE_string(ranger_config_path);
 
-static bool ValidateRangerSentryFlags() {
-  if (!FLAGS_sentry_service_rpc_addresses.empty() &&
-      !FLAGS_ranger_config_path.empty()) {
-    LOG(ERROR) << "--sentry_service_rpc_addresses and --ranger_config_path "
-                  "cannot be set at the same time.";
-    return false;
-  }
-  return true;
-}
-GROUP_FLAG_VALIDATOR(ranger_sentry_flags, ValidateRangerSentryFlags);
-
 // Validates that if auto-rebalancing is enabled, the cluster uses 3-4-3 replication
 // (the --raft_prepare_replacement_before_eviction flag must be set to true).
 static bool Validate343SchemeEnabledForAutoRebalancing()  {
@@ -780,9 +767,7 @@
       leader_ready_term_(-1),
       hms_notification_log_event_id_(-1),
       leader_lock_(RWMutex::Priority::PREFER_WRITING) {
-  if (SentryAuthzProvider::IsEnabled()) {
-    authz_provider_.reset(new SentryAuthzProvider(master_->metric_entity()));
-  } else if (RangerAuthzProvider::IsEnabled()) {
+  if (RangerAuthzProvider::IsEnabled()) {
     authz_provider_.reset(new RangerAuthzProvider(master_->fs_manager()->env(),
                                                   master_->metric_entity()));
   } else {
diff --git a/src/kudu/master/default_authz_provider.h b/src/kudu/master/default_authz_provider.h
index 55b3311..46c181c 100644
--- a/src/kudu/master/default_authz_provider.h
+++ b/src/kudu/master/default_authz_provider.h
@@ -40,10 +40,6 @@
 
   void Stop() override {}
 
-  Status ResetCache() override {
-    return Status::NotSupported("provider does not have privileges cache");
-  }
-
   Status AuthorizeCreateTable(const std::string& /*table_name*/,
                               const std::string& /*user*/,
                               const std::string& /*owner*/) override WARN_UNUSED_RESULT {
diff --git a/src/kudu/master/master.proto b/src/kudu/master/master.proto
index 9a7dbc6..a4a2b32 100644
--- a/src/kudu/master/master.proto
+++ b/src/kudu/master/master.proto
@@ -937,15 +937,6 @@
   optional bytes replacement_tablet_id = 2;
 }
 
-// ResetAuthzCache{Request/Result}PB: reset the authz privileges cache,
-// clearing it of all existing entries.
-message ResetAuthzCacheRequestPB {
-}
-
-message ResetAuthzCacheResponsePB {
-  optional MasterErrorPB error = 1;
-}
-
 enum MasterFeatures {
   UNKNOWN_FEATURE = 0;
   // The master supports creating tables with non-covering range partitions.
@@ -1033,10 +1024,6 @@
   rpc ReplaceTablet(ReplaceTabletRequestPB) returns (ReplaceTabletResponsePB) {
     option (kudu.rpc.authz_method) = "AuthorizeSuperUser";
   }
-  rpc ResetAuthzCache(ResetAuthzCacheRequestPB) returns
-      (ResetAuthzCacheResponsePB) {
-    option (kudu.rpc.authz_method) = "AuthorizeSuperUser";
-  }
   rpc ChangeTServerState(ChangeTServerStateRequestPB) returns
       (ChangeTServerStateResponsePB) {
     option (kudu.rpc.authz_method) = "AuthorizeSuperUser";
diff --git a/src/kudu/master/master_service.cc b/src/kudu/master/master_service.cc
index b67cd02..3934c78 100644
--- a/src/kudu/master/master_service.cc
+++ b/src/kudu/master/master_service.cc
@@ -37,7 +37,6 @@
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/hms/hms_catalog.h"
-#include "kudu/master/authz_provider.h"
 #include "kudu/master/catalog_manager.h"
 #include "kudu/master/location_cache.h"
 #include "kudu/master/master.h"
@@ -721,17 +720,6 @@
   rpc->RespondSuccess();
 }
 
-void MasterServiceImpl::ResetAuthzCache(
-    const ResetAuthzCacheRequestPB* /* req */,
-    ResetAuthzCacheResponsePB* resp,
-    rpc::RpcContext* rpc) {
-  LOG(INFO) << Substitute("request to reset authz privileges cache from $0",
-                          rpc->requestor_string());
-  CheckRespErrorOrSetUnknown(
-      server_->catalog_manager()->authz_provider()->ResetCache(), resp);
-  rpc->RespondSuccess();
-}
-
 bool MasterServiceImpl::SupportsFeature(uint32_t feature) const {
   switch (feature) {
     case MasterFeatures::RANGE_PARTITION_BOUNDS:    FALLTHROUGH_INTENDED;
diff --git a/src/kudu/master/master_service.h b/src/kudu/master/master_service.h
index 4098ce7..00fbdad 100644
--- a/src/kudu/master/master_service.h
+++ b/src/kudu/master/master_service.h
@@ -71,8 +71,6 @@
 class PingResponsePB;
 class ReplaceTabletRequestPB;
 class ReplaceTabletResponsePB;
-class ResetAuthzCacheRequestPB;
-class ResetAuthzCacheResponsePB;
 class TSHeartbeatRequestPB;
 class TSHeartbeatResponsePB;
 
@@ -172,10 +170,6 @@
                      ReplaceTabletResponsePB* resp,
                      rpc::RpcContext* rpc) override;
 
-  void ResetAuthzCache(const ResetAuthzCacheRequestPB* req,
-                       ResetAuthzCacheResponsePB* resp,
-                       rpc::RpcContext* rpc) override;
-
   bool SupportsFeature(uint32_t feature) const override;
 
  private:
diff --git a/src/kudu/master/ranger_authz_provider.h b/src/kudu/master/ranger_authz_provider.h
index 6dabf33..e84e912 100644
--- a/src/kudu/master/ranger_authz_provider.h
+++ b/src/kudu/master/ranger_authz_provider.h
@@ -50,10 +50,6 @@
 
   void Stop() override {}
 
-  Status ResetCache() override {
-    return Status::NotSupported("Resetting cache is not supported with Ranger");
-  }
-
   Status AuthorizeCreateTable(const std::string& table_name,
                               const std::string& user,
                               const std::string& owner) override WARN_UNUSED_RESULT;
diff --git a/src/kudu/master/sentry_authz_provider-test-base.h b/src/kudu/master/sentry_authz_provider-test-base.h
deleted file mode 100644
index c60e367..0000000
--- a/src/kudu/master/sentry_authz_provider-test-base.h
+++ /dev/null
@@ -1,134 +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.
-
-#pragma once
-
-#include <set>
-#include <string>
-
-#include <gflags/gflags_declare.h>
-
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/sentry/mini_sentry.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/thrift/client.h"
-#include "kudu/util/test_macros.h"
-#include "kudu/util/test_util.h"
-
-DECLARE_string(server_name);
-
-namespace kudu {
-namespace master {
-
-inline Status DropRole(sentry::SentryClient* sentry_client,
-                       const std::string& role_name) {
-  ::sentry::TDropSentryRoleRequest role_req;
-  role_req.__set_requestorUserName("test-admin");
-  role_req.__set_roleName(role_name);
-  return sentry_client->DropRole(role_req);
-}
-
-inline Status CreateRoleAndAddToGroups(sentry::SentryClient* sentry_client,
-                                       const std::string& role_name,
-                                       const std::string& group_name) {
-  ::sentry::TCreateSentryRoleRequest role_req;
-  role_req.__set_requestorUserName("test-admin");
-  role_req.__set_roleName(role_name);
-  RETURN_NOT_OK(sentry_client->CreateRole(role_req));
-
-  ::sentry::TSentryGroup group;
-  group.groupName = group_name;
-  std::set<::sentry::TSentryGroup> groups;
-  groups.insert(group);
-  ::sentry::TAlterSentryRoleAddGroupsRequest group_request;
-  ::sentry::TAlterSentryRoleAddGroupsResponse group_response;
-  group_request.__set_requestorUserName("test-admin");
-  group_request.__set_roleName(role_name);
-  group_request.__set_groups(groups);
-  return sentry_client->AlterRoleAddGroups(group_request, &group_response);
-}
-
-inline Status AlterRoleGrantPrivilege(sentry::SentryClient* sentry_client,
-                                      const std::string& role_name,
-                                      const ::sentry::TSentryPrivilege& privilege) {
-  ::sentry::TAlterSentryRoleGrantPrivilegeRequest privilege_request;
-  ::sentry::TAlterSentryRoleGrantPrivilegeResponse privilege_response;
-  privilege_request.__set_requestorUserName("test-admin");
-  privilege_request.__set_roleName(role_name);
-  privilege_request.__set_privilege(privilege);
-  return sentry_client->AlterRoleGrantPrivilege(privilege_request, &privilege_response);
-}
-
-// Returns a server level TSentryPrivilege with the server name, action
-// and grant option.
-inline ::sentry::TSentryPrivilege GetServerPrivilege(
-    const std::string& action,
-    const ::sentry::TSentryGrantOption::type& grant_option =
-        ::sentry::TSentryGrantOption::DISABLED) {
-  ::sentry::TSentryPrivilege privilege;
-  privilege.__set_privilegeScope("SERVER");
-  privilege.__set_serverName(FLAGS_server_name);
-  privilege.__set_action(action);
-  privilege.__set_grantOption(grant_option);
-  return privilege;
-}
-
-// Returns a database level TSentryPrivilege with the given database name, action
-// and grant option.
-inline ::sentry::TSentryPrivilege GetDatabasePrivilege(
-    const std::string& db_name,
-    const std::string& action,
-    const ::sentry::TSentryGrantOption::type& grant_option =
-        ::sentry::TSentryGrantOption::DISABLED) {
-  ::sentry::TSentryPrivilege privilege = GetServerPrivilege(action, grant_option);
-  privilege.__set_privilegeScope("DATABASE");
-  privilege.__set_dbName(db_name);
-  return privilege;
-}
-
-// Returns a table level TSentryPrivilege with the given table name, database name,
-// action and grant option.
-inline ::sentry::TSentryPrivilege GetTablePrivilege(
-    const std::string& db_name,
-    const std::string& table_name,
-    const std::string& action,
-    const ::sentry::TSentryGrantOption::type& grant_option =
-        ::sentry::TSentryGrantOption::DISABLED) {
-  ::sentry::TSentryPrivilege privilege = GetDatabasePrivilege(db_name, action, grant_option);
-  privilege.__set_privilegeScope("TABLE");
-  privilege.__set_tableName(table_name);
-  return privilege;
-}
-
-// Returns a column level TSentryPrivilege with the given column name, table name,
-// database name, action and grant option.
-inline ::sentry::TSentryPrivilege GetColumnPrivilege(
-    const std::string& db_name,
-    const std::string& table_name,
-    const std::string& column_name,
-    const std::string& action,
-    const ::sentry::TSentryGrantOption::type& grant_option =
-        ::sentry::TSentryGrantOption::DISABLED) {
-  ::sentry::TSentryPrivilege privilege = GetTablePrivilege(db_name, table_name,
-                                                 action, grant_option);
-  privilege.__set_privilegeScope("COLUMN");
-  privilege.__set_columnName(column_name);
-  return privilege;
-}
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_authz_provider-test.cc b/src/kudu/master/sentry_authz_provider-test.cc
deleted file mode 100644
index 71a087b..0000000
--- a/src/kudu/master/sentry_authz_provider-test.cc
+++ /dev/null
@@ -1,1558 +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.
-
-#include "kudu/master/sentry_authz_provider.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <functional>
-#include <initializer_list>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <thread>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-#include <google/protobuf/stubs/port.h>
-#include <google/protobuf/util/message_differencer.h>
-#include <gtest/gtest.h>
-
-#include "kudu/common/common.pb.h"
-#include "kudu/common/schema.h"
-#include "kudu/common/wire_protocol.h"
-#include "kudu/gutil/integral_types.h"
-#include "kudu/gutil/macros.h"
-#include "kudu/gutil/map-util.h"
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/gutil/sysinfo.h"
-#include "kudu/master/sentry_authz_provider-test-base.h"
-#include "kudu/master/sentry_privileges_fetcher.h"
-#include "kudu/security/token.pb.h"
-#include "kudu/sentry/mini_sentry.h"
-#include "kudu/sentry/sentry-test-base.h"
-#include "kudu/sentry/sentry_action.h"
-#include "kudu/sentry/sentry_authorizable_scope.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
-#include "kudu/util/barrier.h"
-#include "kudu/util/flag_tags.h"
-#include "kudu/util/hdr_histogram.h"
-#include "kudu/util/logging.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/net/net_util.h"
-#include "kudu/util/pb_util.h"
-#include "kudu/util/random.h"
-#include "kudu/util/random_util.h"
-#include "kudu/util/status.h"
-#include "kudu/util/stopwatch.h"
-#include "kudu/util/test_macros.h"
-#include "kudu/util/test_util.h"
-#include "kudu/util/ttl_cache.h"
-
-DEFINE_int32(num_table_privileges, 100,
-    "Number of table privileges to use in testing");
-TAG_FLAG(num_table_privileges, hidden);
-
-DEFINE_int32(num_databases, 10,
-    "Number of databases to use in testing");
-TAG_FLAG(num_databases, hidden);
-
-DEFINE_int32(num_tables_per_db, 10,
-    "Number of tables to use per database to use in testing");
-TAG_FLAG(num_tables_per_db, hidden);
-
-DEFINE_bool(has_db_privileges, true,
-    "Whether the user should have db-level privileges in testing");
-TAG_FLAG(has_db_privileges, hidden);
-
-DECLARE_bool(sentry_require_db_privileges_for_list_tables);
-DECLARE_int32(sentry_service_recv_timeout_seconds);
-DECLARE_int32(sentry_service_send_timeout_seconds);
-DECLARE_uint32(sentry_privileges_cache_capacity_mb);
-DECLARE_string(sentry_service_rpc_addresses);
-DECLARE_string(server_name);
-DECLARE_string(trusted_user_acl);
-
-METRIC_DECLARE_counter(sentry_client_tasks_successful);
-METRIC_DECLARE_counter(sentry_client_tasks_failed_fatal);
-METRIC_DECLARE_counter(sentry_client_tasks_failed_nonfatal);
-METRIC_DECLARE_counter(sentry_client_reconnections_succeeded);
-METRIC_DECLARE_counter(sentry_client_reconnections_failed);
-METRIC_DECLARE_histogram(sentry_client_task_execution_time_us);
-
-METRIC_DECLARE_counter(sentry_privileges_cache_evictions);
-METRIC_DECLARE_counter(sentry_privileges_cache_evictions_expired);
-METRIC_DECLARE_counter(sentry_privileges_cache_hits);
-METRIC_DECLARE_counter(sentry_privileges_cache_hits_expired);
-METRIC_DECLARE_counter(sentry_privileges_cache_inserts);
-METRIC_DECLARE_counter(sentry_privileges_cache_lookups);
-METRIC_DECLARE_counter(sentry_privileges_cache_misses);
-METRIC_DECLARE_gauge_uint64(sentry_privileges_cache_memory_usage);
-
-using kudu::pb_util::SecureDebugString;
-using kudu::security::ColumnPrivilegePB;
-using kudu::security::TablePrivilegePB;
-using kudu::sentry::AuthorizableScopesSet;
-using kudu::sentry::SentryAction;
-using kudu::sentry::SentryActionsSet;
-using kudu::sentry::SentryTestBase;
-using kudu::sentry::SentryAuthorizableScope;
-using google::protobuf::util::MessageDifferencer;
-using sentry::TSentryAuthorizable;
-using sentry::TSentryGrantOption;
-using sentry::TSentryPrivilege;
-using std::string;
-using std::thread;
-using std::unique_ptr;
-using std::unordered_map;
-using std::unordered_set;
-using std::vector;
-using strings::Substitute;
-
-namespace kudu {
-namespace master {
-
-TEST(SentryAuthzProviderStaticTest, TestTrustedUserAcl) {
-  FLAGS_trusted_user_acl = "impala,hive,hdfs";
-  SentryAuthzProvider authz_provider;
-  ASSERT_TRUE(authz_provider.IsTrustedUser("impala"));
-  ASSERT_TRUE(authz_provider.IsTrustedUser("hive"));
-  ASSERT_TRUE(authz_provider.IsTrustedUser("hdfs"));
-  ASSERT_FALSE(authz_provider.IsTrustedUser("untrusted"));
-}
-
-// Basic unit test for validations on ill-formed privileges.
-TEST(SentryPrivilegesFetcherStaticTest, TestPrivilegesWellFormed) {
-  const string kDb = "db";
-  const string kTable = "table";
-  TSentryAuthorizable requested_authorizable;
-  requested_authorizable.__set_server(FLAGS_server_name);
-  requested_authorizable.__set_db(kDb);
-  requested_authorizable.__set_table(kTable);
-  TSentryPrivilege real_privilege = GetTablePrivilege(kDb, kTable, "ALL");
-  {
-    // Privilege with a bogus action set.
-    TSentryPrivilege privilege = real_privilege;
-    privilege.__set_action("NotAnAction");
-    ASSERT_FALSE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege, requested_authorizable, /*scope=*/nullptr, /*action=*/nullptr));
-  }
-  {
-    // Privilege with a bogus authorizable scope set.
-    TSentryPrivilege privilege = real_privilege;
-    privilege.__set_privilegeScope("NotAnAuthorizableScope");
-    ASSERT_FALSE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege, requested_authorizable, /*scope=*/nullptr, /*action=*/nullptr));
-  }
-  {
-    // Privilege with a valid, but unexpected scope for the set fields.
-    TSentryPrivilege privilege = real_privilege;
-    privilege.__set_privilegeScope("COLUMN");
-    ASSERT_FALSE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege, requested_authorizable, /*scope=*/nullptr, /*action=*/nullptr));
-  }
-  {
-    // Privilege with a messed up scope field at a higher scope than that
-    // requested.
-    TSentryPrivilege privilege = real_privilege;
-    privilege.__set_dbName("NotTheActualDb");
-    ASSERT_FALSE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege, requested_authorizable, /*scope=*/nullptr, /*action=*/nullptr));
-  }
-  {
-    // Privilege with an field set that isn't meant to be set at its scope.
-    TSentryPrivilege privilege = real_privilege;
-    privilege.__set_columnName("SomeColumn");
-    ASSERT_FALSE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege, requested_authorizable, /*scope=*/nullptr, /*action=*/nullptr));
-  }
-  {
-    // Privilege with a missing field for its scope.
-    TSentryPrivilege privilege = real_privilege;
-    privilege.__isset.tableName = false;
-    ASSERT_FALSE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege, requested_authorizable, /*scope=*/nullptr, /*action=*/nullptr));
-  }
-  {
-    // Finally, the correct table-level privilege.
-    SentryAuthorizableScope::Scope granted_scope;
-    SentryAction::Action granted_action;
-    real_privilege.printTo(LOG(INFO));
-    ASSERT_TRUE(SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        real_privilege, requested_authorizable, &granted_scope, &granted_action));
-    ASSERT_EQ(SentryAuthorizableScope::TABLE, granted_scope);
-    ASSERT_EQ(SentryAction::ALL, granted_action);
-  }
-}
-
-class SentryAuthzProviderTest : public SentryTestBase {
- public:
-  static const char* const kTestUser;
-  static const char* const kTrustedUser;
-  static const char* const kUserGroup;
-  static const char* const kRoleName;
-
-  void SetUp() override {
-    SentryTestBase::SetUp();
-
-    metric_entity_ = METRIC_ENTITY_server.Instantiate(
-        &metric_registry_, "sentry_auth_provider-test");
-
-    // Configure the SentryAuthzProvider flags.
-    FLAGS_sentry_privileges_cache_capacity_mb = CachingEnabled() ? 1 : 0;
-    FLAGS_sentry_service_rpc_addresses = sentry_->address().ToString();
-    FLAGS_trusted_user_acl = kTrustedUser;
-    sentry_authz_provider_.reset(new SentryAuthzProvider(metric_entity_));
-    ASSERT_OK(sentry_authz_provider_->Start());
-  }
-
-  bool KerberosEnabled() const override {
-    // The returned value corresponds to the actual setting of the
-    // --sentry_service_security_mode flag; now it's "kerberos" by default.
-    return true;
-  }
-
-  virtual bool CachingEnabled() const {
-    return true;
-  }
-
-  Status StopSentry() {
-    RETURN_NOT_OK(sentry_client_->Stop());
-    RETURN_NOT_OK(sentry_->Stop());
-    return Status::OK();
-  }
-
-  Status StartSentry() {
-    RETURN_NOT_OK(sentry_->Start());
-    RETURN_NOT_OK(sentry_client_->Start());
-    return Status::OK();
-  }
-
-  Status DropRole() {
-    RETURN_NOT_OK(kudu::master::DropRole(sentry_client_.get(), kRoleName));
-    return sentry_authz_provider_->fetcher_.ResetCache();
-  }
-
-  Status CreateRoleAndAddToGroups() {
-    RETURN_NOT_OK(kudu::master::CreateRoleAndAddToGroups(
-        sentry_client_.get(), kRoleName, kUserGroup));
-    return sentry_authz_provider_->fetcher_.ResetCache();
-  }
-
-  Status AlterRoleGrantPrivilege(const TSentryPrivilege& privilege) {
-    RETURN_NOT_OK(kudu::master::AlterRoleGrantPrivilege(
-        sentry_client_.get(), kRoleName, privilege));
-    return sentry_authz_provider_->fetcher_.ResetCache();
-  }
-
-#define GET_GAUGE_READINGS(func_name, counter_name_suffix) \
-  int64_t func_name() { \
-    scoped_refptr<Counter> gauge(metric_entity_->FindOrCreateCounter( \
-        &METRIC_sentry_client_##counter_name_suffix)); \
-    CHECK(gauge); \
-    return gauge->value(); \
-  }
-  GET_GAUGE_READINGS(GetTasksSuccessful, tasks_successful)
-  GET_GAUGE_READINGS(GetTasksFailedFatal, tasks_failed_fatal)
-  GET_GAUGE_READINGS(GetTasksFailedNonFatal, tasks_failed_nonfatal)
-  GET_GAUGE_READINGS(GetReconnectionsSucceeded, reconnections_succeeded)
-  GET_GAUGE_READINGS(GetReconnectionsFailed, reconnections_failed)
-#undef GET_GAUGE_READINGS
-
-#define GET_GAUGE_READINGS(func_name, counter_name_suffix) \
-  int64_t func_name() { \
-    scoped_refptr<Counter> gauge(metric_entity_->FindOrCreateCounter( \
-        &METRIC_sentry_privileges_##counter_name_suffix)); \
-    CHECK(gauge); \
-    return gauge->value(); \
-  }
-  GET_GAUGE_READINGS(GetCacheEvictions, cache_evictions)
-  GET_GAUGE_READINGS(GetCacheEvictionsExpired, cache_evictions_expired)
-  GET_GAUGE_READINGS(GetCacheHitsExpired, cache_hits_expired)
-  GET_GAUGE_READINGS(GetCacheHits, cache_hits)
-  GET_GAUGE_READINGS(GetCacheInserts, cache_inserts)
-  GET_GAUGE_READINGS(GetCacheLookups, cache_lookups)
-  GET_GAUGE_READINGS(GetCacheMisses, cache_misses)
-#undef GET_GAUGE_READINGS
-
-  int64_t GetCacheUsage() {
-    scoped_refptr<AtomicGauge<uint64>> gauge(metric_entity_->FindOrCreateGauge(
-        &METRIC_sentry_privileges_cache_memory_usage, static_cast<uint64>(0)));
-    CHECK(gauge);
-    return gauge->value();
-  }
-
- protected:
-  MetricRegistry metric_registry_;
-  scoped_refptr<MetricEntity> metric_entity_;
-  unique_ptr<SentryAuthzProvider> sentry_authz_provider_;
-};
-
-const char* const SentryAuthzProviderTest::kTestUser = "test-user";
-const char* const SentryAuthzProviderTest::kTrustedUser = "trusted-user";
-const char* const SentryAuthzProviderTest::kUserGroup = "user";
-const char* const SentryAuthzProviderTest::kRoleName = "developer";
-
-namespace {
-
-const SentryActionsSet kAllActions({
-  SentryAction::ALL,
-  SentryAction::METADATA,
-  SentryAction::SELECT,
-  SentryAction::INSERT,
-  SentryAction::UPDATE,
-  SentryAction::DELETE,
-  SentryAction::ALTER,
-  SentryAction::CREATE,
-  SentryAction::DROP,
-  SentryAction::OWNER,
-});
-
-} // anonymous namespace
-
-namespace {
-
-// Indicates different invalid privilege response types to be injected.
-enum class InvalidPrivilege {
-  // No error is injected.
-  NONE,
-
-  // The action string is set to something other than the expected action.
-  INCORRECT_ACTION,
-
-  // The scope string is set to something other than the expected scope.
-  INCORRECT_SCOPE,
-
-  // The 'serverName' field is set to something other than the authorizable's
-  // server name. Why just the server? This guarantees that a request for any
-  // authorizable scope will ignore such invalid privileges. E.g. say we
-  // instead granted an incorrect 'tableName'; assuming the dbName were still
-  // correct, a request at the database scope would correctly _not_ ignore the
-  // privilege. So to ensure that these InvalidPrivileges always yield
-  // privileges that are ignored, we exclusively butcher the 'server' field.
-  INCORRECT_SERVER,
-
-  // One of the scope fields (e.g. serverName, dbName, etc.) is unexpectedly
-  // missing or unexpectedly set. Note: Sentry servers don't allow an empty
-  // 'server' scope; if erasing the 'server' field, we'll instead set it to
-  // something other than the expected server.
-  FLIPPED_FIELD,
-};
-
-constexpr const char* kDb = "db";
-constexpr const char* kTable = "table";
-constexpr const char* kColumn = "column";
-
-} // anonymous namespace
-
-// Benchmark to test the time it takes to evaluate privileges when requesting
-// privileges for braod authorization scopes (e.g. SERVER, DATABASE).
-TEST_F(SentryAuthzProviderTest, BroadAuthzScopeBenchmark) {
-  const char* kLongDb = "DbWithLongName";
-  const char* kLongTable = "TableWithLongName";
-  ASSERT_OK(CreateRoleAndAddToGroups());
-
-  // Create a database with a bunch tables in it.
-  int kNumTables = FLAGS_num_table_privileges;
-  for (int i = 0; i < kNumTables; i++) {
-    KLOG_EVERY_N_SECS(INFO, 3) << Substitute("num tables granted: $0", i);
-    ASSERT_OK(AlterRoleGrantPrivilege(
-        GetTablePrivilege(kLongDb, Substitute("$0_$1", kLongTable, i), "OWNER")));
-  }
-
-  // Time how long it takes to get the database privileges via authorizing a
-  // create table request.
-  Status s;
-  LOG_TIMING(INFO, "Getting database privileges") {
-    s = sentry_authz_provider_->AuthorizeCreateTable(
-        Substitute("$0.$1_$2", kLongDb, kLongTable, 0) , kTestUser, kTestUser);
-  }
-  ASSERT_TRUE(s.IsNotAuthorized());
-}
-
-// Benchmark to test the time it takes to evaluate privileges when listing
-// tables.
-TEST_F(SentryAuthzProviderTest, ListTablesBenchmark) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  unordered_set<string> tables;
-  for (int d = 0; d < FLAGS_num_databases; d++) {
-    const string db_name = Substitute("$0_$1", kDb, d);
-    // Regardless of whether the user has database-level privileges on the
-    // database, make sure there's at least one privilege for a database to
-    // keep the benchmark consistent when toggling this flag.
-    const string dummy_name = Substitute("$0_$1", "foo", d);
-    ASSERT_OK(AlterRoleGrantPrivilege(
-        GetDatabasePrivilege(FLAGS_has_db_privileges ? db_name : dummy_name, "METADATA")));
-    for (int t = 0; t < FLAGS_num_tables_per_db; t++) {
-      const string table_name = Substitute("$0_$1", kTable, t);
-      const string table_ident = Substitute("$0.$1", db_name, table_name);
-
-      KLOG_EVERY_N_SECS(INFO, 3) << "Granted privilege on table: " << table_ident;
-      ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege(db_name, table_name, "METADATA")));
-      EmplaceOrDie(&tables, table_ident);
-    }
-  }
-  bool checked_table_names = false;
-  LOG_TIMING(INFO, "Listing tables") {
-    ASSERT_OK(sentry_authz_provider_->AuthorizeListTables(
-        kTestUser, &tables, &checked_table_names));
-  }
-  ASSERT_TRUE(checked_table_names);
-  ASSERT_EQ(FLAGS_num_databases * FLAGS_num_tables_per_db, tables.size());
-}
-
-TEST_F(SentryAuthzProviderTest, TestListTables) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  const int kNumDbs = 2;
-  const int kNumTablesPerDb = 5;
-  const int kNumNonHiveTables = 3;
-  unordered_set<string> tables;
-  for (int d = 0; d < kNumDbs; d++) {
-    const string db_name = Substitute("$0_$1", kDb, d);
-    for (int t = 0; t < kNumTablesPerDb; t++) {
-      const string table_name = Substitute("$0_$1", kTable, t);
-      // To test the absence of privileges, only grant privileges on one table
-      // per database.
-      if (t == 0) {
-        ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege(db_name, table_name, "METADATA")));
-      }
-      EmplaceOrDie(&tables, Substitute("$0.$1", db_name, table_name));
-    }
-  }
-  // Add some tables that don't conform to Hive's naming convention.
-  for (int i = 0; i < kNumNonHiveTables; i++) {
-    EmplaceOrDie(&tables, Substitute("badname_$0!", i));
-  }
-  bool checked_table_names = false;
-  // List tables as a trusted user. All tables, including non-Hive-conformant
-  // ones, should be visible.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeListTables(
-      kTrustedUser, &tables, &checked_table_names));
-  ASSERT_FALSE(checked_table_names);
-  ASSERT_EQ(kNumDbs * kNumTablesPerDb + kNumNonHiveTables, tables.size());
-
-  // Now try as a regular user. Only the tables with Hive-conformant names that
-  // the user has privileges on should be visible.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeListTables(kTestUser, &tables, &checked_table_names));
-  ASSERT_TRUE(checked_table_names);
-  ASSERT_EQ(kNumDbs, tables.size());
-
-  // When requires database level privileges for list tables, user shouldn't see
-  // any tables with only table level privileges.
-  FLAGS_sentry_require_db_privileges_for_list_tables = true;
-  ASSERT_OK(sentry_authz_provider_->AuthorizeListTables(kTestUser, &tables, &checked_table_names));
-  ASSERT_TRUE(checked_table_names);
-  ASSERT_EQ(0, tables.size());
-}
-
-class SentryAuthzProviderFilterPrivilegesTest : public SentryAuthzProviderTest {
- public:
-  SentryAuthzProviderFilterPrivilegesTest()
-      : prng_(SeedRandom()) {
-  }
-
-  void SetUp() override {
-    SentryAuthzProviderTest::SetUp();
-    ASSERT_OK(CreateRoleAndAddToGroups());
-    full_authorizable_.server = FLAGS_server_name;
-    full_authorizable_.db = kDb;
-    full_authorizable_.table = kTable;
-    full_authorizable_.column = kColumn;
-  }
-
-  // Creates a Sentry privilege for the user based on the given action,
-  // the given scope, and the given authorizable that has all scope fields set.
-  // With all of the scope fields set in the authorizable, and a given scope,
-  // we can return an appropriate privilege for it, with tweaks indicated by
-  // 'invalid_privilege' to make the privilege invalid if desired.
-  TSentryPrivilege CreatePrivilege(const TSentryAuthorizable& full_authorizable,
-                                   const SentryAuthorizableScope& scope, const SentryAction& action,
-                                   InvalidPrivilege invalid_privilege = InvalidPrivilege::NONE) {
-    DCHECK(!full_authorizable.server.empty() && !full_authorizable.db.empty() &&
-           !full_authorizable.table.empty() && !full_authorizable.column.empty());
-    TSentryPrivilege privilege;
-    privilege.__set_action(invalid_privilege == InvalidPrivilege::INCORRECT_ACTION ?
-                           "foobar" : ActionToString(action.action()));
-    privilege.__set_privilegeScope(invalid_privilege == InvalidPrivilege::INCORRECT_SCOPE ?
-                                   "foobar" : ScopeToString(scope.scope()));
-
-    // Select a scope at which we'll mess up the privilege request's field.
-    AuthorizableScopesSet nonempty_fields =
-        SentryPrivilegesFetcher::ExpectedNonEmptyFields(scope.scope());
-    if (invalid_privilege == InvalidPrivilege::FLIPPED_FIELD) {
-      static const AuthorizableScopesSet kMessUpCandidates = {
-        SentryAuthorizableScope::SERVER,
-        SentryAuthorizableScope::DATABASE,
-        SentryAuthorizableScope::TABLE,
-        SentryAuthorizableScope::COLUMN,
-      };
-      SentryAuthorizableScope::Scope field_to_mess_up =
-          SelectRandomElement<AuthorizableScopesSet, SentryAuthorizableScope::Scope, Random>(
-              kMessUpCandidates, &prng_);
-      if (ContainsKey(nonempty_fields, field_to_mess_up)) {
-        // Since Sentry servers don't allow empty 'server' fields in requests,
-        // rather flipping the empty status of the field, inject an incorrect
-        // value for the field.
-        if (field_to_mess_up == SentryAuthorizableScope::SERVER) {
-          invalid_privilege = InvalidPrivilege::INCORRECT_SERVER;
-        } else {
-          nonempty_fields.erase(field_to_mess_up);
-        }
-      } else {
-        InsertOrDie(&nonempty_fields, field_to_mess_up);
-      }
-    }
-
-    // Fill in any fields we may need.
-    for (const auto& field : nonempty_fields) {
-      switch (field) {
-        case SentryAuthorizableScope::SERVER:
-          privilege.__set_serverName(invalid_privilege == InvalidPrivilege::INCORRECT_SERVER ?
-                                     "foobar" : full_authorizable.server);
-          break;
-        case SentryAuthorizableScope::DATABASE:
-          privilege.__set_dbName(full_authorizable.db);
-          break;
-        case SentryAuthorizableScope::TABLE:
-          privilege.__set_tableName(full_authorizable.table);
-          break;
-        case SentryAuthorizableScope::COLUMN:
-          privilege.__set_columnName(full_authorizable.column);
-          break;
-        default:
-          LOG(FATAL) << "not a valid scope field: " << field;
-      }
-    }
-    return privilege;
-  }
- protected:
-  // Authorizable that has all scope fields set; useful for generating
-  // privilege requests.
-  TSentryAuthorizable full_authorizable_;
-
- private:
-  mutable Random prng_;
-};
-
-TEST_F(SentryAuthzProviderFilterPrivilegesTest, TestTablePrivilegePBParsing) {
-  constexpr int kNumColumns = 10;
-  SchemaBuilder schema_builder;
-  schema_builder.AddKeyColumn("col0", DataType::INT32);
-  vector<string> column_names = { "col0" };
-  for (int i = 1; i < kNumColumns; i++) {
-    const string col = Substitute("col$0", i);
-    schema_builder.AddColumn(ColumnSchema(col, DataType::INT32),
-                             /*is_key=*/false);
-    column_names.emplace_back(col);
-  }
-  SchemaPB schema_pb;
-  ASSERT_OK(SchemaToPB(schema_builder.Build(), &schema_pb));
-  unordered_map<string, ColumnId> col_name_to_id;
-  for (const auto& col_pb : schema_pb.columns()) {
-    EmplaceOrDie(&col_name_to_id, col_pb.name(), ColumnId(col_pb.id()));
-  }
-
-  // First, grant some privileges at the table authorizable scope or higher.
-  Random prng(SeedRandom());
-  vector<SentryAuthorizableScope::Scope> scope_to_grant_that_implies_table =
-      SelectRandomSubset<vector<SentryAuthorizableScope::Scope>,
-          SentryAuthorizableScope::Scope, Random>({ SentryAuthorizableScope::SERVER,
-                                                    SentryAuthorizableScope::DATABASE,
-                                                    SentryAuthorizableScope::TABLE }, 0, &prng);
-  unordered_map<SentryAuthorizableScope::Scope, SentryActionsSet, std::hash<int>>
-      granted_privileges;
-  SentryActionsSet table_privileges;
-  TSentryAuthorizable table_authorizable;
-  table_authorizable.__set_server(FLAGS_server_name);
-  table_authorizable.__set_db(kDb);
-  table_authorizable.__set_table(kTable);
-  table_authorizable.__set_column(column_names[0]);
-  for (const auto& granted_scope : scope_to_grant_that_implies_table) {
-    for (const auto& action : SelectRandomSubset<SentryActionsSet, SentryAction::Action, Random>(
-        kAllActions, 0, &prng)) {
-      // Grant the privilege to the user.
-      TSentryPrivilege table_privilege = CreatePrivilege(table_authorizable,
-          SentryAuthorizableScope(granted_scope), SentryAction(action));
-      ASSERT_OK(AlterRoleGrantPrivilege(table_privilege));
-
-      // All of the privileges imply the table-level action.
-      InsertIfNotPresent(&table_privileges, action);
-    }
-  }
-
-  // Grant some privileges at the column scope.
-  vector<string> columns_to_grant =
-      SelectRandomSubset<vector<string>, string, Random>(column_names, 0, &prng);
-  unordered_set<ColumnId> scannable_columns;
-  for (const auto& column_name : columns_to_grant) {
-    for (const auto& action : SelectRandomSubset<SentryActionsSet, SentryAction::Action, Random>(
-        kAllActions, 0, &prng)) {
-      // Grant the privilege to the user.
-      TSentryPrivilege column_privilege =
-          GetColumnPrivilege(kDb, kTable, column_name, ActionToString(action));
-      ASSERT_OK(AlterRoleGrantPrivilege(column_privilege));
-
-      if (SentryAction(action).Implies(SentryAction(SentryAction::SELECT))) {
-        InsertIfNotPresent(&scannable_columns, FindOrDie(col_name_to_id, column_name));
-      }
-    }
-  }
-
-  // Make sure that any implied privileges make their way to the token.
-  const string kTableId = "table-id";
-  TablePrivilegePB expected_pb;
-  expected_pb.set_table_id(kTableId);
-  for (const auto& granted_table_action : table_privileges) {
-    if (SentryAction(granted_table_action).Implies(SentryAction(SentryAction::INSERT))) {
-      expected_pb.set_insert_privilege(true);
-    }
-    if (SentryAction(granted_table_action).Implies(SentryAction(SentryAction::UPDATE))) {
-      expected_pb.set_update_privilege(true);
-    }
-    if (SentryAction(granted_table_action).Implies(SentryAction(SentryAction::DELETE))) {
-      expected_pb.set_delete_privilege(true);
-    }
-    if (SentryAction(granted_table_action).Implies(SentryAction(SentryAction::SELECT))) {
-      expected_pb.set_scan_privilege(true);
-    }
-  }
-
-  // If any of the table-level privileges imply privileges on scan, we
-  // shouldn't expect per-column scan privileges. Otherwise, we should expect
-  // the columns privileges that implied SELECT to have scan privileges.
-  if (!expected_pb.scan_privilege()) {
-    ColumnPrivilegePB scan_col_privilege;
-    scan_col_privilege.set_scan_privilege(true);
-    for (const auto& id : scannable_columns) {
-      InsertIfNotPresent(expected_pb.mutable_column_privileges(), id, scan_col_privilege);
-    }
-  }
-  // Validate the privileges went through.
-  TablePrivilegePB privilege_pb;
-  privilege_pb.set_table_id(kTableId);
-  ASSERT_OK(sentry_authz_provider_->FillTablePrivilegePB(Substitute("$0.$1", kDb, kTable),
-                                                         kTestUser, schema_pb, &privilege_pb));
-  ASSERT_TRUE(MessageDifferencer::Equals(expected_pb, privilege_pb))
-      << Substitute("$0 vs $1", SecureDebugString(expected_pb), SecureDebugString(privilege_pb));
-}
-
-// Parameterized on the scope at which the privilege will be granted.
-class SentryAuthzProviderFilterPrivilegesScopeTest :
-    public SentryAuthzProviderFilterPrivilegesTest,
-    public ::testing::WithParamInterface<SentryAuthorizableScope::Scope> {};
-
-// Attempt to grant privileges for various actions on a single scope of an
-// authorizable, injecting various invalid privileges, and checking that Kudu
-// ignores them.
-TEST_P(SentryAuthzProviderFilterPrivilegesScopeTest, TestFilterInvalidResponses) {
-  const string& table_ident = Substitute("$0.$1", full_authorizable_.db, full_authorizable_.table);
-  static constexpr InvalidPrivilege kInvalidPrivileges[] = {
-      InvalidPrivilege::INCORRECT_ACTION,
-      InvalidPrivilege::INCORRECT_SCOPE,
-      InvalidPrivilege::INCORRECT_SERVER,
-      InvalidPrivilege::FLIPPED_FIELD,
-  };
-  SentryAuthorizableScope granted_scope(GetParam());
-  for (const auto& action : kAllActions) {
-    for (const auto& ip : kInvalidPrivileges) {
-      TSentryPrivilege privilege = CreatePrivilege(full_authorizable_, granted_scope,
-                                                   SentryAction(action), ip);
-      ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-    }
-  }
-  for (const auto& requested_scope : { SentryAuthorizableScope::SERVER,
-                                       SentryAuthorizableScope::DATABASE,
-                                       SentryAuthorizableScope::TABLE }) {
-    SentryPrivilegesBranch privileges_info;
-    ASSERT_OK(sentry_authz_provider_->fetcher_.GetSentryPrivileges(
-        requested_scope, table_ident, kTestUser,
-        SentryCaching::ALL, &privileges_info));
-    // Kudu should ignore all of the invalid privileges.
-    ASSERT_TRUE(privileges_info.privileges().empty());
-  }
-}
-
-// Grants privileges for various actions on a single scope of an authorizable.
-TEST_P(SentryAuthzProviderFilterPrivilegesScopeTest, TestFilterValidResponses) {
-  const string& table_ident = Substitute("$0.$1", full_authorizable_.db, full_authorizable_.table);
-  SentryAuthorizableScope granted_scope(GetParam());
-  // Send valid requests and verify that we can get it back through the
-  // SentryAuthzProvider.
-  for (const auto& action : kAllActions) {
-    TSentryPrivilege privilege = CreatePrivilege(full_authorizable_, granted_scope,
-                                                 SentryAction(action));
-    ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  }
-  for (const auto& requested_scope : { SentryAuthorizableScope::SERVER,
-                                       SentryAuthorizableScope::DATABASE,
-                                       SentryAuthorizableScope::TABLE }) {
-    SentryPrivilegesBranch privileges_info;
-    ASSERT_OK(sentry_authz_provider_->fetcher_.GetSentryPrivileges(
-        requested_scope, table_ident, kTestUser,
-        SentryCaching::ALL, &privileges_info));
-    ASSERT_EQ(1, privileges_info.privileges().size());
-    const auto& authorizable_privileges = *privileges_info.privileges().cbegin();
-    ASSERT_EQ(GetParam(), authorizable_privileges.scope)
-        << ScopeToString(authorizable_privileges.scope);
-    ASSERT_FALSE(authorizable_privileges.allowed_actions.empty());
-  }
-}
-
-INSTANTIATE_TEST_CASE_P(GrantedScopes, SentryAuthzProviderFilterPrivilegesScopeTest,
-                        ::testing::Values(SentryAuthorizableScope::SERVER,
-                                          SentryAuthorizableScope::DATABASE,
-                                          SentryAuthorizableScope::TABLE,
-                                          SentryAuthorizableScope::COLUMN));
-
-// Test to create tables requiring ALL ON DATABASE with the grant option. This
-// is parameterized on the ALL scope and OWNER actions, which behave
-// identically.
-class CreateTableAuthorizationTest :
-    public SentryAuthzProviderTest,
-    public ::testing::WithParamInterface<string> {
-};
-
-TEST_P(CreateTableAuthorizationTest, TestAuthorizeCreateTable) {
-  // Don't authorize create table on a non-existent user.
-  Status s = sentry_authz_provider_->AuthorizeCreateTable("db.table",
-                                                          "non-existent-user",
-                                                          "non-existent-user");
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Don't authorize create table on a user without any privileges.
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Don't authorize create table on a user without required privileges.
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "DROP");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Authorize create table on a user with proper privileges.
-  privilege = GetDatabasePrivilege("db", "CREATE");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, kTestUser));
-
-  // Table creation with a different owner than the user
-  // requires the creating user have 'ALL on DATABASE' with grant.
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, "diff-user");
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  const auto& all = GetParam();
-  privilege = GetDatabasePrivilege("db", all);
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, "diff-user");
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  privilege = GetDatabasePrivilege("db", all, TSentryGrantOption::ENABLED);
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, "diff-user"));
-}
-
-INSTANTIATE_TEST_CASE_P(AllOrOwner, CreateTableAuthorizationTest,
-    ::testing::Values("ALL", "OWNER"));
-
-TEST_F(SentryAuthzProviderTest, TestAuthorizeDropTable) {
-  // Don't authorize delete table on a user without required privileges.
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "SELECT");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  Status s = sentry_authz_provider_->AuthorizeDropTable("db.table", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Authorize delete table on a user with proper privileges.
-  privilege = GetDatabasePrivilege("db", "DROP");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeDropTable("db.table", kTestUser));
-}
-
-TEST_F(SentryAuthzProviderTest, TestAuthorizeAlterTable) {
-  // Don't authorize alter table on a user without required privileges.
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege db_privilege = GetDatabasePrivilege("db", "SELECT");
-  ASSERT_OK(AlterRoleGrantPrivilege(db_privilege));
-  Status s = sentry_authz_provider_->AuthorizeAlterTable("db.table", "db.table", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Authorize alter table without rename on a user with proper privileges.
-  db_privilege = GetDatabasePrivilege("db", "ALTER");
-  ASSERT_OK(AlterRoleGrantPrivilege(db_privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable("db.table", "db.table", kTestUser));
-
-  // Table alteration with rename requires 'ALL ON TABLE <old-table>' and
-  // 'CREATE ON DATABASE <new-database>'
-  s = sentry_authz_provider_->AuthorizeAlterTable("db.table", "new_db.new_table", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Authorize alter table without rename on a user with proper privileges.
-  db_privilege = GetDatabasePrivilege("new_db", "CREATE");
-  ASSERT_OK(AlterRoleGrantPrivilege(db_privilege));
-  TSentryPrivilege table_privilege = GetTablePrivilege("db", "table", "ALL");
-  ASSERT_OK(AlterRoleGrantPrivilege(table_privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable("db.table",
-                                                        "new_db.new_table",
-                                                        kTestUser));
-}
-
-TEST_F(SentryAuthzProviderTest, TestAuthorizeGetTableStatistics) {
-  // Don't authorize getting statistics of a table for a user without required
-  // privileges.
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  Status s = sentry_authz_provider_->AuthorizeGetTableStatistics("db.table", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Authorize get table statistics on a user with proper privileges.
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "SELECT");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableStatistics("db.table", kTestUser));
-}
-
-TEST_F(SentryAuthzProviderTest, TestAuthorizeGetTableMetadata) {
-  // Don't authorize getting metadata on a table for a user without required
-  // privileges.
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  Status s = sentry_authz_provider_->AuthorizeGetTableMetadata("db.table", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Authorize getting metadata on a table for a user with proper privileges.
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "SELECT");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableMetadata("db.table", kTestUser));
-}
-
-TEST_F(SentryAuthzProviderTest, TestInvalidAction) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "invalid");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  // User has privileges with invalid action cannot operate on the table.
-  Status s = sentry_authz_provider_->AuthorizeCreateTable("DB.table", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-}
-
-TEST_F(SentryAuthzProviderTest, TestInvalidAuthzScope) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "ALL");
-  privilege.__set_privilegeScope("invalid");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  // User has privileges with invalid authorizable scope cannot operate
-  // on the table.
-  Status s = sentry_authz_provider_->AuthorizeCreateTable("DB.table", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-}
-
-// Ensures Sentry privileges are case insensitive.
-TEST_F(SentryAuthzProviderTest, TestPrivilegeCaseSensitivity) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "create");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeCreateTable("DB.table", kTestUser, kTestUser));
-}
-
-// Verify the behavior of the SentryAuthzProvider's cache upon fetching
-// privilege information on authorizables of the TABLE scope in
-// 'adjacent branches' of the authz hierarchy.
-TEST_F(SentryAuthzProviderTest, CacheBehaviorScopeHierarchyAdjacentBranches) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  ASSERT_OK(AlterRoleGrantPrivilege(GetDatabasePrivilege("db", "METADATA")));
-  ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege("db", "t0", "ALTER")));
-  ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege("db", "t1", "ALTER")));
-
-  // ALTER TABLE, if not renaming the table itself, requires ALTER privilege
-  // on the table, but nothing is required on the database that contains
-  // the table.
-  ASSERT_EQ(0, GetTasksSuccessful());
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t0", "db.t0", kTestUser));
-  ASSERT_EQ(1, GetTasksSuccessful());
-
-  // The cache was empty. The query was for TABLE scope privileges, so the
-  // cache was examined for both DATABASE and TABLE scope entries, and both
-  // were missing. After fetching information on privileges granted to the user
-  // on table 'db.t0', the information received from Sentry was split and put
-  // into DATABASE and TABLE scope entries.
-  ASSERT_EQ(2, GetCacheLookups());
-  ASSERT_EQ(2, GetCacheMisses());
-  ASSERT_EQ(0, GetCacheHits());
-  ASSERT_EQ(2, GetCacheInserts());
-
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t1", "db.t1", kTestUser));
-  // Information on the user's privileges granted on 'db.t1' was not present
-  // in the cache: there was an RPC request sent to Sentry.
-  ASSERT_EQ(2, GetTasksSuccessful());
-
-  // One more cache miss: TABLE scope entry for 'db.t1' was absent.
-  ASSERT_EQ(3, GetCacheMisses());
-  // One more cache hit: DATABASE scope entry was already present.
-  ASSERT_EQ(1, GetCacheHits());
-  // Updated already existing DATABASE and inserted new TABLE entry.
-  ASSERT_EQ(4, GetCacheInserts());
-
-  // METADATA requires corresponding privilege granted on the table, but nothing
-  // is required on the database.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableMetadata(
-      "db.other_table", kTestUser));
-  ASSERT_EQ(3, GetTasksSuccessful());
-
-  // One more cache miss: TABLE scope entry for 'db.other_table' was absent.
-  ASSERT_EQ(4, GetCacheMisses());
-  // One more cache hit: DATABASE scope entry was already present.
-  ASSERT_EQ(2, GetCacheHits());
-  // Updated already existing DATABASE and inserted new TABLE entry.
-  ASSERT_EQ(6, GetCacheInserts());
-
-  // Repeat all the requests above: not a single new RPC to Sentry should be
-  // sent since all authz queries must hit the cache: that's about repeating
-  // the same requests.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t0", "db.t0", kTestUser));
-  ASSERT_EQ(4, GetCacheHits());
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t1", "db.t1", kTestUser));
-  ASSERT_EQ(6, GetCacheHits());
-  ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableMetadata(
-      "db.other_table", kTestUser));
-  ASSERT_EQ(8, GetCacheHits());
-  // No new cache misses.
-  ASSERT_EQ(4, GetCacheMisses());
-  // No additional inserts, of course.
-  ASSERT_EQ(6, GetCacheInserts());
-  // No additional RPC requests to Sentry.
-  ASSERT_EQ(3, GetTasksSuccessful());
-
-  // All the requests below should also hit the cache since the information on
-  // the privileges granted on each of the tables in the requests below
-  // is in the cache. In the Sentry's privileges model for Kudu, DROP TABLE
-  // requires privileges on the table itself, but nothing is required on the
-  // database the table belongs to.
-  Status s = sentry_authz_provider_->AuthorizeDropTable("db.t0", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(10, GetCacheHits());
-  s = sentry_authz_provider_->AuthorizeDropTable("db.t1", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(12, GetCacheHits());
-  s = sentry_authz_provider_->AuthorizeDropTable("db.other_table", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(14, GetCacheHits());
-  // No new cache misses.
-  ASSERT_EQ(4, GetCacheMisses());
-  // No additional inserts, of course.
-  ASSERT_EQ(6, GetCacheInserts());
-  // No additional RPC requests to Sentry.
-  ASSERT_EQ(3, GetTasksSuccessful());
-
-  // A sanity check: verify no failed requests are registered.
-  ASSERT_EQ(0, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-}
-
-// Ensure requests to authorize CreateTables and AlterTables hit cache once
-// the information was fetched from Sentry for an authorizable of the TABLE
-// scope in the same hierarchy branch. A bit of context: Sentry sends all
-// available information for the branch up the authz scope hierarchy.
-TEST_F(SentryAuthzProviderTest, CacheBehaviorForCreateAndAlter) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  ASSERT_OK(AlterRoleGrantPrivilege(GetDatabasePrivilege("db0", "ALTER")));
-  ASSERT_OK(AlterRoleGrantPrivilege(GetDatabasePrivilege("db1", "CREATE")));
-  ASSERT_EQ(0, GetTasksSuccessful());
-
-  // ALTER TABLE, if not renaming the table itself, requires privileges on the
-  // table only.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db0.t0", "db0.t0", kTestUser));
-  ASSERT_EQ(1, GetTasksSuccessful());
-
-  // The cache was empty. The query was for TABLE scope privileges, so the
-  // cache was examined for both DATABASE and TABLE scope entries, and both
-  // were missing. After fetching information on privileges granted to the user
-  // on table 'db.t0', the information received from Sentry was split and put
-  // into DATABASE and TABLE scope entries.
-  ASSERT_EQ(2, GetCacheLookups());
-  ASSERT_EQ(2, GetCacheMisses());
-  ASSERT_EQ(0, GetCacheHits());
-  ASSERT_EQ(2, GetCacheInserts());
-
-  // The CREATE privileges is not granted on the 'db0', so the request must
-  // not be authorized.
-  auto s = sentry_authz_provider_->AuthorizeCreateTable(
-      "db0.t1", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized());
-  // CREATE TABLE requires privileges on the database only, and those should
-  // have been cached already due to the prior request.
-  ASSERT_EQ(1, GetTasksSuccessful());
-
-  // One more cache lookup of the corresponding DATABASE scope key.
-  ASSERT_EQ(3, GetCacheLookups());
-  // No new cache misses.
-  ASSERT_EQ(2, GetCacheMisses());
-  // Single cache lookup turned to be a cache hit.
-  ASSERT_EQ(1, GetCacheHits());
-
-  // No new RPCs to Sentry should be issued: the information on privileges
-  // on 'db1' authorizable of the DATABASE scope should be fetched and cached
-  // while fetching the information privileges on 'db1.t0' authorizable of the
-  // TABLE scope.
-  for (int idx = 0; idx < 10; ++idx) {
-    const auto table_name = Substitute("db1.t$0", idx);
-    ASSERT_OK(sentry_authz_provider_->AuthorizeCreateTable(
-        table_name, kTestUser, kTestUser));
-  }
-  // Only a single new RPC should be issued to Sentry: to get information
-  // for "db1" authorizable of the DATABASE scope while authorizing the creation
-  // of table "db1.t0". All other requests must hit the cache.
-  ASSERT_EQ(2, GetTasksSuccessful());
-
-  // Ten more cache lookups of the corresponding DATABASE scope key: one turned
-  // to be a miss and other nine hits after the information was fetched
-  // from Sentry and inserted into the cache.
-  ASSERT_EQ(13, GetCacheLookups());
-  ASSERT_EQ(3, GetCacheMisses());
-  ASSERT_EQ(10, GetCacheHits());
-  // One more insert: adding an entry for the DATABASE scope key for 'db1'.
-  ASSERT_EQ(3, GetCacheInserts());
-
-  // Same story for requests for 'db1.t0', ..., 'db1.t19'.
-  for (int idx = 0; idx < 20; ++idx) {
-    const auto table_name = Substitute("db1.t$0", idx);
-    ASSERT_OK(sentry_authz_provider_->AuthorizeCreateTable(
-        table_name, kTestUser, kTestUser));
-  }
-  ASSERT_EQ(2, GetTasksSuccessful());
-
-  // All twenty lookups hit the cache, no new misses.
-  ASSERT_EQ(33, GetCacheLookups());
-  ASSERT_EQ(30, GetCacheHits());
-  ASSERT_EQ(3, GetCacheMisses());
-
-  // A sanity check: verify no failed requests are registered.
-  ASSERT_EQ(0, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-}
-
-// A scenario where a TABLE-scope privilege on a table is granted to a user,
-// but there isn't any DATABASE-scope privilege granted on the database
-// the table belongs to. After authorizing an operation on the table, there
-// should not be another RPC to Sentry issued while authorizing an operation
-// on the database itself.
-TEST_F(SentryAuthzProviderTest, CacheBehaviorHybridLookups) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege("db", "t", "ALL")));
-
-  ASSERT_EQ(0, GetTasksSuccessful());
-  // In the Sentry's authz model for Kudu, DROP TABLE requires only privileges
-  // on the table itself.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeDropTable("db.t", kTestUser));
-  ASSERT_EQ(1, GetTasksSuccessful());
-
-  // The cache was empty. The query was for TABLE scope privileges, so the
-  // cache was examined for both DATABASE and TABLE scope entries, and both
-  // were missing. After fetching information on privileges granted to the user
-  // on table 'db.t', the information received from Sentry was split and put
-  // into DATABASE and TABLE scope entries.
-  ASSERT_EQ(0, GetCacheHits());
-  ASSERT_EQ(2, GetCacheLookups());
-  ASSERT_EQ(2, GetCacheMisses());
-  ASSERT_EQ(2, GetCacheInserts());
-
-  // CREATE TABLE requires privileges only on the database itself. No privileges
-  // are granted on the database, so the request must not be authorized.
-  auto s = sentry_authz_provider_->AuthorizeCreateTable(
-      "db.t", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  // No extra RPC should be sent to Sentry: the information on the privileges
-  // granted on relevant authorizables of the DATABASE scope in corresponding
-  // branch should have been fetched and cached.
-  ASSERT_EQ(1, GetTasksSuccessful());
-  // One more lookup in the cache that turned to a cache hit: it was necessary
-  // to lookup only DATABASE scope entry in the cache.
-  ASSERT_EQ(3, GetCacheLookups());
-  ASSERT_EQ(1, GetCacheHits());
-
-  // ALTER TABLE, if renaming the table, requires privileges both on the
-  // database and the table. Even if ALL is granted on the table itself, there
-  // isn't any privilege granted on the database, so the request to rename
-  // the table must not be authorized.
-  s = sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t", "db.t_renamed", kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  // No extra RPCs are expected in this case.
-  ASSERT_EQ(1, GetTasksSuccessful());
-  // Three more lookups; three more cache hits: DATABASE and TABLE lookups
-  // are 'db.t'-related, and DATABASE lookup is 'db.t_renamed' related.
-  ASSERT_EQ(6, GetCacheLookups());
-  ASSERT_EQ(4, GetCacheHits());
-
-  // A sanity check: verify no failed requests are registered.
-  ASSERT_EQ(0, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-}
-
-// Verify that information on TABLE-scope privileges are fetched from Sentry,
-// but not cached when SentryPrivilegeFetcher receives a ListPrivilegesByUser
-// response for a DATABASE-scope authorizable for CreateTables or AlterTables.
-TEST_F(SentryAuthzProviderTest, CacheBehaviorNotCachingTableInfo) {
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  ASSERT_OK(AlterRoleGrantPrivilege(GetDatabasePrivilege("db", "CREATE")));
-  ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege("db", "t0", "ALL")));
-  ASSERT_OK(AlterRoleGrantPrivilege(GetTablePrivilege("db", "t1", "ALTER")));
-
-  ASSERT_EQ(0, GetTasksSuccessful());
-  // In the Sentry's authz model for Kudu, CREATE TABLE requires only privileges
-  // on the database.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeCreateTable(
-      "db.table", kTestUser, kTestUser));
-  ASSERT_EQ(1, GetTasksSuccessful());
-  ASSERT_EQ(1, GetCacheInserts());
-  ASSERT_EQ(1, GetCacheLookups());
-  ASSERT_EQ(1, GetCacheMisses());
-
-  // Examine the entry that has just been cached: it should not contain
-  // any information on authorizables of the TABLE scope under the 'db':
-  // the cache chops off everything of the TABLE and narrower scope from
-  // Sentry response before adding corresponding entry into the cache.
-  auto* cache = sentry_authz_provider_->fetcher_.cache_.get();
-  ASSERT_NE(nullptr, cache);
-  {
-    auto handle = cache->Get(
-        Substitute("$0/$1/$2", kTestUser, FLAGS_server_name, "db"));
-    ASSERT_TRUE(handle);
-    ASSERT_EQ(2, GetCacheLookups());
-    ASSERT_EQ(1, GetCacheHits());
-
-    const auto& value = handle.value();
-    for (const auto& privilege : value.privileges()) {
-      ASSERT_NE(SentryAuthorizableScope::TABLE, privilege.scope);
-      ASSERT_NE(SentryAuthorizableScope::COLUMN, privilege.scope);
-    }
-  }
-
-  // ALTER TABLE, if not renaming the table, requires privileges only on the
-  // table itself.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t0", "db.t0", kTestUser));
-  // Here an RPC request should be sent to Sentry to fetch information on
-  // privileges granted at the table 'db.t0'. That information was fetched
-  // from Sentry upon prior call to AuthorizeCreateTable(), but it was not
-  // cached deliberately: that way the cache avoids storing information on
-  // non-Kudu tables, if any, under an authorizable of the DATABASE scope.
-  ASSERT_EQ(2, GetTasksSuccessful());
-  ASSERT_EQ(2, GetCacheMisses());
-  // Two more lookups: one DATABASE scope and another TABLE scope lookup.
-  ASSERT_EQ(4, GetCacheLookups());
-  // Inserted DATABASE and TABLE entries.
-  ASSERT_EQ(3, GetCacheInserts());
-
-  // The same as above stays valid for the 'db.t1' table.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeAlterTable(
-      "db.t1", "db.t1", kTestUser));
-  ASSERT_EQ(3, GetTasksSuccessful());
-  ASSERT_EQ(3, GetCacheMisses());
-  // Two more lookups: one DATABASE scope and another TABLE scope lookup.
-  ASSERT_EQ(6, GetCacheLookups());
-  // Updated already existing DATABASE and inserted new TABLE entry.
-  ASSERT_EQ(5, GetCacheInserts());
-
-  // A sanity check: verify no failed requests are registered.
-  ASSERT_EQ(0, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-}
-
-// Whether the authz information received from Sentry is cached or not.
-enum class AuthzCaching {
-  Disabled,
-  Enabled,
-};
-
-// Tests to ensure SentryAuthzProvider enforces access restrictions as expected.
-// Parameterized by whether caching is enabled.
-class SentryAuthzProviderReconnectionTest :
-    public SentryAuthzProviderTest,
-    public ::testing::WithParamInterface<AuthzCaching> {
- public:
-  bool CachingEnabled() const override {
-    return GetParam() == AuthzCaching::Enabled;
-  }
-};
-INSTANTIATE_TEST_CASE_P(
-    , SentryAuthzProviderReconnectionTest,
-    ::testing::Values(AuthzCaching::Disabled, AuthzCaching::Enabled));
-
-// Checks that the SentryAuthzProvider handles reconnecting to Sentry
-// after a connection failure, or service being too busy.
-TEST_P(SentryAuthzProviderReconnectionTest, ConnectionFailureOrTooBusy) {
-  // Restart SentryAuthzProvider with configured timeout to reduce the run time
-  // of this test.
-  NO_FATALS(sentry_authz_provider_->Stop());
-  FLAGS_sentry_service_rpc_addresses = sentry_->address().ToString();
-  FLAGS_sentry_service_send_timeout_seconds = AllowSlowTests() ? 5 : 2;
-  FLAGS_sentry_service_recv_timeout_seconds = AllowSlowTests() ? 5 : 2;
-  sentry_authz_provider_.reset(new SentryAuthzProvider);
-  ASSERT_OK(sentry_authz_provider_->Start());
-
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  TSentryPrivilege privilege = GetDatabasePrivilege("db", "METADATA");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableMetadata("db.table", kTestUser));
-
-  // Shutdown Sentry and try a few operations.
-  ASSERT_OK(StopSentry());
-
-  Status s = sentry_authz_provider_->AuthorizeDropTable("db.table", kTestUser);
-  if (CachingEnabled()) {
-    EXPECT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  } else {
-    EXPECT_TRUE(s.IsNetworkError()) << s.ToString();
-  }
-
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table", kTestUser, "diff-user");
-  if (CachingEnabled()) {
-    EXPECT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  } else {
-    EXPECT_TRUE(s.IsNetworkError()) << s.ToString();
-  }
-
-  // Start Sentry back up and ensure that the same operations succeed.
-  ASSERT_OK(StartSentry());
-  ASSERT_EVENTUALLY([&] {
-    ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableMetadata(
-        "db.table", kTestUser));
-  });
-
-  privilege = GetDatabasePrivilege("db", "DROP");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-  ASSERT_OK(sentry_authz_provider_->AuthorizeDropTable("db.table", kTestUser));
-
-  // Pause Sentry and try a few operations.
-  ASSERT_OK(sentry_->Pause());
-
-  s = sentry_authz_provider_->AuthorizeDropTable("db.table", kTestUser);
-  if (CachingEnabled()) {
-    EXPECT_TRUE(s.ok()) << s.ToString();
-  } else {
-    EXPECT_TRUE(s.IsTimedOut()) << s.ToString();
-  }
-
-  s = sentry_authz_provider_->AuthorizeGetTableMetadata("db.table", kTestUser);
-  if (CachingEnabled()) {
-    EXPECT_TRUE(s.ok()) << s.ToString();
-  } else {
-    EXPECT_TRUE(s.IsTimedOut()) << s.ToString();
-  }
-
-  // Resume Sentry and ensure that the same operations succeed.
-  ASSERT_OK(sentry_->Resume());
-  ASSERT_EVENTUALLY([&] {
-    ASSERT_OK(sentry_authz_provider_->AuthorizeDropTable(
-        "db.table", kTestUser));
-  });
-}
-
-// Test to ensure the authorization hierarchy rule of SentryAuthzProvider
-// works as expected.
-class TestAuthzHierarchy :
-    public SentryAuthzProviderTest,
-    public ::testing::WithParamInterface<SentryAuthorizableScope::Scope> {
-};
-
-TEST_P(TestAuthzHierarchy, TestAuthorizableScope) {
-  const SentryAuthorizableScope::Scope scope = GetParam();
-  const string action = "ALL";
-  const string db = "database";
-  const string tbl = "table";
-  const string col = "col";
-  vector<TSentryPrivilege> lower_hierarchy_privs;
-  vector<TSentryPrivilege> higher_hierarchy_privs;
-  const TSentryPrivilege column_priv = GetColumnPrivilege(db, tbl, col, action);
-  const TSentryPrivilege table_priv = GetTablePrivilege(db, tbl, action);
-  const TSentryPrivilege db_priv = GetDatabasePrivilege(db, action);
-  const TSentryPrivilege server_priv = GetServerPrivilege(action);
-
-  switch (scope) {
-    case SentryAuthorizableScope::Scope::TABLE:
-      higher_hierarchy_privs.emplace_back(table_priv);
-      FALLTHROUGH_INTENDED;
-    case SentryAuthorizableScope::Scope::DATABASE:
-      higher_hierarchy_privs.emplace_back(db_priv);
-      FALLTHROUGH_INTENDED;
-    case SentryAuthorizableScope::Scope::SERVER:
-      higher_hierarchy_privs.emplace_back(server_priv);
-      break;
-    default:
-      break;
-  }
-
-  switch (scope) {
-    case SentryAuthorizableScope::Scope::SERVER:
-      lower_hierarchy_privs.emplace_back(db_priv);
-      FALLTHROUGH_INTENDED;
-    case SentryAuthorizableScope::Scope::DATABASE:
-      lower_hierarchy_privs.emplace_back(table_priv);
-      FALLTHROUGH_INTENDED;
-    case SentryAuthorizableScope::Scope::TABLE:
-      lower_hierarchy_privs.emplace_back(column_priv);
-      break;
-    default:
-      break;
-  }
-
-  // Privilege with higher scope on the hierarchy can imply privileges
-  // with lower scope on the hierarchy.
-  for (const auto& privilege : higher_hierarchy_privs) {
-    ASSERT_OK(CreateRoleAndAddToGroups());
-    ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-    ASSERT_OK(sentry_authz_provider_->Authorize(scope, SentryAction::Action::ALL,
-                                                Substitute("$0.$1", db, tbl), kTestUser));
-    ASSERT_OK(DropRole());
-  }
-
-  // Privilege with lower scope on the hierarchy cannot imply privileges
-  // with higher scope on the hierarchy.
-  for (const auto& privilege : lower_hierarchy_privs) {
-    ASSERT_OK(CreateRoleAndAddToGroups());
-    ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-    Status s = sentry_authz_provider_->Authorize(scope, SentryAction::Action::ALL,
-                                                 Substitute("$0.$1", db, tbl), kTestUser);
-    ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-    ASSERT_OK(DropRole());
-  }
-}
-
-INSTANTIATE_TEST_CASE_P(AuthzCombinations, TestAuthzHierarchy,
-    // Scope::COLUMN is excluded since column scope for table
-    // authorizable doesn't make sense.
-    ::testing::Values(SentryAuthorizableScope::Scope::SERVER,
-                      SentryAuthorizableScope::Scope::DATABASE,
-                      SentryAuthorizableScope::Scope::TABLE));
-
-// Test to verify the functionality of metrics in HA Sentry client used in
-// SentryAuthzProvider to communicate with Sentry.
-class TestSentryClientMetrics : public SentryAuthzProviderTest {
- public:
-  bool CachingEnabled() const override {
-    // For simplicity, scenarios of this test doesn't use caching. The scenarios
-    // track updates of HaClient metrics upon issuing RPCs to Sentry.
-    return false;
-  }
-};
-
-TEST_F(TestSentryClientMetrics, Basic) {
-  ASSERT_EQ(0, GetTasksSuccessful());
-  ASSERT_EQ(0, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-  ASSERT_EQ(0, GetReconnectionsSucceeded());
-  ASSERT_EQ(0, GetReconnectionsFailed());
-
-  Status s = sentry_authz_provider_->AuthorizeCreateTable("db.table",
-                                                          kTestUser, kTestUser);
-  // The call should be counted as successful, and the client should connect
-  // to Sentry (counted as reconnect).
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(1, GetTasksSuccessful());
-  ASSERT_EQ(0, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-  ASSERT_EQ(1, GetReconnectionsSucceeded());
-  ASSERT_EQ(0, GetReconnectionsFailed());
-
-  // Stop Sentry, and try the same call again. There should be a fatal error
-  // reported, and then there should be failed reconnection attempts.
-  ASSERT_OK(StopSentry());
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table",
-                                                   kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
-  ASSERT_EQ(1, GetTasksSuccessful());
-  ASSERT_EQ(1, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-  ASSERT_LE(1, GetReconnectionsFailed());
-  ASSERT_EQ(1, GetReconnectionsSucceeded());
-
-  ASSERT_OK(StartSentry());
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table",
-                                                   kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(2, GetTasksSuccessful());
-  ASSERT_EQ(1, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-  ASSERT_EQ(2, GetReconnectionsSucceeded());
-
-  // NotAuthorized() from Sentry itself considered as a fatal error.
-  // TODO(KUDU-2769): clarify whether it is a bug in HaClient or Sentry itself?
-  s = sentry_authz_provider_->AuthorizeCreateTable("db.table",
-                                                   "nobody", "nobody");
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(2, GetTasksSuccessful());
-  ASSERT_EQ(2, GetTasksFailedFatal());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-  // Once a new fatal error is registered, the client should reconnect.
-  ASSERT_EQ(3, GetReconnectionsSucceeded());
-
-  // Shorten the default timeout parameters: make timeout interval shorter.
-  NO_FATALS(sentry_authz_provider_->Stop());
-  FLAGS_sentry_service_rpc_addresses = sentry_->address().ToString();
-  FLAGS_sentry_service_send_timeout_seconds = 2;
-  FLAGS_sentry_service_recv_timeout_seconds = 2;
-  sentry_authz_provider_.reset(new SentryAuthzProvider(metric_entity_));
-  ASSERT_OK(sentry_authz_provider_->Start());
-
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  const auto privilege = GetDatabasePrivilege("db", "create");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-
-  // Pause Sentry and try to send an RPC, expecting it to time out.
-  ASSERT_OK(sentry_->Pause());
-  s = sentry_authz_provider_->AuthorizeCreateTable(
-      "db.table", kTestUser, kTestUser);
-  ASSERT_TRUE(s.IsTimedOut());
-  ASSERT_OK(sentry_->Resume());
-
-  scoped_refptr<Histogram> hist(metric_entity_->FindOrCreateHistogram(
-      &METRIC_sentry_client_task_execution_time_us));
-  ASSERT_LT(0, hist->histogram()->MinValue());
-  // Change the threshold to 1900000 in case of very unstable system clock
-  // and other scheduler anomalies of the OS scheduler.
-  ASSERT_LT(1900000, hist->histogram()->MaxValue());
-  ASSERT_LE(5, hist->histogram()->TotalCount());
-  ASSERT_LT(1900000, hist->histogram()->TotalSum());
-}
-
-enum class ThreadsNumPolicy {
-  CloseToCPUsNum,
-  MoreThanCPUsNum,
-};
-
-// Test to ensure concurrent requests to Sentry with the same set of parameters
-// are accumulated by SentryAuthzProvider, so in total there is less RPC
-// requests sent to Sentry than the total number of concurrent requests to
-// the provider (ideally, there should be just single request to Sentry).
-class TestConcurrentRequests :
-    public SentryAuthzProviderTest,
-    public ::testing::WithParamInterface<std::tuple<ThreadsNumPolicy,
-                                                    AuthzCaching>> {
- public:
-  bool CachingEnabled() const override {
-    return std::get<1>(GetParam()) == AuthzCaching::Enabled;
-  }
-};
-
-// Verify how multiple concurrent requests are handled when Sentry responds
-// with success.
-TEST_P(TestConcurrentRequests, SuccessResponses) {
-  const auto kNumRequestThreads =
-      std::get<0>(GetParam()) == ThreadsNumPolicy::CloseToCPUsNum
-      ? std::min(base::NumCPUs(), 4) : base::NumCPUs() * 3;
-
-  ASSERT_OK(CreateRoleAndAddToGroups());
-  const auto privilege = GetDatabasePrivilege("db", "METADATA");
-  ASSERT_OK(AlterRoleGrantPrivilege(privilege));
-
-  Barrier barrier(kNumRequestThreads);
-
-  vector<thread> threads;
-  vector<Status> thread_status(kNumRequestThreads);
-  for (auto i = 0; i < kNumRequestThreads; ++i) {
-    const auto thread_idx = i;
-    threads.emplace_back([&, thread_idx] () {
-      barrier.Wait();
-      thread_status[thread_idx] = sentry_authz_provider_->
-          AuthorizeGetTableMetadata("db.table", kTestUser);
-    });
-  }
-  for (auto& thread : threads) {
-    thread.join();
-  }
-  for (const auto& s : thread_status) {
-    ASSERT_TRUE(s.ok()) << s.ToString();
-  }
-
-  const auto sentry_rpcs_num = GetTasksSuccessful();
-  // Ideally all requests should result in a single RPC sent to Sentry, but some
-  // scheduling anomalies might occur so even the current threshold of maximum
-  // (kNumRequestThreads / 2) of actual RPC requests to Sentry might be reached
-  // and the assertion below would be triggered. For example, the OS scheduler
-  // might de-schedule the majority of the threads spawned above for a time
-  // longer than it takes to complete an RPC to Sentry, and that de-scheduling
-  // might happen exactly prior the point when the 'earlier-running' thread
-  // added itself into a queue designed to track concurrent requests.
-  // Essentially, that's about 'freezing' all incoming requests just before the
-  // queueing point, and then awakening them one by one, so no more than one
-  // thread is registered in the queue at any time.
-  //
-  // However, those anomalies are expected to be exceptionally rare. In fact,
-  // (kNumRequestThreads / 2) seems to be a good enough threshold even for TSAN
-  // builds while running the test scenario with --stress_cpu_threads=16.
-  ASSERT_GE(kNumRequestThreads / 2, sentry_rpcs_num);
-
-  // Issue the same request once more. If caching is enabled, there should be
-  // no additional RPCs sent to Sentry.
-  ASSERT_OK(sentry_authz_provider_->AuthorizeGetTableMetadata(
-      "db.table", kTestUser));
-  ASSERT_EQ(CachingEnabled() ? sentry_rpcs_num : sentry_rpcs_num + 1,
-            GetTasksSuccessful());
-}
-
-// Verify how multiple concurrent requests are handled when Sentry responds
-// with errors.
-TEST_P(TestConcurrentRequests, FailureResponses) {
-  const auto kNumRequestThreads =
-      std::get<0>(GetParam()) == ThreadsNumPolicy::CloseToCPUsNum
-      ? std::min(base::NumCPUs(), 4) : base::NumCPUs() * 3;
-
-  Barrier barrier(kNumRequestThreads);
-
-  vector<thread> threads;
-  vector<Status> thread_status(kNumRequestThreads);
-  for (auto i = 0; i < kNumRequestThreads; ++i) {
-    const auto thread_idx = i;
-    threads.emplace_back([&, thread_idx] () {
-      barrier.Wait();
-      thread_status[thread_idx] = sentry_authz_provider_->
-          AuthorizeCreateTable("db.table", "nobody", "nobody");
-    });
-  }
-  for (auto& thread : threads) {
-    thread.join();
-  }
-  for (const auto& s : thread_status) {
-    ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  }
-  ASSERT_EQ(0, GetTasksSuccessful());
-  ASSERT_EQ(0, GetTasksFailedNonFatal());
-  const auto sentry_rpcs_num = GetTasksFailedFatal();
-  // See the TestConcurrentRequests.SuccessResponses scenario above for details
-  // on setting the threshold for 'sentry_rpcs_num'.
-  ASSERT_GE(kNumRequestThreads / 2, sentry_rpcs_num);
-
-  // The cache does not store negative responses/errors, so in both caching and
-  // non-caching case there should be one extra RPC sent to Sentry.
-  auto s = sentry_authz_provider_->AuthorizeCreateTable(
-      "db.table", "nobody", "nobody");
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  ASSERT_EQ(sentry_rpcs_num + 1, GetTasksFailedFatal());
-}
-INSTANTIATE_TEST_CASE_P(QueueingConcurrentRequests, TestConcurrentRequests,
-    ::testing::Combine(::testing::Values(ThreadsNumPolicy::CloseToCPUsNum,
-                                         ThreadsNumPolicy::MoreThanCPUsNum),
-                       ::testing::Values(AuthzCaching::Disabled,
-                                         AuthzCaching::Enabled)));
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_authz_provider.cc b/src/kudu/master/sentry_authz_provider.cc
deleted file mode 100644
index 702ef2f..0000000
--- a/src/kudu/master/sentry_authz_provider.cc
+++ /dev/null
@@ -1,368 +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.
-
-#include "kudu/master/sentry_authz_provider.h"
-
-#include <ostream>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-
-#include "kudu/common/common.pb.h"
-#include "kudu/common/table_util.h"
-#include "kudu/gutil/macros.h"
-#include "kudu/gutil/map-util.h"
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/master/sentry_privileges_fetcher.h"
-#include "kudu/security/token.pb.h"
-#include "kudu/sentry/sentry_action.h"
-#include "kudu/sentry/sentry_authorizable_scope.h"
-#include "kudu/util/flag_tags.h"
-#include "kudu/util/slice.h"
-#include "kudu/util/trace.h"
-
-DEFINE_bool(sentry_require_db_privileges_for_list_tables, false,
-            "Whether Kudu will require database-level privileges to authorize "
-            "ListTables requests. When set to false, table-level privileges are "
-            "required for each table. ranger_config_path must not be set if "
-            "this is set");
-TAG_FLAG(sentry_require_db_privileges_for_list_tables, advanced);
-
-DECLARE_string(sentry_service_rpc_addresses);
-
-using kudu::security::ColumnPrivilegePB;
-using kudu::security::TablePrivilegePB;
-using kudu::sentry::SentryAction;
-using kudu::sentry::SentryAuthorizableScope;
-using std::string;
-using std::unordered_map;
-using std::unordered_set;
-using std::vector;
-using strings::Substitute;
-
-namespace kudu {
-namespace master {
-
-namespace {
-
-// Whether the given privileges 'privileges_branch' allows for the specified
-// action ('required_action') in the specified scope ('required_scope')
-// with GRANT ALL option, if any required ('requires_all_with_grant').
-bool IsActionAllowed(SentryAction::Action required_action,
-                     SentryAuthorizableScope::Scope required_scope,
-                     SentryGrantRequired requires_all_with_grant,
-                     const SentryPrivilegesBranch& privileges_branch) {
-  // In general, a privilege implies another when:
-  // 1. the authorizable from the former implies the authorizable from the latter
-  //    (authorizable with a higher scope on the hierarchy can imply authorizables
-  //    with a lower scope on the hierarchy, but not vice versa), and
-  // 2. the action from the former implies the action from the latter, and
-  // 3. grant option from the former implies the grant option from the latter.
-  //
-  // See org.apache.sentry.policy.common.CommonPrivilege. Note that policy validation
-  // in CommonPrivilege also allows wildcard authorizable matching. For example,
-  // authorizable 'server=server1->db=*' can imply authorizable 'server=server1'.
-  // However, wildcard authorizable granting is neither practical nor useful (semantics
-  // of granting such privilege are not supported in Apache Hive, Impala and Hue. And
-  // 'server=server1->db=*' has exactly the same meaning as 'server=server1'). Therefore,
-  // wildcard authorizable matching is dropped in this implementation.
-  //
-  // Moreover, because ListPrivilegesByUser lists all Sentry privileges granted to the
-  // user that match the authorizable of each scope in the input authorizable hierarchy,
-  // privileges with lower scope will also be returned in the response. This contradicts
-  // rule (1) mentioned above. Therefore, we need to validate privilege scope, in addition
-  // to action and grant option. Otherwise, privilege escalation can happen.
-  TRACE("Evaluating privileges");
-  SentryAction action(required_action);
-  SentryAuthorizableScope scope(required_scope);
-  const auto& privileges = privileges_branch.privileges();
-  for (const auto& privilege : privileges) {
-    // A grant option cannot imply the other if the latter is set but the
-    // former is not.
-    if (requires_all_with_grant == REQUIRED && !privilege.all_with_grant) {
-      continue;
-    }
-    // Both privilege scope and action need to imply the other.
-    if (SentryAuthorizableScope(privilege.scope).Implies(scope)) {
-      for (const auto& allowed_action : privilege.allowed_actions) {
-        if (SentryAction(allowed_action).Implies(action)) {
-          return true;
-        }
-      }
-    }
-  }
-  return false;
-}
-
-} // anonymous namespace
-
-SentryAuthzProvider::SentryAuthzProvider(
-    scoped_refptr<MetricEntity> metric_entity)
-    : fetcher_(std::move(metric_entity)) {
-}
-
-SentryAuthzProvider::~SentryAuthzProvider() {
-  Stop();
-}
-
-Status SentryAuthzProvider::Start() {
-  return fetcher_.Start();
-}
-
-void SentryAuthzProvider::Stop() {
-  fetcher_.Stop();
-}
-
-Status SentryAuthzProvider::ResetCache() {
-  return fetcher_.ResetCache();
-}
-
-bool SentryAuthzProvider::IsEnabled() {
-  return !FLAGS_sentry_service_rpc_addresses.empty();
-}
-
-Status SentryAuthzProvider::AuthorizeCreateTable(const string& table_name,
-                                                 const string& user,
-                                                 const string& owner) {
-  // If the table is being created with a different owner than the user,
-  // then the creating user must have 'ALL ON DATABASE' with grant. See
-  // design doc in [SENTRY-2151](https://issues.apache.org/jira/browse/SENTRY-2151).
-  //
-  // Otherwise, table creation requires 'CREATE ON DATABASE' privilege.
-  SentryAction::Action action;
-  SentryGrantRequired grant_option;
-  if (user == owner) {
-    action = SentryAction::Action::CREATE;
-    grant_option = NOT_REQUIRED;
-  } else {
-    action = SentryAction::Action::ALL;
-    grant_option = REQUIRED;
-  }
-  // Note: in our request to Sentry, we shouldn't cache table- or column-level
-  // privileges for the table, since Sentry may automatically grant privileges
-  // upon creation of new tables that caching might miss.
-  return Authorize(SentryAuthorizableScope::Scope::DATABASE, action,
-                   table_name, user, grant_option,
-                   SentryCaching::SERVER_AND_DB_ONLY);
-}
-
-Status SentryAuthzProvider::AuthorizeDropTable(const string& table_name,
-                                               const string& user) {
-  // Table deletion requires 'DROP ON TABLE' privilege.
-  return Authorize(SentryAuthorizableScope::Scope::TABLE,
-                   SentryAction::Action::DROP,
-                   table_name, user);
-}
-
-Status SentryAuthzProvider::AuthorizeAlterTable(const string& old_table,
-                                                const string& new_table,
-                                                const string& user) {
-  // For table alteration (without table rename) requires 'ALTER ON TABLE'
-  // privilege;
-  // For table alteration (with table rename) requires
-  //  1. 'ALL ON TABLE <old-table>',
-  //  2. 'CREATE ON DATABASE <new-database>'.
-  // See [SENTRY-2264](https://issues.apache.org/jira/browse/SENTRY-2264).
-  // TODO(hao): add inline hierarchy validation to avoid multiple RPCs.
-  if (old_table == new_table) {
-    return Authorize(SentryAuthorizableScope::Scope::TABLE,
-                     SentryAction::Action::ALTER,
-                     old_table, user);
-  }
-  RETURN_NOT_OK(Authorize(SentryAuthorizableScope::Scope::TABLE,
-                          SentryAction::Action::ALL,
-                          old_table, user));
-  // Note: in our request to Sentry, we shouldn't cache table- or column-level
-  // privileges for the table, since Sentry may automatically alter privileges
-  // upon altering tables that caching might miss.
-  return Authorize(SentryAuthorizableScope::Scope::DATABASE,
-                   SentryAction::Action::CREATE, new_table, user,
-                   SentryGrantRequired::NOT_REQUIRED,
-                   SentryCaching::SERVER_AND_DB_ONLY);
-}
-
-Status SentryAuthzProvider::AuthorizeGetTableMetadata(const string& table_name,
-                                                      const string& user) {
-  // Retrieving table metadata requires 'METADATA ON TABLE' privilege.
-  return Authorize(SentryAuthorizableScope::Scope::TABLE,
-                   SentryAction::Action::METADATA,
-                   table_name, user);
-}
-
-Status SentryAuthzProvider::AuthorizeListTables(const string& user,
-                                                unordered_set<string>* table_names,
-                                                bool* checked_table_names) {
-  if (IsTrustedUser(user)) {
-    *checked_table_names = false;
-    return Status::OK();
-  }
-  unordered_set<string> authorized_tables;
-  unordered_map<string, vector<string>> tables_by_db;
-  for (auto table_name : *table_names) {
-    Slice db_slice;
-    Slice unused_table_slice;
-    Status s = ParseHiveTableIdentifier(table_name, &db_slice, &unused_table_slice);
-    if (!s.ok()) {
-      continue;
-    }
-    LookupOrInsert(&tables_by_db, db_slice.ToString(), {}).emplace_back(std::move(table_name));
-  }
-  for (auto db_and_tables : tables_by_db) {
-    auto tables_in_db = db_and_tables.second;
-    DCHECK(!tables_in_db.empty());
-    // Authorize database-level privileges first in case the user has
-    // database-level privileges. This would allow us to avoid authorizing each
-    // indiviudual table.
-    // Note: the exact table isn't particularly important, as long as we pass
-    // in a table within the database we're interested in.
-    const string& first_table_name_in_db = tables_in_db[0];
-    Status s = Authorize(SentryAuthorizableScope::Scope::DATABASE, SentryAction::METADATA,
-                         first_table_name_in_db, user);
-    if (s.ok()) {
-      for (auto table_name : tables_in_db) {
-        EmplaceOrDie(&authorized_tables, std::move(table_name));
-      }
-    } else if (!FLAGS_sentry_require_db_privileges_for_list_tables) {
-      for (auto table_name : tables_in_db) {
-        s = AuthorizeGetTableMetadata(table_name, user);
-        if (s.ok()) {
-          EmplaceOrDie(&authorized_tables, std::move(table_name));
-        }
-      }
-    }
-  }
-  *table_names = authorized_tables;
-  *checked_table_names = true;
-  return Status::OK();
-}
-
-Status SentryAuthzProvider::AuthorizeGetTableStatistics(const std::string& table_name,
-                                                        const std::string& user) {
-  // Statistics contain data (e.g. number of rows) that requires the 'SELECT ON TABLE'
-  // privilege.
-  return Authorize(SentryAuthorizableScope::Scope::TABLE,
-                   SentryAction::Action::SELECT,
-                   table_name, user);
-}
-
-Status SentryAuthzProvider::FillTablePrivilegePB(const string& table_name,
-                                                 const string& user,
-                                                 const SchemaPB& schema_pb,
-                                                 TablePrivilegePB* pb) {
-  DCHECK(pb);
-  DCHECK(pb->has_table_id());
-  if (AuthzProvider::IsTrustedUser(user)) {
-    pb->set_delete_privilege(true);
-    pb->set_insert_privilege(true);
-    pb->set_scan_privilege(true);
-    pb->set_update_privilege(true);
-    return Status::OK();
-  }
-  static ColumnPrivilegePB scan_col_privilege;
-  scan_col_privilege.set_scan_privilege(true);
-
-  // Note: it might seem like we could cache these TablePrivilegePBs rather
-  // than parsing them from Sentry privileges every time. This is tricky
-  // because the column-level privileges depend on the input schema, which may
-  // be different upon subsequent calls to this function.
-  SentryPrivilegesBranch privileges_branch;
-  RETURN_NOT_OK(fetcher_.GetSentryPrivileges(
-      SentryAuthorizableScope::TABLE, table_name, user,
-      SentryCaching::ALL, &privileges_branch));
-  unordered_set<string> scannable_col_names;
-  static const SentryAuthorizableScope kTableScope(SentryAuthorizableScope::TABLE);
-  for (const auto& privilege : privileges_branch.privileges()) {
-    if (SentryAuthorizableScope(privilege.scope).Implies(kTableScope)) {
-      // Pull out any privileges at the table scope or higher.
-      if (ContainsKey(privilege.allowed_actions, SentryAction::ALL) ||
-          ContainsKey(privilege.allowed_actions, SentryAction::OWNER)) {
-        // Generate privilege with everything.
-        pb->set_delete_privilege(true);
-        pb->set_insert_privilege(true);
-        pb->set_scan_privilege(true);
-        pb->set_update_privilege(true);
-        return Status::OK();
-      }
-      if (ContainsKey(privilege.allowed_actions, SentryAction::DELETE)) {
-        pb->set_delete_privilege(true);
-      }
-      if (ContainsKey(privilege.allowed_actions, SentryAction::INSERT)) {
-        pb->set_insert_privilege(true);
-      }
-      if (ContainsKey(privilege.allowed_actions, SentryAction::SELECT)) {
-        pb->set_scan_privilege(true);
-      }
-      if (ContainsKey(privilege.allowed_actions, SentryAction::UPDATE)) {
-        pb->set_update_privilege(true);
-      }
-    } else if (!pb->scan_privilege() &&
-               (ContainsKey(privilege.allowed_actions, SentryAction::ALL) ||
-                ContainsKey(privilege.allowed_actions, SentryAction::OWNER) ||
-                ContainsKey(privilege.allowed_actions, SentryAction::SELECT))) {
-      // Pull out any scan privileges at the column scope.
-      DCHECK_EQ(SentryAuthorizableScope::COLUMN, privilege.scope);
-      DCHECK(!privilege.column_name.empty());
-      EmplaceIfNotPresent(&scannable_col_names, privilege.column_name);
-    }
-  }
-  // If we got any column-level scan privileges and we don't already have
-  // table-level scan privileges, set them now.
-  if (!pb->scan_privilege()) {
-    for (const auto& col : schema_pb.columns()) {
-      if (ContainsKey(scannable_col_names, col.name())) {
-        InsertIfNotPresent(pb->mutable_column_privileges(), col.id(), scan_col_privilege);
-      }
-    }
-  }
-  return Status::OK();
-}
-
-Status SentryAuthzProvider::Authorize(SentryAuthorizableScope::Scope scope,
-                                      SentryAction::Action action,
-                                      const string& table_ident,
-                                      const string& user,
-                                      SentryGrantRequired require_grant_option,
-                                      SentryCaching caching) {
-  if (AuthzProvider::IsTrustedUser(user)) {
-    return Status::OK();
-  }
-
-  SentryPrivilegesBranch privileges;
-  RETURN_NOT_OK(fetcher_.GetSentryPrivileges(scope, table_ident, user,
-      caching, &privileges));
-  if (IsActionAllowed(action, scope, require_grant_option, privileges)) {
-    return Status::OK();
-  }
-
-  // Log a warning if the action is not authorized for debugging purpose, and
-  // only return a generic error to users to avoid a side channel leak, e.g.
-  // whether table A exists.
-  LOG(WARNING) << Substitute("Action <$0> on table <$1> with authorizable scope "
-                             "<$2> is not permitted for user <$3>",
-                             sentry::ActionToString(action),
-                             table_ident,
-                             sentry::ScopeToString(scope),
-                             user);
-  return Status::NotAuthorized("unauthorized action");
-}
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_authz_provider.h b/src/kudu/master/sentry_authz_provider.h
deleted file mode 100644
index 27c0fa1..0000000
--- a/src/kudu/master/sentry_authz_provider.h
+++ /dev/null
@@ -1,140 +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.
-
-#pragma once
-
-#include <string>
-#include <unordered_set>
-
-#include <gtest/gtest_prod.h>
-
-#include "kudu/gutil/port.h"
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/master/authz_provider.h"
-#include "kudu/master/sentry_privileges_fetcher.h"
-#include "kudu/sentry/sentry_action.h"
-#include "kudu/sentry/sentry_authorizable_scope.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-
-class SchemaPB;
-
-namespace security {
-class TablePrivilegePB;
-} // namespace security
-
-namespace master {
-
-// Enum indicating whether a grant option is required to perform a specific
-// action.
-enum SentryGrantRequired {
-  NOT_REQUIRED,
-  REQUIRED,
-};
-
-// An implementation of AuthzProvider that connects to the Sentry service
-// for authorization metadata and allows or denies the actions performed by
-// users based on the metadata.
-//
-// This class is thread-safe after Start() is called.
-class SentryAuthzProvider : public AuthzProvider {
- public:
-  explicit SentryAuthzProvider(scoped_refptr<MetricEntity> metric_entity = {});
-
-  ~SentryAuthzProvider();
-
-  // Start SentryAuthzProvider instance which connects to the Sentry service.
-  Status Start() override WARN_UNUSED_RESULT;
-
-  void Stop() override;
-
-  Status ResetCache() override WARN_UNUSED_RESULT;
-
-  // Returns true if the SentryAuthzProvider should be enabled.
-  static bool IsEnabled();
-
-  // The following authorizing methods will fail if:
-  //   - the operation is not authorized
-  //   - the Sentry service is unreachable (when privilege caching is disabled)
-  //   - Sentry fails to resolve the group mapping of the user
-  //   - the specified '--kudu_service_name' is a non-admin user in Sentry
-  // TODO(hao): add early failure recognition when SENTRY-2440 is done.
-
-  Status AuthorizeCreateTable(const std::string& table_name,
-                              const std::string& user,
-                              const std::string& owner) override WARN_UNUSED_RESULT;
-
-  Status AuthorizeDropTable(const std::string& table_name,
-                            const std::string& user) override WARN_UNUSED_RESULT;
-
-  // Note that the caller should normalize the table name if case sensitivity is not
-  // enforced for naming. e.g. when HMS integration is enabled.
-  Status AuthorizeAlterTable(const std::string& old_table,
-                             const std::string& new_table,
-                             const std::string& user) override WARN_UNUSED_RESULT;
-
-  Status AuthorizeGetTableMetadata(const std::string& table_name,
-                                   const std::string& user) override WARN_UNUSED_RESULT;
-
-  Status AuthorizeListTables(const std::string& user,
-                             std::unordered_set<std::string>* table_names,
-                             bool* checked_table_names) override WARN_UNUSED_RESULT;
-
-  Status AuthorizeGetTableStatistics(const std::string& table_name,
-                                     const std::string& user) override WARN_UNUSED_RESULT;
-
-  Status FillTablePrivilegePB(const std::string& table_name,
-                              const std::string& user,
-                              const SchemaPB& schema_pb,
-                              security::TablePrivilegePB* pb) override WARN_UNUSED_RESULT;
-
- private:
-  friend class SentryAuthzProviderTest;
-  FRIEND_TEST(TestAuthzHierarchy, TestAuthorizableScope);
-  FRIEND_TEST(SentryAuthzProviderFilterPrivilegesScopeTest, TestFilterInvalidResponses);
-  FRIEND_TEST(SentryAuthzProviderFilterPrivilegesScopeTest, TestFilterValidResponses);
-  FRIEND_TEST(SentryAuthzProviderTest, CacheBehaviorNotCachingTableInfo);
-
-  // Checks if the user can perform an action on the table identifier (in the format
-  // <database-name>.<table-name>), based on the given authorizable scope and the
-  // grant option. Note that the authorizable scope should be equal or higher than
-  // 'TABLE' scope.
-  //
-  // If the operation is not authorized, returns Status::NotAuthorized().
-  // Note that the authorization process is case insensitive for the
-  // authorizables.
-  //
-  // If 'caching' is SERVER_AND_DB_ONLY and the underlying
-  // SentryPrivilegesFetcher is configured to cache privileges, it will not
-  // cache privileges equal to or below the 'TABLE' scope.
-  Status Authorize(sentry::SentryAuthorizableScope::Scope scope,
-                   sentry::SentryAction::Action action,
-                   const std::string& table_ident,
-                   const std::string& user,
-                   SentryGrantRequired require_grant_option = NOT_REQUIRED,
-                   SentryCaching caching = ALL);
-
-  // An instance of utility class that provides interface to search for
-  // required privileges through the information received from Sentry.
-  // The fetcher can optionally cache the received information.
-  SentryPrivilegesFetcher fetcher_;
-};
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_client_metrics.cc b/src/kudu/master/sentry_client_metrics.cc
deleted file mode 100644
index bee17e2..0000000
--- a/src/kudu/master/sentry_client_metrics.cc
+++ /dev/null
@@ -1,64 +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.
-
-#include "kudu/master/sentry_client_metrics.h"
-
-#include "kudu/util/metrics.h"
-
-METRIC_DEFINE_counter(server, sentry_client_tasks_successful,
-                      "Successful Tasks", kudu::MetricUnit::kTasks,
-                      "Number of successfully run tasks",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_client_tasks_failed_fatal,
-                      "Failed tasks (fatal)", kudu::MetricUnit::kTasks,
-                      "Number of tasks failed with fatal errors",
-                      kudu::MetricLevel::kWarn);
-METRIC_DEFINE_counter(server, sentry_client_tasks_failed_nonfatal,
-                      "Failed Tasks (nonfatal)", kudu::MetricUnit::kTasks,
-                      "Number of tasks failed with non-fatal errors",
-                      kudu::MetricLevel::kWarn);
-METRIC_DEFINE_counter(server, sentry_client_reconnections_succeeded,
-                      "Successful Reconnections", kudu::MetricUnit::kUnits,
-                      "Number of successful reconnections to Sentry",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_client_reconnections_failed,
-                      "Failed Reconnections", kudu::MetricUnit::kUnits,
-                      "Number of failed reconnections to Sentry",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_histogram(server, sentry_client_task_execution_time_us,
-                        "Task Execution Time (us)",
-                        kudu::MetricUnit::kMicroseconds,
-                        "Duration of HaClient::Execute() calls (us)",
-                        kudu::MetricLevel::kInfo,
-                        60000000, 2);
-
-namespace kudu {
-namespace master {
-
-#define MINIT(member, x) member = METRIC_##x.Instantiate(e)
-SentryClientMetrics::SentryClientMetrics(const scoped_refptr<MetricEntity>& e) {
-  MINIT(tasks_successful, sentry_client_tasks_successful);
-  MINIT(tasks_failed_fatal, sentry_client_tasks_failed_fatal);
-  MINIT(tasks_failed_nonfatal, sentry_client_tasks_failed_nonfatal);
-  MINIT(reconnections_succeeded, sentry_client_reconnections_succeeded);
-  MINIT(reconnections_failed, sentry_client_reconnections_failed);
-  MINIT(task_execution_time_us, sentry_client_task_execution_time_us);
-}
-#undef MINIT
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_client_metrics.h b/src/kudu/master/sentry_client_metrics.h
deleted file mode 100644
index 39af49f..0000000
--- a/src/kudu/master/sentry_client_metrics.h
+++ /dev/null
@@ -1,33 +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.
-
-#pragma once
-
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/thrift/ha_client_metrics.h"
-
-namespace kudu {
-
-class MetricEntity;
-
-namespace master {
-struct SentryClientMetrics : public thrift::HaClientMetrics {
-  explicit SentryClientMetrics(const scoped_refptr<MetricEntity>& e);
-};
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_privileges_cache_metrics.cc b/src/kudu/master/sentry_privileges_cache_metrics.cc
deleted file mode 100644
index 7e0477a..0000000
--- a/src/kudu/master/sentry_privileges_cache_metrics.cc
+++ /dev/null
@@ -1,85 +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.
-
-#include "kudu/master/sentry_privileges_cache_metrics.h"
-
-#include "kudu/util/metrics.h"
-
-METRIC_DEFINE_counter(server, sentry_privileges_cache_inserts,
-                      "Sentry Privileges Cache Inserts",
-                      kudu::MetricUnit::kEntries,
-                      "Number of entries inserted in the cache",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_privileges_cache_lookups,
-                      "Sentry Privileges Cache Lookups",
-                      kudu::MetricUnit::kEntries,
-                      "Number of entries looked up from the cache",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_privileges_cache_evictions,
-                      "Sentry Privileges Cache Evictions",
-                      kudu::MetricUnit::kEntries,
-                      "Number of entries evicted from the cache",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_privileges_cache_evictions_expired,
-                      "Sentry Privileges Cache Evictions of Expired Entries",
-                      kudu::MetricUnit::kEntries,
-                      "Number of entries that had already expired upon "
-                      "eviction from the cache",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_privileges_cache_misses,
-                      "Sentry Privileges Cache Misses",
-                      kudu::MetricUnit::kEntries,
-                      "Number of lookups that didn't find a cached entry",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_privileges_cache_hits,
-                      "Sentry Privileges Cache Hits",
-                      kudu::MetricUnit::kEntries,
-                      "Number of lookups that found a cached entry",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_counter(server, sentry_privileges_cache_hits_expired,
-                      "Sentry Privileges Cache Hits of Expired Entries",
-                      kudu::MetricUnit::kEntries,
-                      "Number of lookups that found an entry, but the entry "
-                      "had already expired at the time of lookup",
-                      kudu::MetricLevel::kDebug);
-METRIC_DEFINE_gauge_uint64(server, sentry_privileges_cache_memory_usage,
-                           "Sentry Privileges Cache Memory Usage",
-                           kudu::MetricUnit::kBytes,
-                           "Memory consumed by the cache",
-                           kudu::MetricLevel::kDebug);
-
-namespace kudu {
-namespace master {
-
-#define MINIT(member, x) member = METRIC_##x.Instantiate(metric_entity)
-#define GINIT(member, x) member = METRIC_##x.Instantiate(metric_entity, 0)
-SentryPrivilegesCacheMetrics::SentryPrivilegesCacheMetrics(
-    const scoped_refptr<MetricEntity>& metric_entity) {
-  MINIT(inserts, sentry_privileges_cache_inserts);
-  MINIT(lookups, sentry_privileges_cache_lookups);
-  MINIT(evictions, sentry_privileges_cache_evictions);
-  MINIT(evictions_expired, sentry_privileges_cache_evictions_expired);
-  MINIT(cache_hits_caching, sentry_privileges_cache_hits);
-  MINIT(cache_hits_expired, sentry_privileges_cache_hits_expired);
-  MINIT(cache_misses_caching, sentry_privileges_cache_misses);
-  GINIT(cache_usage, sentry_privileges_cache_memory_usage);
-}
-#undef MINIT
-#undef GINIT
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_privileges_cache_metrics.h b/src/kudu/master/sentry_privileges_cache_metrics.h
deleted file mode 100644
index 3f21ca9..0000000
--- a/src/kudu/master/sentry_privileges_cache_metrics.h
+++ /dev/null
@@ -1,35 +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.
-
-#pragma once
-
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/util/ttl_cache_metrics.h"
-
-namespace kudu {
-
-class MetricEntity;
-
-namespace master {
-
-struct SentryPrivilegesCacheMetrics : public TTLCacheMetrics {
-  explicit SentryPrivilegesCacheMetrics(
-      const scoped_refptr<MetricEntity>& metric_entity);
-};
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_privileges_fetcher.cc b/src/kudu/master/sentry_privileges_fetcher.cc
deleted file mode 100644
index b9d35b7..0000000
--- a/src/kudu/master/sentry_privileges_fetcher.cc
+++ /dev/null
@@ -1,933 +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.
-
-#include "kudu/master/sentry_privileges_fetcher.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <iterator>
-#include <memory>
-#include <mutex>
-#include <set>
-#include <type_traits>
-#include <unordered_map>
-#include <vector>
-
-#include <boost/algorithm/string/predicate.hpp>
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-
-#include "kudu/common/table_util.h"
-#include "kudu/gutil/macros.h"
-#include "kudu/gutil/map-util.h"
-#include "kudu/gutil/port.h"
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/master/sentry_client_metrics.h"
-#include "kudu/master/sentry_privileges_cache_metrics.h"
-#include "kudu/sentry/sentry_action.h"
-#include "kudu/sentry/sentry_authorizable_scope.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
-#include "kudu/thrift/client.h"
-#include "kudu/thrift/ha_client_metrics.h"
-#include "kudu/util/async_util.h"
-#include "kudu/util/flag_tags.h"
-#include "kudu/util/flag_validators.h"
-#include "kudu/util/malloc.h"
-#include "kudu/util/monotime.h"
-#include "kudu/util/net/net_util.h"
-#include "kudu/util/slice.h"
-#include "kudu/util/test_util_prod.h"
-#include "kudu/util/trace.h"
-#include "kudu/util/ttl_cache_metrics.h"
-
-DEFINE_string(sentry_service_rpc_addresses, "",
-              "Comma-separated list of RPC addresses of the Sentry service(s). When "
-              "set, Sentry integration is enabled, fine-grained access control is "
-              "enforced in the master, and clients are issued authorization tokens. "
-              "Must match the value of the sentry.service.client.server.rpc-addresses "
-              "option in the Sentry server configuration.");
-
-DEFINE_string(server_name, "server1",
-              "Configures which server namespace the Kudu instance belongs to for defining "
-              "server-level privileges in Sentry. Used to distinguish a particular Kudu "
-              "cluster in case of a multi-cluster setup. Must match the value of the "
-              "hive.sentry.server option in the HiveServer2 configuration, and the value "
-              "of the --server_name in Impala configuration.");
-
-DEFINE_string(kudu_service_name, "kudu",
-              "The service name of the Kudu server. Must match the service name "
-              "used for Kudu server of sentry.service.admin.group option in the "
-              "Sentry server configuration.");
-
-DEFINE_string(sentry_service_kerberos_principal, "sentry",
-              "The service principal of the Sentry server. Must match the primary "
-              "(user) portion of sentry.service.server.principal option in the "
-              "Sentry server configuration.");
-
-DEFINE_string(sentry_service_security_mode, "kerberos",
-              "Configures whether Thrift connections to the Sentry server use "
-              "SASL (Kerberos) security. Must match the value of the "
-              "‘sentry.service.security.mode’ option in the Sentry server "
-              "configuration.");
-
-DEFINE_int32(sentry_service_retry_count, 1,
-             "The number of times that Sentry operations will retry after "
-             "encountering retriable failures, such as network errors.");
-TAG_FLAG(sentry_service_retry_count, advanced);
-
-DEFINE_int32(sentry_service_send_timeout_seconds, 60,
-             "Configures the socket send timeout, in seconds, for Thrift "
-             "connections to the Sentry server.");
-TAG_FLAG(sentry_service_send_timeout_seconds, advanced);
-
-DEFINE_int32(sentry_service_recv_timeout_seconds, 60,
-             "Configures the socket receive timeout, in seconds, for Thrift "
-             "connections to the Sentry server.");
-TAG_FLAG(sentry_service_recv_timeout_seconds, advanced);
-
-DEFINE_int32(sentry_service_conn_timeout_seconds, 60,
-             "Configures the socket connect timeout, in seconds, for Thrift "
-             "connections to the Sentry server.");
-TAG_FLAG(sentry_service_conn_timeout_seconds, advanced);
-
-DEFINE_int32(sentry_service_max_message_size_bytes, 100 * 1024 * 1024,
-             "Maximum size of Sentry objects that can be received by the "
-             "Sentry client in bytes. Must match the value of the "
-             "sentry.policy.client.thrift.max.message.size option in the "
-             "Sentry server configuration.");
-TAG_FLAG(sentry_service_max_message_size_bytes, advanced);
-
-// TODO(aserbin): provide some reasonable default value for the
-//                --sentry_privileges_cache_capacity_mb flag. Maybe, make it
-//                a multiple of FLAG_sentry_service_max_message_size_bytes ?
-DEFINE_uint32(sentry_privileges_cache_capacity_mb, 256,
-              "Capacity for the authz cache, in MiBytes. The cache stores "
-              "information received from Sentry. A value of 0 means Sentry "
-              "responses will not be cached.");
-TAG_FLAG(sentry_privileges_cache_capacity_mb, advanced);
-
-DEFINE_uint32(sentry_privileges_cache_ttl_factor, 10,
-              "Factor of multiplication for the authz token validity interval "
-              "defined by --authz_token_validity_seconds flag. The result of "
-              "the multiplication of this factor and authz token validity "
-              "defines the TTL of entries in the authz cache.");
-TAG_FLAG(sentry_privileges_cache_ttl_factor, advanced);
-
-DEFINE_uint32(sentry_privileges_cache_scrubbing_period_sec, 20,
-              "The interval to run the periodic task that scrubs the "
-              "privileges cache of expired entries. A value of 0 means expired "
-              "entries are only evicted when inserting new entries into a full "
-              "cache.");
-TAG_FLAG(sentry_privileges_cache_scrubbing_period_sec, advanced);
-
-DEFINE_uint32(sentry_privileges_cache_max_scrubbed_entries_per_pass, 32,
-              "Maximum number of entries in the privileges cache to process "
-              "in one pass of the periodic scrubbing task. A value of 0 means "
-              "there is no limit, i.e. all expired entries, if any, "
-              "are invalidated every time the scrubbing task runs. Note "
-              "that the cache is locked while the scrubbing task is running.");
-TAG_FLAG(sentry_privileges_cache_max_scrubbed_entries_per_pass, advanced);
-
-DECLARE_int64(authz_token_validity_seconds);
-DECLARE_string(hive_metastore_uris);
-DECLARE_string(kudu_service_name);
-DECLARE_string(server_name);
-
-using kudu::sentry::AuthorizableScopesSet;
-using kudu::sentry::SentryAction;
-using kudu::sentry::SentryAuthorizableScope;
-using kudu::sentry::SentryClient;
-using sentry::TListSentryPrivilegesRequest;
-using sentry::TListSentryPrivilegesResponse;
-using sentry::TSentryAuthorizable;
-using sentry::TSentryGrantOption;
-using sentry::TSentryPrivilege;
-using std::make_shared;
-using std::shared_ptr;
-using std::string;
-using std::unique_ptr;
-using std::unordered_map;
-using std::vector;
-using strings::Substitute;
-
-namespace kudu {
-namespace master {
-
-// Validates the sentry_service_rpc_addresses gflag.
-static bool ValidateAddresses(const char* flag_name, const string& addresses) {
-  vector<HostPort> host_ports;
-  Status s = HostPort::ParseStringsWithScheme(addresses,
-                                              SentryClient::kDefaultSentryPort,
-                                              &host_ports);
-  if (!s.ok()) {
-    LOG(ERROR) << "invalid flag " << flag_name << ": " << s.ToString();
-  }
-  return s.ok();
-}
-DEFINE_validator(sentry_service_rpc_addresses, &ValidateAddresses);
-
-// This group flag validator enforces the logical dependency of the Sentry+Kudu
-// fine-grain authz scheme on the integration with HMS catalog.
-//
-// The validator makes it necessary to set the --hive_metastore_uris flag
-// if the --sentry_service_rpc_addresses flag is set.
-//
-// Even if Kudu could successfully fetch information on granted privileges from
-// Sentry to allow or deny commencing DML operations on already existing
-// tables, the information on privileges in Sentry would become inconsistent
-// after DDL operations (e.g., renaming a table).
-bool ValidateSentryServiceRpcAddresses() {
-  if (!FLAGS_sentry_service_rpc_addresses.empty() &&
-      FLAGS_hive_metastore_uris.empty()) {
-    LOG(ERROR) << "Hive Metastore catalog is required (--hive_metastore_uris) "
-                  "to run Kudu with Sentry-backed authorization scheme "
-                  "(--sentry_service_rpc_addresses).";
-    return false;
-  }
-  return true;
-}
-GROUP_FLAG_VALIDATOR(sentry_service_rpc_addresses,
-                     ValidateSentryServiceRpcAddresses);
-
-namespace {
-
-// Fetching privileges from Sentry gets more expensive the broader the scope of
-// the authorizable is, since the API used in a fetch returns all ancestors and
-// all descendents of an authorizable in its hierarchy tree.
-//
-// Even if requesting privileges at a relatively broad scope, e.g. DATABASE,
-// fill in the authorizable to request a narrower scope, since the broader
-// privileges (i.e. the ancestors) will be returned from Sentry anyway.
-void NarrowAuthzScopeForFetch(const string& db, const string& table,
-                              TSentryAuthorizable* authorizable) {
-  if (authorizable->db.empty()) {
-    authorizable->__set_db(db);
-  }
-  if (authorizable->table.empty()) {
-    authorizable->__set_table(table);
-  }
-}
-
-// Returns an authorizable based on the given database and table name and the
-// given scope.
-Status GetAuthorizable(const string& db, const string& table,
-                       SentryAuthorizableScope::Scope scope,
-                       TSentryAuthorizable* authorizable) {
-  // We should only ever request privileges from Sentry for authorizables of
-  // scope equal to or higher than 'TABLE'.
-  DCHECK_NE(scope, SentryAuthorizableScope::Scope::COLUMN);
-  switch (scope) {
-    case SentryAuthorizableScope::Scope::TABLE:
-      authorizable->__set_table(table);
-      FALLTHROUGH_INTENDED;
-    case SentryAuthorizableScope::Scope::DATABASE:
-      authorizable->__set_db(db);
-      FALLTHROUGH_INTENDED;
-    case SentryAuthorizableScope::Scope::SERVER:
-      authorizable->__set_server(FLAGS_server_name);
-      break;
-    default:
-      LOG(FATAL) << "unsupported SentryAuthorizableScope: "
-                 << sentry::ScopeToString(scope);
-      break;
-  }
-
-  return Status::OK();
-}
-
-// A utility class to help with Sentry privilege scoping, generating sequence
-// of keys to lookup corresponding entries in the cache.
-class AuthzInfoKey {
- public:
-  // The maximum possible number of the elements in the key lookup sequence
-  // returned by the key_sequence() method (see below). Maximum number of keys
-  // to lookup in the cache is 2. See the comment for the GenerateKeySequence()
-  // method below for more details.
-  constexpr static size_t kKeySequenceMaxSize = 2;
-
-  AuthzInfoKey(const string& user,
-               const ::sentry::TSentryAuthorizable& authorizable);
-
-  // Get the key to lookup the corresponding entry in the cache with the scope
-  // of the authorizable widened as specified by the 'scope' parameter.
-  // E.g., if the original scope of the autorizable specified in the constructor
-  // was COLUMN, with the 'scope' set to TABLE the returned key is 'U/S/D/T',
-  // while the key for the authorizable as is would be 'U/S/D/T/C'.
-  const string& GetKey(SentryAuthorizableScope::Scope scope) const;
-
-  // This method returns the sequence of keys to look up in the cache
-  // if retrieving privileges granted to the 'user' on the 'authorizable'
-  // specified in the constructor.
-  const vector<string>& key_sequence() const {
-    return key_sequence_;
-  }
-
- private:
-  // Generate the raw key sequence: a sequence of keys for the authz scope
-  // hierarchy, starting from the very top (i.e. SERVER scope) and narrowing
-  // down to the scope of the 'authorizable' specified in the constructor.
-  //
-  // For example, for user 'U' and authorizable { server:S, db:D, table:T }
-  // the raw sequence of keys is { 'U/S', 'U/S/D', 'U/S/D/T' }.
-  static vector<string> GenerateRawKeySequence(
-      const string& user, const ::sentry::TSentryAuthorizable& authorizable);
-
-  // Generate the cache key lookup sequence: a sequence of keys to use while
-  // looking up corresponding entry in the authz cache. The maximum
-  // length of the returned sequence is limited by kCacheKeySequenceMaxSize.
-  //
-  // For authorizables of the TABLE scope and narrower, it returns sequence
-  // { 'U/S/D', 'U/S/D/T' }. For authorizables of the DATABASE scope it returns
-  // { 'U/S/D' }. For authorizables of the SERVER scope it returns { 'U/S' }.
-  static vector<string> GenerateKeySequence(const vector<string>& raw_sequence);
-
-  // Convert the Sentry authz scope to an index in the list
-  // { SERVER, DATABASE, TABLE, COLUMN }.
-  static size_t ScopeToRawSequenceIdx(SentryAuthorizableScope::Scope scope);
-
-  const vector<string> raw_key_sequence_;
-  const vector<string> key_sequence_;
-};
-
-AuthzInfoKey::AuthzInfoKey(const string& user,
-                           const ::sentry::TSentryAuthorizable& authorizable)
-    : raw_key_sequence_(GenerateRawKeySequence(user, authorizable)),
-      key_sequence_(GenerateKeySequence(raw_key_sequence_)) {
-  DCHECK(!raw_key_sequence_.empty());
-  DCHECK(!key_sequence_.empty());
-  DCHECK_GE(kKeySequenceMaxSize, key_sequence_.size());
-}
-
-const string& AuthzInfoKey::GetKey(SentryAuthorizableScope::Scope scope) const {
-  const size_t level = ScopeToRawSequenceIdx(scope);
-  if (level < raw_key_sequence_.size()) {
-    return raw_key_sequence_[level];
-  }
-  return raw_key_sequence_.back();
-}
-
-vector<string> AuthzInfoKey::GenerateRawKeySequence(
-    const string& user, const ::sentry::TSentryAuthorizable& authorizable) {
-  DCHECK(!user.empty());
-  DCHECK(!authorizable.server.empty());
-  if (!authorizable.__isset.db || authorizable.db.empty()) {
-    return {
-      Substitute("$0/$1", user, authorizable.server),
-    };
-  }
-
-  if (!authorizable.__isset.table || authorizable.table.empty()) {
-    auto k0 = Substitute("$0/$1", user, authorizable.server);
-    auto k1 = Substitute("$0/$1", k0, authorizable.db);
-    return { std::move(k0), std::move(k1), };
-  }
-
-  if (!authorizable.__isset.column || authorizable.column.empty()) {
-    auto k0 = Substitute("$0/$1", user, authorizable.server);
-    auto k1 = Substitute("$0/$1", k0, authorizable.db);
-    auto k2 = Substitute("$0/$1", k1, authorizable.table);
-    return { std::move(k0), std::move(k1), std::move(k2), };
-  }
-
-  auto k0 = Substitute("$0/$1", user, authorizable.server);
-  auto k1 = Substitute("$0/$1", k0, authorizable.db);
-  auto k2 = Substitute("$0/$1", k1, authorizable.table);
-  auto k3 = Substitute("$0/$1", k2, authorizable.column);
-  return { std::move(k0), std::move(k1), std::move(k2), std::move(k3), };
-}
-
-vector<string> AuthzInfoKey::GenerateKeySequence(
-    const vector<string>& raw_sequence) {
-  DCHECK(!raw_sequence.empty());
-  vector<string> sequence;
-  const auto idx_db = ScopeToRawSequenceIdx(SentryAuthorizableScope::DATABASE);
-  if (idx_db < raw_sequence.size()) {
-    sequence.emplace_back(raw_sequence[idx_db]);
-  }
-  const auto idx_table = ScopeToRawSequenceIdx(SentryAuthorizableScope::TABLE);
-  if (idx_table < raw_sequence.size()) {
-    sequence.emplace_back(raw_sequence[idx_table]);
-  }
-  if (sequence.empty()) {
-    sequence.emplace_back(raw_sequence.back());
-  }
-  DCHECK_GE(kKeySequenceMaxSize, sequence.size());
-  return sequence;
-}
-
-size_t AuthzInfoKey::ScopeToRawSequenceIdx(SentryAuthorizableScope::Scope scope) {
-  size_t idx = 0;
-  switch (scope) {
-    case SentryAuthorizableScope::Scope::SERVER:
-      idx = 0;
-      break;
-    case SentryAuthorizableScope::Scope::DATABASE:
-      idx = 1;
-      break;
-    case SentryAuthorizableScope::Scope::TABLE:
-      idx = 2;
-      break;
-    case SentryAuthorizableScope::Scope::COLUMN:
-      idx = 3;
-      break;
-    default:
-      LOG(DFATAL) << "unexpected scope: " << static_cast<int16_t>(scope);
-      break;
-  }
-
-  return idx;
-}
-
-// Returns a unique string key for the given authorizable, at the given scope.
-// The authorizable must be a well-formed at the given scope.
-string GetKey(const string& server,
-              const string& db,
-              const string& table,
-              const string& column,
-              SentryAuthorizableScope::Scope scope) {
-  DCHECK(!server.empty());
-  switch (scope) {
-    case SentryAuthorizableScope::SERVER:
-      return server;
-    case SentryAuthorizableScope::DATABASE:
-      DCHECK(!db.empty());
-      return Substitute("$0/$1", server, db);
-    case SentryAuthorizableScope::TABLE:
-      DCHECK(!db.empty());
-      DCHECK(!table.empty());
-      return Substitute("$0/$1/$2", server, db, table);
-    case SentryAuthorizableScope::COLUMN:
-      DCHECK(!db.empty());
-      DCHECK(!table.empty());
-      DCHECK(!column.empty());
-      return Substitute("$0/$1/$2/$3", server, db, table, column);
-    default:
-      LOG(DFATAL) << "not reachable";
-      break;
-  }
-  return "";
-}
-
-} // anonymous namespace
-
-
-SentryPrivilegesBranch::SentryPrivilegesBranch(
-    const ::sentry::TSentryAuthorizable& authorizable,
-    const TListSentryPrivilegesResponse& response) {
-  DoInit(authorizable, response);
-}
-
-size_t SentryPrivilegesBranch::memory_footprint() const {
-  size_t res = kudu_malloc_usable_size(this);
-  // This is a simple approximation: the exact information could be available
-  // from the allocator of std::vector and std::string.
-  res += privileges_.capacity() * sizeof(AuthorizablePrivileges);
-  for (const auto& p : privileges_) {
-    res += p.db_name.capacity();
-    res += p.table_name.capacity();
-    res += p.column_name.capacity();
-    res += sizeof(decltype(p.allowed_actions));
-  }
-  return res;
-}
-
-void SentryPrivilegesBranch::Merge(const SentryPrivilegesBranch& other) {
-  std::copy(other.privileges_.begin(), other.privileges_.end(),
-            std::back_inserter(privileges_));
-}
-
-void SentryPrivilegesBranch::Split(
-    SentryPrivilegesBranch* other_scope_db,
-    SentryPrivilegesBranch* other_scope_table) const {
-  SentryPrivilegesBranch scope_db;
-  SentryPrivilegesBranch scope_table;
-  for (const auto& e : privileges_) {
-    switch (e.scope) {
-      case SentryAuthorizableScope::SERVER:
-      case SentryAuthorizableScope::DATABASE:
-        scope_db.privileges_.emplace_back(e);
-        break;
-      case SentryAuthorizableScope::TABLE:
-      case SentryAuthorizableScope::COLUMN:
-        scope_table.privileges_.emplace_back(e);
-        break;
-      default:
-        LOG(DFATAL) << "not reachable";
-        break;
-    }
-  }
-  *other_scope_db = std::move(scope_db);
-  *other_scope_table = std::move(scope_table);
-}
-
-void SentryPrivilegesBranch::DoInit(
-    const ::sentry::TSentryAuthorizable& authorizable,
-    const TListSentryPrivilegesResponse& response) {
-  unordered_map<string, AuthorizablePrivileges> privileges_map;
-  for (const auto& privilege_resp : response.privileges) {
-    SentryAuthorizableScope::Scope scope;
-    SentryAction::Action action;
-    if (!SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-        privilege_resp, authorizable, &scope, &action)) {
-      VLOG(1) << "ignoring privilege response: " << privilege_resp;
-      continue;
-    }
-    const auto& db = privilege_resp.dbName;
-    const auto& table = privilege_resp.tableName;
-    const auto& column = privilege_resp.columnName;
-    const string authorizable_key = GetKey(privilege_resp.serverName,
-                                           db, table, column, scope);
-    auto& privilege = LookupOrInsert(&privileges_map, authorizable_key,
-        AuthorizablePrivileges(scope, db, table, column));
-    InsertIfNotPresent(&privilege.allowed_actions, action);
-    if (action == SentryAction::ALL || action == SentryAction::OWNER) {
-      privilege.all_with_grant =
-          (privilege_resp.grantOption == TSentryGrantOption::ENABLED);
-    }
-    if (VLOG_IS_ON(1)) {
-      if (action != SentryAction::ALL && action != SentryAction::OWNER &&
-          privilege_resp.grantOption == TSentryGrantOption::ENABLED) {
-        VLOG(1) << "ignoring ENABLED grant option for unknown action: "
-                << static_cast<int16_t>(action);
-      }
-    }
-  }
-  EmplaceValuesFromMap(std::move(privileges_map), &privileges_);
-}
-
-SentryPrivilegesFetcher::SentryPrivilegesFetcher(
-    scoped_refptr<MetricEntity> metric_entity)
-    : metric_entity_(std::move(metric_entity)) {
-  if (metric_entity_) {
-    std::unique_ptr<SentryClientMetrics> metrics(
-        new SentryClientMetrics(metric_entity_));
-    sentry_client_.SetMetrics(std::move(metrics));
-  }
-}
-
-Status SentryPrivilegesFetcher::Start() {
-  // The semantics of SentryAuthzProvider's Start()/Stop() don't guarantee
-  // immutability of the Sentry service's end-point between restarts. So, since
-  // the information in the cache might become irrelevant after restarting
-  // 'sentry_client_' with different Sentry address, it makes sense to clear
-  // the cache of all accumulated entries.
-  ResetCache();
-
-  vector<HostPort> addresses;
-  RETURN_NOT_OK(HostPort::ParseStringsWithScheme(
-      FLAGS_sentry_service_rpc_addresses,
-      SentryClient::kDefaultSentryPort,
-      &addresses));
-
-  thrift::ClientOptions options;
-  options.enable_kerberos = boost::iequals(
-      FLAGS_sentry_service_security_mode, "kerberos");
-  options.service_principal =
-      FLAGS_sentry_service_kerberos_principal;
-  options.send_timeout = MonoDelta::FromSeconds(
-      FLAGS_sentry_service_send_timeout_seconds);
-  options.recv_timeout = MonoDelta::FromSeconds(
-      FLAGS_sentry_service_recv_timeout_seconds);
-  options.conn_timeout = MonoDelta::FromSeconds(
-      FLAGS_sentry_service_conn_timeout_seconds);
-  options.max_buf_size =
-      FLAGS_sentry_service_max_message_size_bytes;
-  options.retry_count =
-      FLAGS_sentry_service_retry_count;
-
-  return sentry_client_.Start(std::move(addresses), std::move(options));
-}
-
-void SentryPrivilegesFetcher::Stop() {
-  sentry_client_.Stop();
-}
-
-Status SentryPrivilegesFetcher::ResetCache() {
-  const auto cache_capacity_bytes =
-      FLAGS_sentry_privileges_cache_capacity_mb * 1024 * 1024;
-  shared_ptr<PrivilegeCache> new_cache;
-  if (cache_capacity_bytes != 0) {
-    const auto cache_entry_ttl = MonoDelta::FromSeconds(
-        FLAGS_authz_token_validity_seconds *
-        FLAGS_sentry_privileges_cache_ttl_factor);
-
-    MonoDelta cache_scrubbing_period;  // explicitly non-initialized variable
-    if (FLAGS_sentry_privileges_cache_scrubbing_period_sec > 0) {
-      cache_scrubbing_period = std::min(cache_entry_ttl, MonoDelta::FromSeconds(
-          FLAGS_sentry_privileges_cache_scrubbing_period_sec));
-    }
-
-    new_cache = make_shared<PrivilegeCache>(
-        cache_capacity_bytes, cache_entry_ttl, cache_scrubbing_period,
-        FLAGS_sentry_privileges_cache_max_scrubbed_entries_per_pass,
-        "sentry-privileges-ttl-cache");
-    if (metric_entity_) {
-      unique_ptr<SentryPrivilegesCacheMetrics> metrics(
-          new SentryPrivilegesCacheMetrics(metric_entity_));
-      new_cache->SetMetrics(std::move(metrics));
-    }
-  }
-  {
-    std::lock_guard<rw_spinlock> l(cache_lock_);
-    cache_ = new_cache;
-  }
-
-  return Status::OK();
-}
-
-Status SentryPrivilegesFetcher::GetSentryPrivileges(
-    SentryAuthorizableScope::Scope requested_scope,
-    const string& table_ident,
-    const string& user,
-    SentryCaching caching,
-    SentryPrivilegesBranch* privileges) {
-  Slice db_slice;
-  Slice table_slice;
-  RETURN_NOT_OK(ParseHiveTableIdentifier(table_ident, &db_slice, &table_slice));
-  DCHECK(!table_slice.empty());
-  DCHECK(!db_slice.empty());
-  const string table = table_slice.ToString();
-  const string db = db_slice.ToString();
-
-  // 1. Put together the requested authorizable.
-
-  TSentryAuthorizable authorizable;
-  RETURN_NOT_OK(GetAuthorizable(db, table, requested_scope, &authorizable));
-
-  if (PREDICT_FALSE(requested_scope == SentryAuthorizableScope::SERVER &&
-                    !IsGTest())) {
-    // A request for an authorizable of the scope wider than DATABASE is served,
-    // but the response from Sentry is not cached. With current privilege
-    // scheme, SentryPrivilegesFetcher is not expected to request authorizables
-    // of the SERVER scope unless this method is called from test code.
-    LOG(DFATAL) << Substitute(
-        "requesting privileges of the SERVER scope from Sentry "
-        "on authorizable '$0' for user '$1'", table_ident, user);
-  }
-
-  // Not expecting requests for authorizables of the scope narrower than TABLE,
-  // even in tests.
-  DCHECK_NE(SentryAuthorizableScope::COLUMN, requested_scope);
-
-  const AuthzInfoKey requested_info(user, authorizable);
-  // Do not query Sentry for authz scopes narrower than 'TABLE'.
-  const auto& requested_key = requested_info.GetKey(SentryAuthorizableScope::TABLE);
-  const auto& requested_key_seq = requested_info.key_sequence();
-
-  // 2. Check the cache to see if it contains the requested privileges.
-
-  // Copy the shared pointer to the cache. That's necessary because:
-  //   * the cache_ member may be reset by concurrent ResetCache()
-  //   * TTLCache is based on Cache that doesn't allow for outstanding handles
-  //     if the cache itself destructed (in this case, goes out of scope).
-  shared_ptr<PrivilegeCache> cache;
-  {
-    shared_lock<rw_spinlock> l(cache_lock_);
-    cache = cache_;
-  }
-  vector<typename PrivilegeCache::EntryHandle> handles;
-  handles.reserve(AuthzInfoKey::kKeySequenceMaxSize);
-
-  if (PREDICT_TRUE(cache)) {
-    for (const auto& e : requested_key_seq) {
-      auto handle = cache->Get(e);
-      VLOG(3) << Substitute("'$0': '$1' key lookup", requested_key, e);
-      if (!handle) {
-        continue;
-      }
-      VLOG(2) << Substitute("'$0': '$1' key found", requested_key, e);
-      handles.emplace_back(std::move(handle));
-    }
-  }
-  // If the cache contains all the necessary information, repackage the
-  // cached information and return as the result.
-  if (handles.size() == requested_key_seq.size()) {
-    SentryPrivilegesBranch result;
-    for (const auto& e : handles) {
-      DCHECK(e);
-      result.Merge(e.value());
-    }
-    *privileges = std::move(result);
-    return Status::OK();
-  }
-
-  // 3. The required privileges do not exist in the cache. Fetch them from
-  // Sentry.
-
-  // Narrow the scope of the authorizable to limit the number of privileges
-  // sent back from Sentry to be relevant to the provided table.
-  NarrowAuthzScopeForFetch(db, table, &authorizable);
-  const AuthzInfoKey full_authz_info(user, authorizable);
-  const string& full_key = full_authz_info.GetKey(SentryAuthorizableScope::TABLE);
-
-  Synchronizer sync;
-  bool is_first_request = false;
-  // The result (i.e. the retrieved informaton on privileges) might be used
-  // independently by multiple threads. The shared ownership approach simplifies
-  // passing the information around.
-  shared_ptr<SentryPrivilegesBranch> fetched_privileges;
-  {
-    std::lock_guard<simple_spinlock> l(pending_requests_lock_);
-    auto& pending_request = LookupOrEmplace(&pending_requests_,
-                                            full_key, SentryRequestsInfo());
-    // Is the queue of pending requests for the same key empty?
-    // If yes, that's the first request being sent out.
-    is_first_request = pending_request.callbacks.empty();
-    pending_request.callbacks.emplace_back(sync.AsStatusCallback());
-    if (is_first_request) {
-      DCHECK(!pending_request.result);
-      pending_request.result = make_shared<SentryPrivilegesBranch>();
-    }
-    fetched_privileges = pending_request.result;
-  }
-  if (!is_first_request) {
-    TRACE("Waiting for in-flight request to Sentry");
-    RETURN_NOT_OK(sync.Wait());
-    *privileges = *fetched_privileges;
-    return Status::OK();
-  }
-
-  TRACE("Fetching privileges from Sentry");
-  const auto s = FetchPrivilegesFromSentry(FLAGS_kudu_service_name,
-                                           user, authorizable,
-                                           fetched_privileges.get());
-
-  // 4. Cache the privileges from Sentry.
-  if (s.ok() && PREDICT_TRUE(cache)) {
-    // Put the result into the cache. Negative results (i.e. errors) are not
-    // cached. Split the information on privileges into at most two cache
-    // entries, for authorizables of scope:
-    //   * SERVER, DATABASE
-    //   * TABLE, COLUMN
-    //
-    // From this perspective, privileges on a corresponding authorizable of the
-    // DATABASE scope might be cached as a by-product when the original request
-    // comes for an authorizable of the TABLE scope.
-    SentryPrivilegesBranch priv_srv_db;
-    SentryPrivilegesBranch priv_table_column;
-    fetched_privileges->Split(&priv_srv_db, &priv_table_column);
-    if (requested_scope != SentryAuthorizableScope::SERVER) {
-      {
-        unique_ptr<SentryPrivilegesBranch> result_ptr(
-            new SentryPrivilegesBranch(std::move(priv_srv_db)));
-        const auto& db_key = full_authz_info.GetKey(SentryAuthorizableScope::DATABASE);
-        const auto result_footprint =
-            result_ptr->memory_footprint() + db_key.capacity();
-        cache->Put(db_key, std::move(result_ptr), result_footprint);
-        VLOG(2) << Substitute(
-            "added entry of size $0 bytes for key '$1' (server-database scope)",
-            result_footprint, db_key);
-      }
-      if (caching == ALL) {
-        unique_ptr<SentryPrivilegesBranch> result_ptr(
-            new SentryPrivilegesBranch(std::move(priv_table_column)));
-        const auto& table_key = full_authz_info.GetKey(SentryAuthorizableScope::TABLE);
-        const auto result_footprint =
-            result_ptr->memory_footprint() + table_key.capacity();
-        cache->Put(table_key, std::move(result_ptr), result_footprint);
-        VLOG(2) << Substitute(
-            "added entry of size $0 bytes for key '$1' (table-column scope)",
-            result_footprint, table_key);
-      }
-    }
-  }
-
-  // 5. Run any pending callbacks and return.
-  SentryRequestsInfo info;
-  {
-    std::lock_guard<simple_spinlock> l(pending_requests_lock_);
-    info = EraseKeyReturnValuePtr(&pending_requests_, full_key);
-  }
-  CHECK_LE(1, info.callbacks.size());
-  for (auto& cb : info.callbacks) {
-    cb(s);
-  }
-  RETURN_NOT_OK(s);
-  *privileges = *fetched_privileges;
-  return Status::OK();
-}
-
-// In addition to sanity checking of the contents of TSentryPrivilege in
-// 'privilege', this function has DCHECKs to spot programmer's errors
-// with regard to correctly setting fields of the 'requested_authorizable'
-// parameter.
-bool SentryPrivilegesFetcher::SentryPrivilegeIsWellFormed(
-    const TSentryPrivilege& privilege,
-    const TSentryAuthorizable& requested_authorizable,
-    SentryAuthorizableScope::Scope* scope,
-    SentryAction::Action* action) {
-  DCHECK_EQ(FLAGS_server_name, requested_authorizable.server);
-  DCHECK(!requested_authorizable.server.empty());
-  DCHECK(requested_authorizable.column.empty());
-
-  // A requested table must be accompanied by a database.
-  bool authorizable_has_db = !requested_authorizable.db.empty();
-  bool authorizable_has_table = !requested_authorizable.table.empty();
-  DCHECK((authorizable_has_db && authorizable_has_table) || !authorizable_has_table);
-
-  // Ignore anything that isn't a Kudu-related privilege.
-  SentryAuthorizableScope granted_scope;
-  SentryAction granted_action;
-  Status s = SentryAuthorizableScope::FromString(privilege.privilegeScope, &granted_scope)
-      .AndThen([&] {
-        return SentryAction::FromString(privilege.action, &granted_action);
-      });
-  if (!s.ok()) {
-    return false;
-  }
-
-  // Make sure that there aren't extraneous fields set in the privilege.
-  for (const auto& empty_field : ExpectedEmptyFields(granted_scope.scope())) {
-    switch (empty_field) {
-      case SentryAuthorizableScope::COLUMN:
-        if (!privilege.columnName.empty()) {
-          return false;
-        }
-        break;
-      case SentryAuthorizableScope::TABLE:
-        if (!privilege.tableName.empty()) {
-          return false;
-        }
-        break;
-      case SentryAuthorizableScope::DATABASE:
-        if (!privilege.dbName.empty()) {
-          return false;
-        }
-        break;
-      case SentryAuthorizableScope::SERVER:
-        if (!privilege.serverName.empty()) {
-          return false;
-        }
-        break;
-      default:
-        LOG(DFATAL) << Substitute("Granted privilege has invalid scope: $0",
-                                  sentry::ScopeToString(granted_scope.scope()));
-    }
-  }
-  // Make sure that all expected fields are set, and that they match those in
-  // the requested authorizable. Sentry auhtorizables are case-insensitive
-  // due to the properties of Kudu-HMS integration.
-  for (const auto& nonempty_field : ExpectedNonEmptyFields(granted_scope.scope())) {
-    switch (nonempty_field) {
-      case SentryAuthorizableScope::COLUMN:
-        if (!privilege.__isset.columnName || privilege.columnName.empty()) {
-          return false;
-        }
-        break;
-      case SentryAuthorizableScope::TABLE:
-        if (!privilege.__isset.tableName || privilege.tableName.empty() ||
-            (authorizable_has_table &&
-             !boost::iequals(privilege.tableName, requested_authorizable.table))) {
-          return false;
-        }
-        break;
-      case SentryAuthorizableScope::DATABASE:
-        if (!privilege.__isset.dbName || privilege.dbName.empty() ||
-            (authorizable_has_db &&
-             !boost::iequals(privilege.dbName, requested_authorizable.db))) {
-          return false;
-        }
-        break;
-      case SentryAuthorizableScope::SERVER:
-        if (privilege.serverName.empty() ||
-            !boost::iequals(privilege.serverName, requested_authorizable.server)) {
-          return false;
-        }
-        break;
-      default:
-        LOG(DFATAL) << Substitute("Granted privilege has invalid scope: $0",
-                                  sentry::ScopeToString(granted_scope.scope()));
-    }
-  }
-  *scope = granted_scope.scope();
-  *action = granted_action.action();
-  return true;
-}
-
-const AuthorizableScopesSet& SentryPrivilegesFetcher::ExpectedEmptyFields(
-    SentryAuthorizableScope::Scope scope) {
-  static const AuthorizableScopesSet kServerFields{ SentryAuthorizableScope::DATABASE,
-                                                    SentryAuthorizableScope::TABLE,
-                                                    SentryAuthorizableScope::COLUMN };
-  static const AuthorizableScopesSet kDbFields{ SentryAuthorizableScope::TABLE,
-                                                SentryAuthorizableScope::COLUMN };
-  static const AuthorizableScopesSet kTableFields{ SentryAuthorizableScope::COLUMN };
-  static const AuthorizableScopesSet kColumnFields{};
-  switch (scope) {
-    case SentryAuthorizableScope::SERVER:
-      return kServerFields;
-    case SentryAuthorizableScope::DATABASE:
-      return kDbFields;
-    case SentryAuthorizableScope::TABLE:
-      return kTableFields;
-    case SentryAuthorizableScope::COLUMN:
-      return kColumnFields;
-    default:
-      LOG(DFATAL) << "not reachable";
-  }
-  return kColumnFields;
-}
-
-const AuthorizableScopesSet& SentryPrivilegesFetcher::ExpectedNonEmptyFields(
-    SentryAuthorizableScope::Scope scope) {
-  static const AuthorizableScopesSet kColumnFields{ SentryAuthorizableScope::SERVER,
-                                                    SentryAuthorizableScope::DATABASE,
-                                                    SentryAuthorizableScope::TABLE,
-                                                    SentryAuthorizableScope::COLUMN };
-  static const AuthorizableScopesSet kTableFields{ SentryAuthorizableScope::SERVER,
-                                                   SentryAuthorizableScope::DATABASE,
-                                                   SentryAuthorizableScope::TABLE };
-  static const AuthorizableScopesSet kDbFields{ SentryAuthorizableScope::SERVER,
-                                                SentryAuthorizableScope::DATABASE };
-  static const AuthorizableScopesSet kServerFields{ SentryAuthorizableScope::SERVER };
-  switch (scope) {
-    case SentryAuthorizableScope::COLUMN:
-      return kColumnFields;
-    case SentryAuthorizableScope::TABLE:
-      return kTableFields;
-    case SentryAuthorizableScope::DATABASE:
-      return kDbFields;
-    case SentryAuthorizableScope::SERVER:
-      return kServerFields;
-    default:
-      LOG(DFATAL) << "not reachable";
-  }
-  return kColumnFields;
-}
-
-Status SentryPrivilegesFetcher::FetchPrivilegesFromSentry(
-    const string& service_name,
-    const string& user,
-    const TSentryAuthorizable& authorizable,
-    SentryPrivilegesBranch* result) {
-  TListSentryPrivilegesRequest request;
-  request.__set_requestorUserName(service_name);
-  request.__set_principalName(user);
-  request.__set_authorizableHierarchy(authorizable);
-  TListSentryPrivilegesResponse response;
-  RETURN_NOT_OK(sentry_client_.Execute(
-      [&] (SentryClient* client) {
-        return client->ListPrivilegesByUser(request, &response);
-      }));
-  *result = SentryPrivilegesBranch(authorizable, response);
-  return Status::OK();
-}
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/master/sentry_privileges_fetcher.h b/src/kudu/master/sentry_privileges_fetcher.h
deleted file mode 100644
index 5bdf51e..0000000
--- a/src/kudu/master/sentry_privileges_fetcher.h
+++ /dev/null
@@ -1,259 +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.
-
-#pragma once
-
-#include <cstddef>
-#include <functional>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <glog/logging.h>
-#include <gtest/gtest_prod.h>
-
-#include "kudu/gutil/macros.h"
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/sentry/sentry_action.h"
-#include "kudu/sentry/sentry_authorizable_scope.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/thrift/client.h"
-#include "kudu/util/bitset.h"
-#include "kudu/util/locks.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/status.h"
-#include "kudu/util/status_callback.h"
-#include "kudu/util/ttl_cache.h"
-
-namespace sentry {
-class TListSentryPrivilegesResponse;
-class TSentryAuthorizable;
-class TSentryPrivilege;
-}  // namespace sentry
-
-namespace kudu {
-namespace master {
-
-enum SentryCaching {
-  ALL,
-  SERVER_AND_DB_ONLY,
-};
-
-// Utility struct to facilitate evaluating the privileges of a given
-// authorizable. This is preferred to using Sentry's Thrift responses directly,
-// since useful information has already been parsed to generate this struct
-// (e.g. the SentryActions and scope).
-// The 'server' field is omitted: everything is implicitly bound to a particular
-// Sentry instance which is the only authoritative source of authz information
-// for Kudu in the current model of AuthzProvider.
-struct AuthorizablePrivileges {
-  AuthorizablePrivileges(sentry::SentryAuthorizableScope::Scope scope,
-                         std::string db,
-                         std::string table,
-                         std::string column)
-    : all_with_grant(false),
-      scope(scope),
-      db_name(std::move(db)),
-      table_name(std::move(table)),
-      column_name(std::move(column)) {
-#ifndef NDEBUG
-    switch (scope) {
-      case sentry::SentryAuthorizableScope::COLUMN:
-        CHECK(!column_name.empty());
-        FALLTHROUGH_INTENDED;
-      case sentry::SentryAuthorizableScope::TABLE:
-        CHECK(!table_name.empty());
-        FALLTHROUGH_INTENDED;
-      case sentry::SentryAuthorizableScope::DATABASE:
-        CHECK(!db_name.empty());
-        break;
-      case sentry::SentryAuthorizableScope::SERVER:
-        break;
-      default:
-        LOG(FATAL) << "not reachable";
-    }
-#endif
-  }
-
-  // Whether the privilege 'ALL' or 'OWNER' has been granted with Sentry's
-  // grant option enabled. Note that the grant option can be granted on any
-  // action, but for Kudu, we only use it with 'ALL' or 'OWNER'.
-  bool all_with_grant;
-
-  // The scope of the authorizable being granted the privileges.
-  sentry::SentryAuthorizableScope::Scope scope;
-
-  // The set of actions for which privileges are granted.
-  sentry::SentryActionsSet allowed_actions;
-
-  // The fields of the authorizable.
-  std::string db_name;
-  std::string table_name;
-  std::string column_name;
-};
-
-// A representation of the Sentry privilege hierarchy branch for a single table
-// (including privileges for the table's ancestors and descendents in the
-//  authz scope hierarchy) for a single user.
-class SentryPrivilegesBranch {
- public:
-  // Construct an empty instance: no information on privileges.
-  SentryPrivilegesBranch() = default;
-
-  // Construct an instance for the specified 'authorizable' from 'response'.
-  SentryPrivilegesBranch(
-      const ::sentry::TSentryAuthorizable& authorizable,
-      const ::sentry::TListSentryPrivilegesResponse& response);
-
-  // Accessor to the privileges information stored in the object.
-  const std::vector<AuthorizablePrivileges>& privileges() const {
-    return privileges_;
-  }
-
-  // Get estimation on amount of memory used (in bytes) to store this instance.
-  size_t memory_footprint() const;
-
-  // Add/merge privileges from other instance of SentryPrivilegesBranch.
-  void Merge(const SentryPrivilegesBranch& other);
-
-  // Output the privileges into branches corresponding to DB-and-higher and
-  // TABLE-and-lower authz scopes.
-  void Split(SentryPrivilegesBranch* other_scope_db,
-             SentryPrivilegesBranch* other_scope_table) const;
-
- private:
-  // Utility function.
-  void DoInit(const ::sentry::TSentryAuthorizable& authorizable,
-              const ::sentry::TListSentryPrivilegesResponse& response);
-
-  // Set of granted privileges.
-  std::vector<AuthorizablePrivileges> privileges_;
-};
-
-// A utility class to use in SentryAuthzProvider. This class provides an
-// interface for finding privileges granted to a user at some authz scope.
-// The authoritative source of the authz privileges information is Sentry,
-// where the Sentry-related parameters are specified via command line flags for
-// kudu-master binary (see the .cc file for available command line flags).
-//
-// Optionally, the fetcher can use TTL-based cache to store information
-// retrieved from Sentry, making it possible to reuse once fetched information
-// until corresponding cache entries expire.
-class SentryPrivilegesFetcher {
- public:
-  explicit SentryPrivilegesFetcher(scoped_refptr<MetricEntity> metric_entity);
-  ~SentryPrivilegesFetcher() = default;
-
-  // Start/stop the underlying Sentry client.
-  Status Start();
-  void Stop();
-
-  // Resets the authz cache. In addition to lifecycle-related methods like
-  // Start(), this method is also used by SentryAuthzProvider::ResetCache().
-  Status ResetCache();
-
-  // Fetches the user's privileges from Sentry for the authorizable specified
-  // by the given table and scope. The result privileges might be served
-  // from the cache, if caching is enabled and corresponding entry exists
-  // in the cache.
-  //
-  // If 'caching' is SERVER_AND_DB_ONLY and the SentryPrivilegesFetcher is
-  // configured to cache privileges, it will not cache privileges equal to or
-  // below the 'TABLE' scope.
-  Status GetSentryPrivileges(
-      sentry::SentryAuthorizableScope::Scope requested_scope,
-      const std::string& table_ident,
-      const std::string& user,
-      SentryCaching caching,
-      SentryPrivilegesBranch* privileges);
-
- private:
-  friend class SentryAuthzProviderFilterPrivilegesTest;
-  friend class SentryAuthzProviderTest;
-  friend class SentryPrivilegesBranch;
-  FRIEND_TEST(SentryPrivilegesFetcherStaticTest, TestPrivilegesWellFormed);
-  FRIEND_TEST(SentryAuthzProviderTest, CacheBehaviorNotCachingTableInfo);
-
-  // Utility function to determine whether the given privilege is a well-formed
-  // possibly Kudu-related privilege describing a descendent or ancestor of the
-  // requested authorizable in the Sentry hierarchy tree, i.e. it:
-  // - has a Kudu-related action (e.g. ALL, INSERT, UPDATE, etc.),
-  // - has a Kudu-related authorizable scope (e.g. SERVER, DATABASE, etc.),
-  // - all fields of equal or higher scope to the privilege's scope are set;
-  //   none lower are set, and
-  // - all fields that are set match those set by the input authorizable.
-  static bool SentryPrivilegeIsWellFormed(
-      const ::sentry::TSentryPrivilege& privilege,
-      const ::sentry::TSentryAuthorizable& requested_authorizable,
-      sentry::SentryAuthorizableScope::Scope* scope,
-      sentry::SentryAction::Action* action);
-
-  // Returns the set of scope fields expected to be non-empty in a Sentry
-  // response with the given authorizable scope. All fields of equal or higher
-  // scope are expected to be set.
-  static const sentry::AuthorizableScopesSet& ExpectedNonEmptyFields(
-      sentry::SentryAuthorizableScope::Scope scope);
-
-  // Returns the set of scope fields expected to be empty in a Sentry response
-  // with the given authorizable scope. All fields of lower scope are expected
-  // to be empty.
-  static const sentry::AuthorizableScopesSet& ExpectedEmptyFields(
-      sentry::SentryAuthorizableScope::Scope scope);
-
-  // Sends a request to fetch privileges from Sentry for the given authorizable.
-  Status FetchPrivilegesFromSentry(
-      const std::string& service_name,
-      const std::string& user,
-      const ::sentry::TSentryAuthorizable& authorizable,
-      SentryPrivilegesBranch* result);
-
-  // Metric entity for registering metric gauges/counters.
-  scoped_refptr<MetricEntity> metric_entity_;
-
-  // Client instance to communicate with Sentry.
-  thrift::HaClient<sentry::SentryClient> sentry_client_;
-
-  // The TTL cache to store information on privileges received from Sentry.
-  // The instance is wrapped into std::shared_ptr to handle operations with
-  // cache items along with concurrent requests to reset the instance.
-  typedef TTLCache<std::string, SentryPrivilegesBranch> PrivilegeCache;
-  std::shared_ptr<PrivilegeCache> cache_;
-
-  // Synchronization primitive to guard access to the cache in the presence
-  // of operations with cache items and concurrent requests to reset the cache.
-  // An alternative would be to use std::atomic_load and std::atomic_exchange,
-  // but:
-  //   * They're higher overhead operations than just using a spinlock.
-  //   * They're not available in all C++11-compatible compilers.
-  rw_spinlock cache_lock_;
-
-  // Utility dictionary to keep track of requests sent to Sentry. Access is
-  // guarded by pending_requests_lock_. The key corresponds to the set of
-  // parameters for a request sent to Sentry.
-  struct SentryRequestsInfo {
-    std::vector<StatusCallback> callbacks;
-    std::shared_ptr<SentryPrivilegesBranch> result;
-  };
-  std::unordered_map<std::string, SentryRequestsInfo> pending_requests_;
-  simple_spinlock pending_requests_lock_;
-};
-
-} // namespace master
-} // namespace kudu
diff --git a/src/kudu/mini-cluster/CMakeLists.txt b/src/kudu/mini-cluster/CMakeLists.txt
index 93dbe74..f92aee8 100644
--- a/src/kudu/mini-cluster/CMakeLists.txt
+++ b/src/kudu/mini-cluster/CMakeLists.txt
@@ -37,7 +37,6 @@
   mini_hms
   mini_kdc
   mini_ranger
-  mini_sentry
   server_base_proto
   tablet_proto
   tserver
@@ -56,5 +55,5 @@
   kudu-master)
 
 # Tests
-SET_KUDU_TEST_LINK_LIBS(mini_cluster kudu_hms kudu_sentry)
+SET_KUDU_TEST_LINK_LIBS(mini_cluster kudu_hms)
 ADD_KUDU_TEST(external_mini_cluster-test PROCESSORS 3)
diff --git a/src/kudu/mini-cluster/external_mini_cluster.cc b/src/kudu/mini-cluster/external_mini_cluster.cc
index ee6529c..c2b649a 100644
--- a/src/kudu/mini-cluster/external_mini_cluster.cc
+++ b/src/kudu/mini-cluster/external_mini_cluster.cc
@@ -53,7 +53,6 @@
 #include "kudu/rpc/sasl_common.h"
 #include "kudu/rpc/user_credentials.h"
 #include "kudu/security/test/mini_kdc.h"
-#include "kudu/sentry/mini_sentry.h"
 #include "kudu/server/server_base.pb.h"
 #include "kudu/server/server_base.proxy.h"
 #include "kudu/tablet/metadata.pb.h"
@@ -118,7 +117,6 @@
       num_data_dirs(1),
       enable_kerberos(false),
       hms_mode(HmsMode::NONE),
-      enable_sentry(false),
       enable_ranger(false),
       logtostderr(true),
       start_process_timeout(MonoDelta::FromSeconds(70)),
@@ -212,30 +210,6 @@
   return Status::OK();
 }
 
-Status ExternalMiniCluster::StartSentry() {
-  sentry_->SetDataRoot(opts_.cluster_root);
-
-  if (hms_) {
-    sentry_->EnableHms(hms_->uris());
-  }
-
-  if (opts_.enable_kerberos) {
-    string spn = Substitute("sentry/$0", sentry_->address().host());
-    string ktpath;
-    RETURN_NOT_OK_PREPEND(kdc_->CreateServiceKeytab(spn, &ktpath),
-                          "could not create keytab");
-    sentry_->EnableKerberos(kdc_->GetEnvVars()["KRB5_CONFIG"],
-                            Substitute("$0@KRBTEST.COM", spn),
-                            ktpath);
-  }
-
-  return sentry_->Start();
-}
-
-Status ExternalMiniCluster::StopSentry() {
-  return sentry_->Stop();
-}
-
 Status ExternalMiniCluster::Start() {
   CHECK(masters_.empty()) << "Masters are not empty (size: " << masters_.size()
       << "). Maybe you meant Restart()?";
@@ -302,43 +276,9 @@
   }
 #endif // #if !defined(NO_CHRONY) ...
 
-  // Start the Sentry service and the HMS in the following steps, in order
-  // to deal with the circular dependency in terms of configuring each
-  // with the other's IP/port.
-  // 1. Pick a bind IP using UNIQUE_LOOPBACK mode for the Sentry service.
-  //    Statically choose a random port. Since the Sentry service will
-  //    live on its own IP address, there's no danger of collision.
-  // 2. Start the HMS, configured to talk to the Sentry service. Find out
-  //    which port it's on.
-  // 3. Start the Sentry service with the chosen address/port from step 1.
-  //
-  // We can also pick a random port for the HMS in step 2, however, due to
-  // HIVE-18998 (which is addressed in Hive 4.0.0 by HIVE-20794), this is not
-  // an option.
-  // TODO(hao): Pick a static port for the HMS to bind to when we move to Hive 4.
-  //
-  // Note that when UNIQUE_LOOPBACK mode is not supported (i.e. on macOS),
-  // we cannot choose a port at random as that can cause a port collision.
-  // In that case, we start the Sentry service with the picked IP address
-  // and port 0 in step 1. Find out which port it's on by polling lsof.
-  // In step 3, restart the Sentry service and reconfigure it to talk to
-  // the HMS's port.
-
-  if (opts_.enable_sentry) {
-    sentry_.reset(new sentry::MiniSentry());
-    string host = GetBindIpForExternalServer(0);
-    uint16_t port = opts_.bind_mode == BindMode::UNIQUE_LOOPBACK ? 10000 : 0;
-    sentry_->SetAddress(HostPort(host, port));
-    if (opts_.bind_mode != BindMode::UNIQUE_LOOPBACK) {
-      RETURN_NOT_OK_PREPEND(StartSentry(), "Failed to start the Sentry service");
-    }
-  }
-
   if (opts_.enable_ranger) {
     string host = GetBindIpForExternalServer(0);
     ranger_.reset(new ranger::MiniRanger(cluster_root(), host));
-    // We're using the same service index as Sentry as they can't be both
-    // started at the same time.
     if (opts_.enable_kerberos) {
 
       // The SPNs match the ones defined in mini_ranger_configs.h.
@@ -390,23 +330,8 @@
                            rpc::SaslProtection::kAuthentication);
     }
 
-    if (opts_.enable_sentry) {
-      string sentry_spn = Substitute("sentry/$0@KRBTEST.COM", sentry_->address().host());
-      hms_->EnableSentry(sentry_->address(), sentry_spn);
-    }
-
     RETURN_NOT_OK_PREPEND(hms_->Start(),
                           "Failed to start the Hive Metastore");
-
-    // (Re)start Sentry with the HMS address.
-    if (opts_.enable_sentry) {
-      if (opts_.bind_mode != BindMode::UNIQUE_LOOPBACK) {
-        RETURN_NOT_OK_PREPEND(StopSentry(),
-                              "Failed to stop the Sentry service");
-      }
-      RETURN_NOT_OK_PREPEND(StartSentry(),
-                            "Failed to start the Sentry service");
-    }
   }
 
   RETURN_NOT_OK_PREPEND(StartMasters(), "failed to start masters");
@@ -634,13 +559,7 @@
         opts.extra_flags.emplace_back("--hive_metastore_sasl_enabled=true");
       }
     }
-    if (opts_.enable_sentry) {
-      opts.extra_flags.emplace_back(Substitute("--sentry_service_rpc_addresses=$0",
-                                               sentry_->address().ToString()));
-      if (!opts_.enable_kerberos) {
-        opts.extra_flags.emplace_back("--sentry_service_security_mode=none");
-      }
-    } else if (opts_.enable_ranger) {
+    if (opts_.enable_ranger) {
       opts.extra_flags.emplace_back(Substitute("--ranger_config_path=$0",
                                                JoinPathSegments(cluster_root(),
                                                                 "ranger-client")));
diff --git a/src/kudu/mini-cluster/external_mini_cluster.h b/src/kudu/mini-cluster/external_mini_cluster.h
index a117c68..d4a1da2 100644
--- a/src/kudu/mini-cluster/external_mini_cluster.h
+++ b/src/kudu/mini-cluster/external_mini_cluster.h
@@ -72,10 +72,6 @@
 class Messenger;
 } // namespace rpc
 
-namespace sentry {
-class MiniSentry;
-} // namespace sentry
-
 namespace ranger {
 class MiniRanger;
 } // namespace ranger
@@ -194,11 +190,6 @@
   // Default: HmsMode::NONE.
   HmsMode hms_mode;
 
-  // If true, set up a Sentry service as part of this ExternalMiniCluster.
-  //
-  // Default: false.
-  bool enable_sentry;
-
   // If true, set up a Ranger service as part of this ExternalMiniCluster.
   //
   // Default: false.
@@ -290,7 +281,7 @@
   // Same as above but for a master.
   std::string GetBindIpForMaster(int index) const;
 
-  // Same as above but for a external server, e.g. Sentry service or Hive Metastore.
+  // Same as above but for a external server, e.g. Ranger service or Hive Metastore.
   std::string GetBindIpForExternalServer(int index) const;
 
   // Return a pointer to the running leader master. This may be NULL
@@ -355,10 +346,6 @@
     return hms_.get();
   }
 
-  sentry::MiniSentry* sentry() const {
-    return sentry_.get();
-  }
-
   ranger::MiniRanger* ranger() const {
     return ranger_.get();
   }
@@ -476,9 +463,6 @@
  private:
   Status StartMasters();
 
-  Status StartSentry();
-  Status StopSentry();
-
   Status DeduceBinRoot(std::string* ret);
   Status HandleOptions();
 
@@ -495,7 +479,6 @@
 #endif
   std::unique_ptr<MiniKdc> kdc_;
   std::unique_ptr<hms::MiniHms> hms_;
-  std::unique_ptr<sentry::MiniSentry> sentry_;
   std::unique_ptr<ranger::MiniRanger> ranger_;
 
   std::shared_ptr<rpc::Messenger> messenger_;
diff --git a/src/kudu/ranger/ranger.proto b/src/kudu/ranger/ranger.proto
index 1f9169a..2f7cabd 100644
--- a/src/kudu/ranger/ranger.proto
+++ b/src/kudu/ranger/ranger.proto
@@ -18,7 +18,7 @@
 package kudu.ranger;
 option java_package = "org.apache.kudu.ranger";
 
-// Similar to Sentry, in Ranger, an action is an operation taken on an
+// In Ranger an action is an operation taken on an
 // authorizable, an authorizable is a linear hierarchically structured
 // resource (database -> table -> column), and 'privileges' are composed
 // of an authorizable and an action, e.g. CREATE ON DATABASE a (db=a).
@@ -27,22 +27,16 @@
 // except that ALL subsumes every other action, and every action subsumes
 // METADATA.
 
-// In term of privilege evaluation, unlike Sentry, (where authorizables higher
-// up on the hierarchy can imply authorizables lower on the hierarchy, e.g.
-// database implies table), Ranger doesn't have the concept of hierarchical
+// In term of privilege evaluation Ranger doesn't have the concept of hierarchical
 // implication. To be more specific, privilege 'METADATA ON DATABASE a (db=a)'
 // does not imply 'METADATA ON TABLE a.tbl (db=a->table=tbl)'. Thus, in Ranger
 // users granted with 'METADATA ON DATABASE a' cannot perform an action that
 // requires 'METADATA ON TABLE a.tbl'. On the other hand, Ranger supports
 // wildcard matching on authorizables, e.g. 'db=a->table=*' matches all the
-// tables that belong to DATABASE a. Therefore, in Ranger users actually need
-// 'METADATA ON db=a->table=*->column=*' privilege to match the semantics of
-// 'METADATA ON db=a' in Sentry.
+// tables that belong to DATABASE a.
 
-// Nevertheless, the same set of privileges are enforced/required for Kudu
-// operations with both Sentry and Ranger. For the detailed privilege
-// enforcement information see 'Policy for Kudu Masters/Tablet Servers'
-// section in docs/security.adoc.
+// For the detailed privilege enforcement information see 'Policy for
+// Kudu Masters/Tablet Servers' section in docs/security.adoc.
 
 enum ActionPB {
   SELECT = 0;
diff --git a/src/kudu/ranger/ranger_client.cc b/src/kudu/ranger/ranger_client.cc
index 3e6dee1..4c1c059 100644
--- a/src/kudu/ranger/ranger_client.cc
+++ b/src/kudu/ranger/ranger_client.cc
@@ -53,9 +53,7 @@
               "When set, Ranger integration is enabled, fine-grained access "
               "control is enforced, and clients are issued authorization "
               "tokens. In addition, both --ranger_java_path and --ranger_jar_path "
-              "flags need to be set properly for Ranger integration to work. "
-              "The --sentry_service_rpc_addresses flag, which enables Sentry "
-              "integration, must not be set if this is enabled.");
+              "flags need to be set properly for Ranger integration to work.");
 
 DEFINE_string(ranger_java_path, "",
               "Path where the Java binary was installed. If the value "
diff --git a/src/kudu/ranger/ranger_client.h b/src/kudu/ranger/ranger_client.h
index 8e119f9..7261005 100644
--- a/src/kudu/ranger/ranger_client.h
+++ b/src/kudu/ranger/ranger_client.h
@@ -64,11 +64,10 @@
 // NotAuthorized based on RangerClient's out parameters and return Status.
 class RangerClient {
  public:
-  // Similar to SentryAuthorizableScope scope which indicates the
-  // hierarchy of authorizables (database -> table -> column). For
-  // example, authorizable 'db=a' has database level scope, while
-  // authorizable 'db=a->table=b' has table level scope. Note that
-  // COLUMN level scope is not defined in the enum as it is not
+  // The privilege scope can indicate the hierarchy of authorizables
+  // (e.g. database -> table -> column). For example, authorizable 'db=a' has
+  // database level scope, while authorizable 'db=a->table=b' has table level scope.
+  // Note that COLUMN level scope is not defined in the enum as it is not
   // used yet in the code (although the concept still apply when
   // authorizing column level privileges).
   enum Scope {
diff --git a/src/kudu/sentry/CMakeLists.txt b/src/kudu/sentry/CMakeLists.txt
deleted file mode 100644
index acd0c63..0000000
--- a/src/kudu/sentry/CMakeLists.txt
+++ /dev/null
@@ -1,84 +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.
-
-##############################
-# sentry_thrift
-##############################
-
-THRIFT_GENERATE_CPP(
-  SENTRY_THRIFT_SRCS SENTRY_THRIFT_HDRS SENTRY_THRIFT_TGTS
-  THRIFT_FILES sentry_common_service.thrift sentry_policy_service.thrift)
-
-add_library(sentry_thrift ${SENTRY_THRIFT_SRCS} thrift_operators.cc)
-target_link_libraries(sentry_thrift thrift)
-add_dependencies(sentry_thrift ${SENTRY_THRIFT_TGTS})
-
-##############################
-# kudu_sentry
-##############################
-
-set(SENTRY_SRCS
-  sentry_action.cc
-  sentry_authorizable_scope.cc
-  sentry_client.cc)
-set(SENTRY_DEPS
-  kudu_common
-  kudu_thrift
-  kudu_util
-  sentry_thrift)
-
-add_library(kudu_sentry ${SENTRY_SRCS})
-target_link_libraries(kudu_sentry ${SENTRY_DEPS})
-
-##############################
-# mini_sentry
-##############################
-
-execute_process(COMMAND ln -nsf
-                "${CMAKE_SOURCE_DIR}/thirdparty/installed/common/opt/sentry"
-                "${EXECUTABLE_OUTPUT_PATH}/sentry-home")
-execute_process(COMMAND ln -nsf
-                "${CMAKE_SOURCE_DIR}/thirdparty/installed/common/opt/hadoop"
-                "${EXECUTABLE_OUTPUT_PATH}/hadoop-home")
-execute_process(COMMAND ln -nsf
-                "${JAVA_HOME}"
-                "${EXECUTABLE_OUTPUT_PATH}/java-home")
-
-set(MINI_SENTRY_SRCS
-  mini_sentry.cc)
-
-add_library(mini_sentry ${MINI_SENTRY_SRCS})
-target_link_libraries(mini_sentry
-  gutil
-  kudu_test_util
-  kudu_util)
-
-##############################
-# sentry tests
-##############################
-
-if (NOT NO_TESTS)
-  SET_KUDU_TEST_LINK_LIBS(
-    kudu_sentry
-    mini_kdc
-    mini_sentry)
-
-  ADD_KUDU_TEST(sentry_action-test)
-  ADD_KUDU_TEST(sentry_authorizable_scope-test)
-  ADD_KUDU_TEST(sentry_client-test)
-  ADD_KUDU_TEST(thrift_operators-test)
-endif()
diff --git a/src/kudu/sentry/mini_sentry.cc b/src/kudu/sentry/mini_sentry.cc
deleted file mode 100644
index cb3bbe1..0000000
--- a/src/kudu/sentry/mini_sentry.cc
+++ /dev/null
@@ -1,366 +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.
-
-#include "kudu/sentry/mini_sentry.h"
-
-#include <algorithm>
-#include <csignal>
-#include <map>
-#include <memory>
-#include <ostream>
-#include <string>
-
-#include <glog/logging.h>
-
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/util/env.h"
-#include "kudu/util/monotime.h"
-#include "kudu/util/path_util.h"
-#include "kudu/util/slice.h"
-#include "kudu/util/status.h"
-#include "kudu/util/stopwatch.h"
-#include "kudu/util/subprocess.h"
-#include "kudu/util/test_util.h"
-
-using std::map;
-using std::string;
-using std::unique_ptr;
-using strings::Substitute;
-
-static constexpr int kSentryStartTimeoutMs = 120000;
-
-namespace kudu {
-namespace sentry {
-
-MiniSentry::MiniSentry() {
-}
-
-MiniSentry::~MiniSentry() {
-  WARN_NOT_OK(Stop(), "Failed to stop MiniSentry");
-}
-
-void MiniSentry::EnableKerberos(string krb5_conf,
-                                string service_principal,
-                                string keytab_file) {
-  CHECK(!sentry_process_);
-  CHECK(!krb5_conf.empty());
-  CHECK(!service_principal.empty());
-  CHECK(!keytab_file.empty());
-  krb5_conf_ = std::move(krb5_conf);
-  service_principal_ = std::move(service_principal);
-  keytab_file_ = std::move(keytab_file);
-}
-
-void MiniSentry::EnableHms(string hms_uris) {
-  CHECK(!sentry_process_);
-  hms_uris_ = std::move(hms_uris);
-}
-
-void MiniSentry::SetDataRoot(string data_root) {
-  CHECK(!sentry_process_);
-  data_root_ = std::move(data_root);
-}
-
-void MiniSentry::SetAddress(const HostPort& address) {
-  CHECK(!sentry_process_);
-  ip_ = address.host();
-  port_ = address.port();
-}
-
-Status MiniSentry::Start() {
-  SCOPED_LOG_TIMING(INFO, "Starting Sentry");
-  CHECK(!sentry_process_);
-
-  VLOG(1) << "Starting Sentry";
-
-  Env* env = Env::Default();
-
-  string exe;
-  RETURN_NOT_OK(env->GetExecutablePath(&exe));
-  const string bin_dir = DirName(exe);
-
-  string hadoop_home;
-  string sentry_home;
-  string java_home;
-  RETURN_NOT_OK(FindHomeDir("hadoop", bin_dir, &hadoop_home));
-  RETURN_NOT_OK(FindHomeDir("sentry", bin_dir, &sentry_home));
-  RETURN_NOT_OK(FindHomeDir("java", bin_dir, &java_home));
-
-  if (data_root_.empty()) {
-    data_root_ = GetTestDataDirectory();
-  }
-
-  RETURN_NOT_OK(CreateSentryConfigs(data_root_));
-
-  // List of JVM environment options to pass to the Sentry service.
-  string java_options;
-  if (!krb5_conf_.empty()) {
-    java_options += Substitute(" -Djava.security.krb5.conf=$0", krb5_conf_);
-  }
-  if (IsHmsEnabled()) {
-    java_options += Substitute(" -Dhive.metastore.uris=$0"
-        " -Dhive.metastore.sasl.enabled=$1"
-        " -Dhive.metastore.kerberos.principal=hive/127.0.0.1@KRBTEST.COM",
-        hms_uris_, IsKerberosEnabled());
-  }
-
-  const map<string, string> env_vars {
-      { "JAVA_HOME", java_home },
-      { "HADOOP_HOME", hadoop_home },
-      { "JAVA_TOOL_OPTIONS", java_options },
-  };
-
-  // Start Sentry.
-  sentry_process_.reset(new Subprocess({
-      Substitute("$0/bin/sentry", sentry_home),
-      "--log4jConf", JoinPathSegments(data_root_, "log4j.properties"),
-      "--command", "service",
-      "--conffile", JoinPathSegments(data_root_, "sentry-site.xml"),
-  }));
-
-  sentry_process_->SetEnvVars(env_vars);
-  RETURN_NOT_OK(sentry_process_->Start());
-
-  // Wait for Sentry to start listening on its ports and commencing operation.
-  VLOG(1) << "Waiting for Sentry ports";
-
-  uint16_t orig_port = port_;
-  Status wait = WaitForTcpBind(sentry_process_->pid(), &port_, ip_,
-                               MonoDelta::FromMilliseconds(kSentryStartTimeoutMs));
-  // Check that the port number only changed if the original port was 0
-  // (i.e. if we asked to bind to an ephemeral port)
-  CHECK(orig_port == 0 || port_ == orig_port);
-  if (!wait.ok()) {
-    WARN_NOT_OK(sentry_process_->Kill(SIGQUIT), "failed to send SIGQUIT to Sentry");
-  }
-  return wait;
-}
-
-Status MiniSentry::Stop() {
-  if (sentry_process_) {
-    VLOG(1) << "Stopping Sentry";
-    unique_ptr<Subprocess> proc = std::move(sentry_process_);
-    RETURN_NOT_OK_PREPEND(proc->KillAndWait(SIGTERM), "failed to stop the Sentry service");
-  }
-  return Status::OK();
-}
-
-Status MiniSentry::Pause() {
-  CHECK(sentry_process_);
-  VLOG(1) << "Pausing Sentry";
-  RETURN_NOT_OK_PREPEND(sentry_process_->Kill(SIGSTOP),
-                        "failed to pause the Sentry service");
-  return Status::OK();
-}
-
-Status MiniSentry::Resume() {
-  CHECK(sentry_process_);
-  VLOG(1) << "Resuming Sentry";
-  RETURN_NOT_OK_PREPEND(sentry_process_->Kill(SIGCONT),
-                        "failed to unpause the Sentry service");
-  return Status::OK();
-}
-
-Status MiniSentry::CreateSentryConfigs(const string& tmp_dir) const {
-
-  // - sentry.store.jdbc.url
-  // - sentry.store.jdbc.password
-  //     Configures Sentry to use a local in-process Derby instance with a dummy
-  //     password value.
-  //
-  // - datanucleus.schema.autoCreateAll
-  // - sentry.verify.schema.version
-  //     Allow Sentry to startup and run without first running the schemaTool.
-  //
-  // - sentry.store.group.mapping
-  //   sentry.store.group.mapping.resource
-  //     Production Sentry instances use Hadoop's UGI infrastructure to map users
-  //     to groups, but that's difficult to mock for tests, so we configure a
-  //     simpler static user/group mapping based on a generated INI file.
-  //
-  // - sentry.service.admin.group
-  //     Set up admin groups which have unrestricted privileges in Sentry.
-  //
-  // - sentry.service.allow.connect
-  //     Set of Kerberos principals which is allowed to connect to Sentry when
-  //     the Kerberos security mode is enabled.
-  //
-  // - sentry.service.server.rpc-port
-  //     Port number that the Sentry service starts with.
-  //
-  // - sentry.service.server.rpc-address
-  //     IP address that the Sentry service starts with.
-  //
-  // - sentry.db.policy.store.owner.as.privilege
-  //    Configures Sentry to enable owner privileges feature which automatically
-  //    derives OWNER/ALL privileges from object's ownership. 'all' indicates an
-  //    object owner has OWNER/ALL privilege on the object, but cannot transfer
-  //    owner privileges to another user or role.
-  //
-  // - sentry.store.clean.period.seconds
-  //    The interval to run the "store-cleaner" Sentry's thread. Setting to a
-  //    negative value means Sentry will not run the "store-cleaner" thread
-  //    at all and that allows for faster start-up times of the Sentry service.
-  //
-  // - hive.sentry.server
-  //    Server namespace the HMS instance belongs to for defining server-level
-  //    privileges in Sentry. Sentry uses it to synchronize privileges upon
-  //    receipt of HMS events (such as table rename). Must match with Kudu
-  //    master's flag 'server_name'.
-  static const string kFileTemplate = R"(
-<configuration>
-
-  <property>
-    <name>sentry.service.security.mode</name>
-    <value>$0</value>
-  </property>
-
-  <property>
-    <name>sentry.service.server.principal</name>
-    <value>$1</value>
-  </property>
-
-  <property>
-    <name>sentry.service.server.keytab</name>
-    <value>$2</value>
-  </property>
-
-  <property>
-    <name>sentry.store.jdbc.url</name>
-    <value>jdbc:derby:$3/sentry;create=true</value>
-  </property>
-
-  <property>
-    <name>sentry.store.jdbc.password</name>
-    <value>_</value>
-  </property>
-
-  <property>
-    <name>datanucleus.schema.autoCreateAll</name>
-    <value>true</value>
-  </property>
-
-  <property>
-    <name>sentry.verify.schema.version</name>
-    <value>false</value>
-  </property>
-
-  <property>
-    <name>sentry.store.group.mapping</name>
-    <value>org.apache.sentry.provider.file.LocalGroupMappingService</value>
-  </property>
-
-  <property>
-    <name>sentry.store.group.mapping.resource</name>
-    <value>$4</value>
-  </property>
-
-  <property>
-    <name>sentry.service.server.rpc-port</name>
-    <value>$5</value>
-  </property>
-
-  <property>
-    <name>sentry.service.server.rpc-address</name>
-    <value>$6</value>
-  </property>
-
-  <property>
-    <name>sentry.service.admin.group</name>
-    <value>admin</value>
-  </property>
-
-  <property>
-    <name>sentry.service.allow.connect</name>
-    <value>kudu,hive</value>
-  </property>
-
-  <property>
-    <name>sentry.db.policy.store.owner.as.privilege</name>
-    <value>all</value>
-  </property>
-
-  <property>
-    <name>sentry.store.clean.period.seconds</name>
-    <value>-1</value>
-  </property>
-
-  <property>
-    <name>hive.sentry.server</name>
-    <value>server1</value>
-  </property>
-
-</configuration>
-  )";
-
-  string users_ini_path = JoinPathSegments(tmp_dir, "users.ini");
-  string file_contents = Substitute(
-      kFileTemplate,
-      IsKerberosEnabled() ? "kerberos" : "none",
-      service_principal_,
-      keytab_file_,
-      tmp_dir,
-      users_ini_path,
-      port_,
-      ip_);
-  RETURN_NOT_OK(WriteStringToFile(Env::Default(),
-                                  file_contents,
-                                  JoinPathSegments(tmp_dir, "sentry-site.xml")));
-
-  // Simple file format containing mapping of user to groups in INI syntax, see
-  // the LocalGroupMappingService class for more information.
-  static const string kUsers = R"(
-[users]
-test-admin=admin
-test-user=user
-kudu=admin
-joe-interloper=""
-user0=group0
-user1=group1
-user2=group2
-  )";
-
-  RETURN_NOT_OK(WriteStringToFile(Env::Default(), kUsers, users_ini_path));
-
-  // Configure the Sentry service to output WARN messages to the stderr
-  // console, and INFO and above to sentry.log in the data root. The console
-  // messages have a special 'SENTRY' tag included to disambiguate them from other
-  // Java component logs.
-  static const string kLogPropertiesTemplate = R"(
-log4j.appender.console = org.apache.log4j.ConsoleAppender
-log4j.appender.console.layout = org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern = %d{HH:mm:ss.SSS} [SENTRY - %p - %t] (%F:%L) %m%n
-log4j.appender.console.Threshold = WARN
-
-log4j.appender.file = org.apache.log4j.FileAppender
-log4j.appender.file.File = $0
-log4j.appender.file.layout = org.apache.log4j.PatternLayout
-log4j.appender.file.layout.ConversionPattern = %d{HH:mm:ss.SSS} [%p - %t] (%F:%L) %m%n
-
-log4j.rootLogger = INFO, console, file
-  )";
-  string log_properties = Substitute(
-      kLogPropertiesTemplate,
-      JoinPathSegments(tmp_dir, "sentry.log"));
-  RETURN_NOT_OK(WriteStringToFile(Env::Default(),
-                                  log_properties,
-                                  JoinPathSegments(tmp_dir, "log4j.properties")));
-
-  return Status::OK();
-}
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/mini_sentry.h b/src/kudu/sentry/mini_sentry.h
deleted file mode 100644
index 36635c7..0000000
--- a/src/kudu/sentry/mini_sentry.h
+++ /dev/null
@@ -1,112 +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.
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "kudu/gutil/port.h"
-#include "kudu/util/net/net_util.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-
-class Subprocess;
-
-namespace sentry {
-
-class MiniSentry {
- public:
-
-  MiniSentry();
-
-  ~MiniSentry();
-
-  // Configures the mini Sentry service to use Kerberos.
-  void EnableKerberos(std::string krb5_conf,
-                      std::string service_principal,
-                      std::string keytab_file);
-
-  // Configures the mini Sentry service to connect to a Hive Metastore instance.
-  void EnableHms(std::string hms_uris);
-
-  // Configures the mini Sentry service to store its data in the provided path.
-  // If not set, it uses a test-only temporary directory.
-  void SetDataRoot(std::string data_root);
-
-  // Configures the mini Sentry service to start with the provided address.
-  // If not set, it uses the default Ip and port number.
-  void SetAddress(const HostPort& address);
-
-  // Starts the mini Sentry service.
-  //
-  // If the MiniSentry has already been started and stopped, it will be restarted
-  // using the same listening port.
-  Status Start() WARN_UNUSED_RESULT;
-
-  // Stops the mini Sentry service.
-  Status Stop() WARN_UNUSED_RESULT;
-
-  // Pause the Sentry service.
-  Status Pause() WARN_UNUSED_RESULT;
-
-  // Unpause the Sentry service.
-  Status Resume() WARN_UNUSED_RESULT;
-
-  // Returns the address of the mini Sentry service. Should only be called after the
-  // Sentry service is started.
-  HostPort address() const {
-    return HostPort(ip_, port_);
-  }
-
-  // Returns true when Kerberos is enabled.
-  bool IsKerberosEnabled() const {
-    return !keytab_file_.empty();
-  }
-
-  // Returns true when the HMS is enabled.
-  bool IsHmsEnabled() const {
-    return !hms_uris_.empty();
-  }
-
- private:
-
-  // Creates a sentry-site.xml for the mini Sentry, and other supporting
-  // configuration files.
-  Status CreateSentryConfigs(const std::string& tmp_dir) const WARN_UNUSED_RESULT;
-
-  std::unique_ptr<Subprocess> sentry_process_;
-
-  // Port number of the mini Sentry service. Default to 0.
-  uint16_t port_ = 0;
-  // Ip address of the mini Sentry service. Default to 0.0.0.0.
-  std::string ip_ = "0.0.0.0";
-  std::string data_root_;
-
-  // Kerberos configuration
-  std::string krb5_conf_;
-  std::string service_principal_;
-  std::string keytab_file_;
-
-  // HMS configuration
-  std::string hms_uris_;
-};
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry-test-base.h b/src/kudu/sentry/sentry-test-base.h
deleted file mode 100644
index 3a2ea71..0000000
--- a/src/kudu/sentry/sentry-test-base.h
+++ /dev/null
@@ -1,91 +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.
-
-#pragma once
-
-#include <string>
-
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/rpc/sasl_common.h"
-#include "kudu/security/test/mini_kdc.h"
-#include "kudu/sentry/mini_sentry.h"
-#include "kudu/sentry/sentry_client.h"
-#include "kudu/thrift/client.h"
-#include "kudu/util/net/net_util.h"
-#include "kudu/util/test_macros.h"
-#include "kudu/util/test_util.h"
-
-namespace kudu {
-namespace sentry {
-
-class SentryTestBase : public KuduTest {
- public:
-
-  void SetUp() override {
-    KuduTest::SetUp();
-
-    thrift::ClientOptions sentry_client_opts;
-    sentry_.reset(new MiniSentry());
-    std::string host = GetBindIpForDaemon(1, kDefaultBindMode);
-    HostPort address(host, 0);
-    sentry_->SetAddress(address);
-    if (KerberosEnabled()) {
-      kdc_.reset(new MiniKdc(MiniKdcOptions()));
-      ASSERT_OK(kdc_->Start());
-
-      // Create a service principal for the Sentry, and configure it to use it.
-      std::string spn = strings::Substitute("sentry/$0", host);
-      std::string ktpath;
-      ASSERT_OK(kdc_->CreateServiceKeytab(spn, &ktpath));
-
-      sentry_->EnableKerberos(kdc_->GetEnvVars()["KRB5_CONFIG"],
-                              strings::Substitute("$0@KRBTEST.COM", spn),
-                              ktpath);
-
-      ASSERT_OK(rpc::SaslInit());
-      // Create a principal 'kudu' for the SentryAuthzProvider, and configure it
-      // to use it.
-      ASSERT_OK(kdc_->CreateUserPrincipal("kudu"));
-      ASSERT_OK(kdc_->Kinit("kudu"));
-      ASSERT_OK(kdc_->SetKrb5Environment());
-      sentry_client_opts.enable_kerberos = true;
-      sentry_client_opts.service_principal = "sentry";
-    }
-
-    ASSERT_OK(sentry_->Start());
-    sentry_client_.reset(new SentryClient(sentry_->address(), sentry_client_opts));
-    ASSERT_OK(sentry_client_->Start());
-  }
-
-  void TearDown() override {
-    if (sentry_client_) {
-      ASSERT_OK(sentry_client_->Stop());
-    }
-    ASSERT_OK(sentry_->Stop());
-    KuduTest::TearDown();
-  }
-
-  virtual bool KerberosEnabled() const = 0;
-
- protected:
-  std::unique_ptr<MiniKdc> kdc_;
-  std::unique_ptr<MiniSentry> sentry_;
-  std::unique_ptr<SentryClient> sentry_client_;
-};
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_action-test.cc b/src/kudu/sentry/sentry_action-test.cc
deleted file mode 100644
index 1f1644d..0000000
--- a/src/kudu/sentry/sentry_action-test.cc
+++ /dev/null
@@ -1,88 +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.
-
-#include "kudu/sentry/sentry_action.h"
-
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "kudu/util/status.h"
-#include "kudu/util/test_macros.h"
-
-using std::string;
-using std::vector;
-
-namespace kudu {
-
-namespace sentry {
-
-TEST(SentryActionTest, TestImplyAction) {
-  SentryAction all(SentryAction::Action::ALL);
-  SentryAction metadata(SentryAction::Action::METADATA);
-  SentryAction select(SentryAction::Action::SELECT);
-  SentryAction insert(SentryAction::Action::INSERT);
-  SentryAction update(SentryAction::Action::UPDATE);
-  SentryAction del(SentryAction::Action::DELETE);
-  SentryAction alter(SentryAction::Action::ALTER);
-  SentryAction create(SentryAction::Action::CREATE);
-  SentryAction drop(SentryAction::Action::DROP);
-  SentryAction owner(SentryAction::Action::OWNER);
-
-  // Different action cannot imply each other.
-  ASSERT_FALSE(insert.Implies(select));
-  ASSERT_FALSE(select.Implies(insert));
-
-  vector<SentryAction> actions({ all, select, insert, update,
-                                 del, alter, create, drop, owner });
-
-  // Any action subsumes METADATA, not vice versa.
-  for (const auto& action : actions) {
-    ASSERT_TRUE(action.Implies(metadata));
-    ASSERT_FALSE(metadata.Implies(action));
-  }
-
-  actions.emplace_back(metadata);
-  for (const auto& action : actions) {
-    // Action ALL implies all other actions.
-    ASSERT_TRUE(all.Implies(action));
-
-    // Action OWNER equals to ALL, which implies all other actions.
-    ASSERT_TRUE(owner.Implies(action));
-
-    // Any action implies itself.
-    ASSERT_TRUE(action.Implies(action));
-  }
-}
-
-TEST(SentryActionTest, TestFromString) {
-  // Action '*' equals to ALL.
-  SentryAction wildcard;
-  ASSERT_OK(SentryAction::FromString(SentryAction::kWildCard, &wildcard));
-  SentryAction all(SentryAction::Action::ALL);
-  ASSERT_TRUE(all.Implies(wildcard));
-  ASSERT_TRUE(wildcard.Implies(all));
-
-  // Unsupported action, such as '+', throws invalid argument error.
-  SentryAction invalid_action;
-  Status s = SentryAction::FromString("+", &invalid_action);
-  ASSERT_TRUE(s.IsInvalidArgument()) << s.ToString();
-}
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_action.cc b/src/kudu/sentry/sentry_action.cc
deleted file mode 100644
index f63ac0a..0000000
--- a/src/kudu/sentry/sentry_action.cc
+++ /dev/null
@@ -1,120 +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.
-
-#include "kudu/sentry/sentry_action.h"
-
-#include <cstdint>
-
-#include <ostream>
-#include <string>
-
-#include <boost/algorithm/string/predicate.hpp>
-#include <glog/logging.h>
-
-#include "kudu/gutil/strings/substitute.h"
-
-using std::string;
-using strings::Substitute;
-
-namespace kudu {
-namespace sentry {
-
-const char* ActionToString(SentryAction::Action action) {
-  switch (action) {
-    case SentryAction::Action::UNINITIALIZED: return "UNINITIALIZED";
-    case SentryAction::Action::ALL: return kActionAll;
-    case SentryAction::Action::METADATA: return kActionMetadata;
-    case SentryAction::Action::SELECT: return kActionSelect;
-    case SentryAction::Action::INSERT: return kActionInsert;
-    case SentryAction::Action::UPDATE: return kActionUpdate;
-    case SentryAction::Action::DELETE: return kActionDelete;
-    case SentryAction::Action::ALTER: return kActionAlter;
-    case SentryAction::Action::CREATE: return kActionCreate;
-    case SentryAction::Action::DROP: return kActionDrop;
-    case SentryAction::Action::OWNER: return kActionOwner;
-  }
-  LOG(FATAL) << static_cast<uint16_t>(action) << ": unknown action";
-  return nullptr;
-}
-
-std::ostream& operator<<(std::ostream& o, SentryAction::Action action) {
-  return o << ActionToString(action);
-}
-
-const char* const SentryAction::kWildCard = "*";
-
-SentryAction::SentryAction()
-  : action_(Action::UNINITIALIZED) {
-}
-
-SentryAction::SentryAction(Action action)
-  : action_(action) {
-}
-
-Status SentryAction::FromString(const string& str, SentryAction* action) {
-  // Consider action '*' equals to ALL to be compatible with the existing
-  // Java Sentry client.
-  //
-  // See org.apache.sentry.api.service.thrift.SentryPolicyServiceClientDefaultImpl.
-  if (boost::iequals(str, kActionAll) || str == kWildCard) {
-    action->action_ = Action::ALL;
-  } else if (boost::iequals(str, kActionMetadata)) {
-    action->action_ = Action::METADATA;
-  } else if (boost::iequals(str, kActionSelect)) {
-    action->action_ = Action::SELECT;
-  } else if (boost::iequals(str, kActionInsert)) {
-    action->action_ = Action::INSERT;
-  } else if (boost::iequals(str, kActionUpdate)) {
-    action->action_ = Action::UPDATE;
-  } else if (boost::iequals(str, kActionDelete)) {
-    action->action_ = Action::DELETE;
-  } else if (boost::iequals(str, kActionAlter)) {
-    action->action_ = Action::ALTER;
-  } else if (boost::iequals(str, kActionCreate)) {
-    action->action_ = Action::CREATE;
-  } else if (boost::iequals(str, kActionDrop)) {
-    action->action_ = Action::DROP;
-  } else if (boost::iequals(str, kActionOwner)) {
-    action->action_ = Action::OWNER;
-  } else {
-    return Status::InvalidArgument(Substitute("unknown SentryAction: $0", str));
-  }
-
-  return Status::OK();
-}
-
-bool SentryAction::Implies(const SentryAction& other) const {
-  // Every action must be initialized.
-  CHECK_NE(action(), Action::UNINITIALIZED);
-  CHECK_NE(other.action(), Action::UNINITIALIZED);
-
-  // Action ALL and OWNER subsume every other action.
-  if (action() == Action::ALL ||
-      action() == Action::OWNER) {
-    return true;
-  }
-
-  // Any action subsumes Action METADATA.
-  if (other.action() == Action::METADATA) {
-    return true;
-  }
-
-  return action() == other.action();
-}
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_action.h b/src/kudu/sentry/sentry_action.h
deleted file mode 100644
index 0793352..0000000
--- a/src/kudu/sentry/sentry_action.h
+++ /dev/null
@@ -1,112 +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.
-
-#pragma once
-
-#include <cstddef>
-#include <iosfwd>
-#include <string>
-
-#include "kudu/gutil/port.h"
-#include "kudu/util/bitset.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-namespace sentry {
-
-// A carbon copy of Sentry Action, which is the operation taken
-// on an authorizable, and authorizable is linear hierarchical
-// structured resource. In this case, HiveSQL privilege model is
-// chosen to define authorizables (server → database → table → column)
-// and actions (create, drop, etc.) to authorize users' operations
-// (e.g. create a table, drop a database).
-// See org.apache.sentry.core.model.db.HivePrivilegeModel.
-//
-// One action can imply another following rules defined in Implies().
-class SentryAction {
- public:
-  static const char* const kWildCard;
-
-  // Actions that are supported. All actions are independent,
-  // except that ALL subsumes every other action, and every
-  // action subsumes METADATA. OWNER is a special action that
-  // behaves like ALL.
-  // Note that 'UNINITIALIZED' is not an actual operation but
-  // only to represent an action in uninitialized state.
-  //
-  // See org.apache.sentry.core.model.db.HiveActionFactory.
-  enum Action {
-    UNINITIALIZED,
-    ALL,
-    METADATA,
-    SELECT,
-    INSERT,
-    UPDATE,
-    DELETE,
-    ALTER,
-    CREATE,
-    DROP,
-    OWNER,
-  };
-  static const size_t kMaxAction = Action::OWNER + 1;
-
-  // The default constructor is useful when creating an Action
-  // from string.
-  SentryAction();
-
-  explicit SentryAction(Action action);
-
-  Action action() const {
-    return action_;
-  }
-
-  // Create an Action from string.
-  static Status FromString(const std::string& str,
-                           SentryAction* action) WARN_UNUSED_RESULT;
-
-  // Check if this action implies 'other'. In general,
-  //   1. an action only implies itself.
-  //   2. with the exceptions that ALL, OWNER imply all other actions,
-  //      and any action implies METADATA.
-  //
-  // See org.apache.sentry.policy.common.CommonPrivilege.impliesAction.
-  bool Implies(const SentryAction& other) const;
-
- private:
-  Action action_;
-};
-
-static constexpr const char* const kActionAll = "ALL";
-static constexpr const char* const kActionMetadata = "METADATA";
-static constexpr const char* const kActionSelect = "SELECT";
-static constexpr const char* const kActionInsert = "INSERT";
-static constexpr const char* const kActionUpdate = "UPDATE";
-static constexpr const char* const kActionDelete = "DELETE";
-static constexpr const char* const kActionAlter = "ALTER";
-static constexpr const char* const kActionCreate = "CREATE";
-static constexpr const char* const kActionDrop = "DROP";
-static constexpr const char* const kActionOwner = "OWNER";
-
-const char* ActionToString(SentryAction::Action action);
-
-std::ostream& operator<<(std::ostream& o, SentryAction::Action action);
-
-typedef FixedBitSet<sentry::SentryAction::Action, sentry::SentryAction::kMaxAction>
-    SentryActionsSet;
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_authorizable_scope-test.cc b/src/kudu/sentry/sentry_authorizable_scope-test.cc
deleted file mode 100644
index 72bd9c7..0000000
--- a/src/kudu/sentry/sentry_authorizable_scope-test.cc
+++ /dev/null
@@ -1,83 +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.
-
-#include "kudu/sentry/sentry_authorizable_scope.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "kudu/util/status.h"
-#include "kudu/util/test_macros.h"
-
-using std::pair;
-using std::string;
-using std::vector;
-
-namespace kudu {
-
-namespace sentry {
-
-TEST(SentryAuthorizableScopeTest, TestImplyScope) {
-  SentryAuthorizableScope server(SentryAuthorizableScope::Scope::SERVER);
-  SentryAuthorizableScope database(SentryAuthorizableScope::Scope::DATABASE);
-  SentryAuthorizableScope table(SentryAuthorizableScope::Scope::TABLE);
-  SentryAuthorizableScope column(SentryAuthorizableScope::Scope::COLUMN);
-
-  vector<SentryAuthorizableScope> scopes({ column, table, database, server });
-  vector<SentryAuthorizableScope> lower_scopes;
-  vector<SentryAuthorizableScope> higher_scopes({ server, database, table, column });
-
-  // A higher scope in the hierarchy can imply a lower scope in the hierarchy,
-  // not vice versa.
-  for (const auto& scope : scopes) {
-    lower_scopes.emplace_back(scope);
-    higher_scopes.pop_back();
-    for (const auto &lower_scope : lower_scopes) {
-      ASSERT_TRUE(scope.Implies(lower_scope));
-    }
-    for (const auto &higher_scope : higher_scopes) {
-      ASSERT_FALSE(scope.Implies(higher_scope));
-    }
-  }
-}
-
-TEST(SentryAuthorizableScopeTest, TestFromString) {
-  const vector<pair<string, SentryAuthorizableScope::Scope>> valid_scopes = {
-      {"server", SentryAuthorizableScope::Scope::SERVER},
-      {"database", SentryAuthorizableScope::Scope::DATABASE},
-      {"table", SentryAuthorizableScope::Scope::TABLE},
-      {"column", SentryAuthorizableScope::Scope::COLUMN}
-  };
-  SentryAuthorizableScope scope;
-  for (const auto& valid_scope : valid_scopes) {
-    ASSERT_OK(SentryAuthorizableScope::FromString(valid_scope.first, &scope));
-    ASSERT_EQ(valid_scope.second, scope.scope());
-  }
-
-  // Unsupported scope returns invalid argument error.
-  const vector<string> invalid_scopes({ "UNINITIALIZED", "tablecolumn" });
-  for (const auto& invalid_scope : invalid_scopes) {
-    Status s = SentryAuthorizableScope::FromString(invalid_scope, &scope);
-    ASSERT_TRUE(s.IsInvalidArgument()) << s.ToString();
-  }
-}
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_authorizable_scope.cc b/src/kudu/sentry/sentry_authorizable_scope.cc
deleted file mode 100644
index 758666d..0000000
--- a/src/kudu/sentry/sentry_authorizable_scope.cc
+++ /dev/null
@@ -1,100 +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.
-
-#include "kudu/sentry/sentry_authorizable_scope.h"
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-
-#include <boost/algorithm/string/predicate.hpp>
-#include <glog/logging.h>
-
-#include "kudu/gutil/strings/substitute.h"
-
-using std::string;
-using strings::Substitute;
-
-namespace kudu {
-namespace sentry {
-
-const char* ScopeToString(SentryAuthorizableScope::Scope scope) {
-  switch (scope) {
-    case SentryAuthorizableScope::Scope::UNINITIALIZED: return "UNINITIALIZED";
-    case SentryAuthorizableScope::Scope::SERVER: return kServer;
-    case SentryAuthorizableScope::Scope::DATABASE: return kDatabase;
-    case SentryAuthorizableScope::Scope::TABLE: return kTable;
-    case SentryAuthorizableScope::Scope::COLUMN: return kColumn;
-  }
-  LOG(FATAL) << static_cast<uint16_t>(scope) << ": unknown scope";
-  return nullptr;
-}
-
-std::ostream& operator<<(std::ostream& o, SentryAuthorizableScope::Scope scope) {
-  return o << ScopeToString(scope);
-}
-
-SentryAuthorizableScope::SentryAuthorizableScope()
-  : scope_(Scope::UNINITIALIZED) {
-}
-
-SentryAuthorizableScope::SentryAuthorizableScope(Scope scope)
-  : scope_(scope) {
-}
-
-Status SentryAuthorizableScope::FromString(const string& str,
-                                           SentryAuthorizableScope* scope) {
-  if (boost::iequals(str, kServer)) {
-    scope->scope_ = Scope::SERVER;
-  } else if (boost::iequals(str, kDatabase)) {
-    scope->scope_ = Scope::DATABASE;
-  } else if (boost::iequals(str, kTable)) {
-    scope->scope_ = Scope::TABLE;
-  } else if (boost::iequals(str, kColumn)) {
-    scope->scope_ = Scope::COLUMN;
-  } else {
-    return Status::InvalidArgument(Substitute("unknown SentryAuthorizableScope: $0", str));
-  }
-
-  return Status::OK();
-}
-
-bool SentryAuthorizableScope::Implies(const SentryAuthorizableScope& other) const {
-  switch (scope_) {
-    case Scope::COLUMN:
-      return other.scope_ == Scope::COLUMN;
-    case Scope::TABLE:
-      return other.scope_ == Scope::TABLE ||
-             other.scope_ == Scope::COLUMN;
-    case Scope::DATABASE:
-      return other.scope_ == Scope::DATABASE ||
-             other.scope_ == Scope::TABLE ||
-             other.scope_ == Scope::COLUMN;
-    case Scope::SERVER:
-      return other.scope_ == Scope::SERVER ||
-             other.scope_ == Scope::DATABASE ||
-             other.scope_ == Scope::TABLE ||
-             other.scope_ == Scope::COLUMN;
-    default:
-      LOG(FATAL) << "unsupported SentryAuthorizableScope";
-      break;
-  }
-  return false;
-}
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_authorizable_scope.h b/src/kudu/sentry/sentry_authorizable_scope.h
deleted file mode 100644
index f7d6dc8..0000000
--- a/src/kudu/sentry/sentry_authorizable_scope.h
+++ /dev/null
@@ -1,89 +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.
-
-#pragma once
-
-#include <cstddef>
-#include <iosfwd>
-#include <string>
-
-#include "kudu/gutil/port.h"
-#include "kudu/util/bitset.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-namespace sentry {
-
-// A carbon copy of Sentry authorizable scope, which indicates the
-// hierarchy of authorizables (server → database → table → column).
-// For example, authorizable 'server=server1->db=a' has database
-// level scope, while authorizable 'server=server1' has server level
-// scope.
-//
-// A privilege scope can imply another following rules defined in
-// Implies().
-class SentryAuthorizableScope {
- public:
-
-  // Note that 'UNINITIALIZED' is not an actual scope but
-  // only to represent the uninitialized state.
-  enum Scope {
-    UNINITIALIZED,
-    SERVER,
-    DATABASE,
-    TABLE,
-    COLUMN,
-  };
-  static const size_t kScopeMaxVal = Scope::COLUMN + 1;
-
-  // The default constructor is useful when creating an authorizable scope
-  // from string.
-  SentryAuthorizableScope();
-
-  explicit SentryAuthorizableScope(Scope scope);
-
-  Scope scope() const {
-    return scope_;
-  }
-
-  // Create an authorizable scope from string.
-  static Status FromString(const std::string& str,
-                           SentryAuthorizableScope* scope) WARN_UNUSED_RESULT;
-
-  // Returns true if one authorizable scope can imply another. In general,
-  // 1.  an authorizable scope implies itself.
-  // 2.  a higher scope in the hierarchy implies a lower scope in the hierarchy.
-  bool Implies(const SentryAuthorizableScope& other) const;
-
- private:
-  Scope scope_;
-};
-
-static constexpr const char* const kServer = "SERVER";
-static constexpr const char* const kDatabase = "DATABASE";
-static constexpr const char* const kTable = "TABLE";
-static constexpr const char* const kColumn = "COLUMN";
-
-const char* ScopeToString(SentryAuthorizableScope::Scope scope);
-
-std::ostream& operator<<(std::ostream& o, SentryAuthorizableScope::Scope scope);
-
-typedef FixedBitSet<SentryAuthorizableScope::Scope, SentryAuthorizableScope::kScopeMaxVal>
-    AuthorizableScopesSet;
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_client-test.cc b/src/kudu/sentry/sentry_client-test.cc
deleted file mode 100644
index c548473..0000000
--- a/src/kudu/sentry/sentry_client-test.cc
+++ /dev/null
@@ -1,265 +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.
-
-#include "kudu/sentry/sentry_client.h"
-
-#include <functional>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "kudu/sentry/mini_sentry.h"
-#include "kudu/sentry/sentry-test-base.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
-#include "kudu/thrift/client.h"
-#include "kudu/util/net/net_util.h"
-#include "kudu/util/status.h"
-#include "kudu/util/test_macros.h"
-
-using sentry::TAlterSentryRoleAddGroupsRequest;
-using sentry::TAlterSentryRoleAddGroupsResponse;
-using sentry::TAlterSentryRoleGrantPrivilegeRequest;
-using sentry::TAlterSentryRoleGrantPrivilegeResponse;
-using sentry::TCreateSentryRoleRequest;
-using sentry::TDropSentryRoleRequest;
-using sentry::TListSentryPrivilegesRequest;
-using sentry::TListSentryPrivilegesResponse;
-using sentry::TSentryAuthorizable;
-using sentry::TSentryGroup;
-using sentry::TSentryPrivilege;
-using std::set;
-using std::string;
-using std::vector;
-
-namespace kudu {
-namespace sentry {
-
-class SentryClientTest : public SentryTestBase,
-                         public ::testing::WithParamInterface<bool> {
- public:
-  bool KerberosEnabled() const {
-    return GetParam();
-  }
-};
-
-INSTANTIATE_TEST_CASE_P(KerberosEnabled, SentryClientTest, ::testing::Bool());
-
-TEST_P(SentryClientTest, TestMiniSentryLifecycle) {
-  // Create an HA Sentry client and ensure it automatically reconnects after service interruption.
-  thrift::HaClient<SentryClient> client;
-  thrift::ClientOptions sentry_client_opts;
-  if (KerberosEnabled()) {
-    sentry_client_opts.enable_kerberos = true;
-    sentry_client_opts.service_principal = "sentry";
-  }
-
-  ASSERT_OK(client.Start(vector<HostPort>({sentry_->address()}),
-                         sentry_client_opts));
-  auto smoketest = [&]() {
-    return client.Execute([](SentryClient* client) {
-        TCreateSentryRoleRequest create_req;
-        create_req.requestorUserName = "test-admin";
-        create_req.roleName = "test-role";
-        RETURN_NOT_OK(client->CreateRole(create_req));
-
-        TDropSentryRoleRequest drop_req;
-        drop_req.requestorUserName = "test-admin";
-        drop_req.roleName = "test-role";
-        RETURN_NOT_OK(client->DropRole(drop_req));
-        return Status::OK();
-    });
-  };
-
-  ASSERT_OK(smoketest());
-
-  ASSERT_OK(sentry_->Stop());
-  ASSERT_OK(sentry_->Start());
-  ASSERT_OK(smoketest());
-
-  ASSERT_OK(sentry_->Pause());
-  ASSERT_OK(sentry_->Resume());
-  ASSERT_OK(smoketest());
-}
-
-// Basic functionality test of the Sentry client. The goal is not an exhaustive
-// test of Sentry's role handling, but instead verification that the client can
-// communicate with the Sentry service, and errors are converted to Status
-// instances.
-TEST_P(SentryClientTest, TestCreateDropRole) {
-
-  { // Create a role
-    TCreateSentryRoleRequest req;
-    req.requestorUserName = "test-admin";
-    req.roleName = "viewer";
-    ASSERT_OK(sentry_client_->CreateRole(req));
-
-    // Attempt to create the role again.
-    Status s = sentry_client_->CreateRole(req);
-    ASSERT_TRUE(s.IsAlreadyPresent()) << s.ToString();
-  }
-
-  { // Attempt to create a role as a non-admin user.
-    TCreateSentryRoleRequest req;
-    req.requestorUserName = "joe-interloper";
-    req.roleName = "fuzz";
-    Status s = sentry_client_->CreateRole(req);
-    ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  }
-
-  { // Attempt to drop the role as a non-admin user.
-    TDropSentryRoleRequest req;
-    req.requestorUserName = "joe-interloper";
-    req.roleName = "viewer";
-    Status s = sentry_client_->DropRole(req);
-    ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-  }
-
-  { // Drop the role
-    TDropSentryRoleRequest req;
-    req.requestorUserName = "test-admin";
-    req.roleName = "viewer";
-    ASSERT_OK(sentry_client_->DropRole(req));
-
-    // Attempt to drop the role again.
-    Status s = sentry_client_->DropRole(req);
-    ASSERT_TRUE(s.IsNotFound()) << s.ToString();
-  }
-}
-
-// Similar to above test to verify that the client can communicate with the
-// Sentry service to list privileges, and errors are converted to Status
-// instances.
-TEST_P(SentryClientTest, TestListPrivileges) {
-  // Attempt to access Sentry privileges without setting the user/principal name.
-  TSentryAuthorizable authorizable;
-  authorizable.server = "server";
-  authorizable.db = "db";
-  authorizable.table = "table";
-  TListSentryPrivilegesRequest request;
-  request.__set_requestorUserName("joe-interloper");
-  request.__set_authorizableHierarchy(authorizable);
-  TListSentryPrivilegesResponse response;
-  Status s = sentry_client_->ListPrivilegesByUser(request, &response);
-  ASSERT_TRUE(s.IsInvalidArgument()) << s.ToString();
-
-  // Attempt to access Sentry privileges by a non admin user.
-  request.__set_principalName("viewer");
-  s = sentry_client_->ListPrivilegesByUser(request, &response);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Attempt to access Sentry privileges by a user without
-  // group mapping.
-  request.requestorUserName = "user-without-mapping";
-  s = sentry_client_->ListPrivilegesByUser(request, &response);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Attempt to access Sentry privileges of a non-exist user.
-  request.requestorUserName = "test-admin";
-  s = sentry_client_->ListPrivilegesByUser(request, &response);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // List the privileges of user 'test-user' .
-  request.__set_principalName("test-user");
-  ASSERT_OK(sentry_client_->ListPrivilegesByUser(request, &response));
-}
-
-// Similar to above test to verify that the client can communicate with the
-// Sentry service to add roles to groups (this allows the users from the
-// groups have all privilege the role has), and errors are converted to Status
-// instances.
-TEST_P(SentryClientTest, TestAlterRoleAddGroups) {
-  // Attempt to alter role by a non admin user.
-
-  TSentryGroup group;
-  group.groupName = "user";
-  set<TSentryGroup> groups;
-  groups.insert(group);
-
-  TAlterSentryRoleAddGroupsRequest group_request;
-  TAlterSentryRoleAddGroupsResponse group_response;
-  group_request.__set_requestorUserName("joe-interloper");
-  group_request.__set_roleName("viewer");
-  group_request.__set_groups(groups);
-
-  Status s = sentry_client_->AlterRoleAddGroups(group_request, &group_response);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Attempt to alter a non-exist role.
-  group_request.__set_requestorUserName("test-admin");
-  s = sentry_client_->AlterRoleAddGroups(group_request, &group_response);
-  ASSERT_TRUE(s.IsNotFound()) << s.ToString();
-
-  // Alter role 'viewer' to add group 'user'.
-  TCreateSentryRoleRequest role_request;
-  role_request.__set_requestorUserName("test-admin");
-  role_request.__set_roleName("viewer");
-  ASSERT_OK(sentry_client_->CreateRole(role_request));
-  ASSERT_OK(sentry_client_->AlterRoleAddGroups(group_request, &group_response));
-}
-
-// Similar to above test to verify that the client can communicate with the
-// Sentry service to grant privileges, and errors are converted to Status
-// instances.
-TEST_P(SentryClientTest, TestGrantPrivilege) {
-  // Alter role 'viewer' to add group 'user'.
-
-  TSentryGroup group;
-  group.groupName = "user";
-  set<TSentryGroup> groups;
-  groups.insert(group);
-
-  TAlterSentryRoleAddGroupsRequest group_request;
-  TAlterSentryRoleAddGroupsResponse group_response;
-  group_request.__set_requestorUserName("test-admin");
-  group_request.__set_roleName("viewer");
-  group_request.__set_groups(groups);
-
-  TCreateSentryRoleRequest role_request;
-  role_request.__set_requestorUserName("test-admin");
-  role_request.__set_roleName("viewer");
-  ASSERT_OK(sentry_client_->CreateRole(role_request));
-  ASSERT_OK(sentry_client_->AlterRoleAddGroups(group_request, &group_response));
-
-  // Attempt to alter role by a non admin user.
-  TAlterSentryRoleGrantPrivilegeRequest privilege_request;
-  TAlterSentryRoleGrantPrivilegeResponse privilege_response;
-  privilege_request.__set_requestorUserName("joe-interloper");
-  privilege_request.__set_roleName("viewer");
-  TSentryPrivilege privilege;
-  privilege.__set_serverName("server");
-  privilege.__set_dbName("db");
-  privilege.__set_tableName("table");
-  privilege.__set_action("SELECT");
-  privilege_request.__set_privilege(privilege);
-  Status s = sentry_client_->AlterRoleGrantPrivilege(privilege_request, &privilege_response);
-  ASSERT_TRUE(s.IsNotAuthorized()) << s.ToString();
-
-  // Attempt to alter a non-exist role.
-  privilege_request.__set_requestorUserName("test-admin");
-  privilege_request.__set_roleName("not-exist");
-  s = sentry_client_->AlterRoleGrantPrivilege(privilege_request, &privilege_response);
-  ASSERT_TRUE(s.IsNotFound()) << s.ToString();
-
-  privilege_request.__set_roleName("viewer");
-  ASSERT_OK(sentry_client_->AlterRoleGrantPrivilege(privilege_request, &privilege_response));
-}
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_client.cc b/src/kudu/sentry/sentry_client.cc
deleted file mode 100644
index dacc3a9..0000000
--- a/src/kudu/sentry/sentry_client.cc
+++ /dev/null
@@ -1,195 +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.
-
-#include "kudu/sentry/sentry_client.h"
-
-#include <exception>
-#include <memory>
-#include <ostream>
-#include <string>
-
-#include <glog/logging.h>
-#include <thrift/Thrift.h>
-#include <thrift/protocol/TMultiplexedProtocol.h>
-#include <thrift/protocol/TProtocol.h>
-#include <thrift/transport/TTransport.h>
-#include <thrift/transport/TTransportException.h>
-
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/sentry/sentry_common_service_constants.h"
-#include "kudu/sentry/sentry_common_service_types.h"
-#include "kudu/sentry/sentry_policy_service_types.h"
-#include "kudu/thrift/client.h"
-#include "kudu/thrift/sasl_client_transport.h"
-#include "kudu/util/status.h"
-#include "kudu/util/stopwatch.h"
-
-using apache::thrift::TException;
-using apache::thrift::protocol::TMultiplexedProtocol;
-using apache::thrift::transport::TTransportException;
-using kudu::thrift::CreateClientProtocol;
-using kudu::thrift::SaslException;
-using sentry::SentryPolicyServiceClient;
-using sentry::TAlterSentryRoleAddGroupsRequest;
-using sentry::TAlterSentryRoleAddGroupsResponse;
-using sentry::TAlterSentryRoleGrantPrivilegeRequest;
-using sentry::TAlterSentryRoleGrantPrivilegeResponse;
-using sentry::TCreateSentryRoleRequest;
-using sentry::TCreateSentryRoleResponse;
-using sentry::TDropSentryRoleRequest;
-using sentry::TDropSentryRoleResponse;
-using sentry::TListSentryPrivilegesRequest;
-using sentry::TListSentryPrivilegesResponse;
-using sentry::TSentryResponseStatus;
-using sentry::g_sentry_common_service_constants;
-using std::make_shared;
-using strings::Substitute;
-
-namespace kudu {
-namespace sentry {
-
-const uint16_t SentryClient::kDefaultSentryPort = 8038;
-
-const char* const SentryClient::kServiceName = "Sentry";
-
-const int kSlowExecutionWarningThresholdMs = 1000;
-
-namespace {
-Status ConvertStatus(const TSentryResponseStatus& status) {
-  // A switch isn't possible because these values aren't generated as real constants.
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_OK) {
-    return Status::OK();
-  }
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_ALREADY_EXISTS) {
-    return Status::AlreadyPresent(status.message, status.stack);
-  }
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_NO_SUCH_OBJECT) {
-    return Status::NotFound(status.message, status.stack);
-  }
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_RUNTIME_ERROR) {
-    return Status::RuntimeError(status.message, status.stack);
-  }
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_INVALID_INPUT) {
-    return Status::InvalidArgument(status.message, status.stack);
-  }
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_ACCESS_DENIED) {
-    return Status::NotAuthorized(status.message, status.stack);
-  }
-  if (status.value == g_sentry_common_service_constants.TSENTRY_STATUS_THRIFT_VERSION_MISMATCH) {
-    return Status::NotSupported(status.message, status.stack);
-  }
-  LOG(WARNING) << "Unknown error code in Sentry status: " << status;
-  return Status::RuntimeError(
-      Substitute("unknown error code: $0: $1", status.value, status.message), status.stack);
-}
-} // namespace
-
-// Wraps calls to the Sentry Thrift service, catching any exceptions and
-// converting the response status to a Kudu Status. If there is no
-// response_status then {} can be substituted.
-#define SENTRY_RET_NOT_OK(call, response_status, msg) \
-  try { \
-    (call); \
-    RETURN_NOT_OK_PREPEND(ConvertStatus(response_status), (msg)); \
-  } catch (const SaslException& e) { \
-    return e.status().CloneAndPrepend(msg); \
-  } catch (const TTransportException& e) { \
-    switch (e.getType()) { \
-      case TTransportException::TIMED_OUT: return Status::TimedOut((msg), e.what()); \
-      case TTransportException::BAD_ARGS: return Status::InvalidArgument((msg), e.what()); \
-      case TTransportException::CORRUPTED_DATA: return Status::Corruption((msg), e.what()); \
-      default: return Status::NetworkError((msg), e.what()); \
-    } \
-  } catch (const TException& e) { \
-    return Status::IOError((msg), e.what()); \
-  } catch (const std::exception& e) { \
-    return Status::RuntimeError((msg), e.what()); \
-  }
-
-SentryClient::SentryClient(const HostPort& address, const thrift::ClientOptions& options)
-      : client_(SentryPolicyServiceClient(
-            make_shared<TMultiplexedProtocol>(CreateClientProtocol(address, options),
-                                              "SentryPolicyService"))) {
-}
-
-SentryClient::~SentryClient() {
-  WARN_NOT_OK(Stop(), "failed to shutdown Sentry client");
-}
-
-Status SentryClient::Start() {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs, "starting Sentry client");
-  SENTRY_RET_NOT_OK(client_.getOutputProtocol()->getTransport()->open(),
-                    {}, "failed to open Sentry connection");
-  return Status::OK();
-}
-
-Status SentryClient::Stop() {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs, "stopping Sentry client");
-  SENTRY_RET_NOT_OK(client_.getInputProtocol()->getTransport()->close(),
-                    {}, "failed to close Sentry connection");
-  return Status::OK();
-}
-
-bool SentryClient::IsConnected() {
-  return client_.getInputProtocol()->getTransport()->isOpen();
-}
-
-Status SentryClient::CreateRole(const TCreateSentryRoleRequest& request) {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs, "create Sentry role");
-  TCreateSentryRoleResponse response;
-  SENTRY_RET_NOT_OK(client_.create_sentry_role(response, request),
-                    response.status, "failed to create Sentry role");
-  return Status::OK();
-}
-
-Status SentryClient::DropRole(const TDropSentryRoleRequest& request) {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs, "drop Sentry role");
-  TDropSentryRoleResponse response;
-  SENTRY_RET_NOT_OK(client_.drop_sentry_role(response, request),
-                    response.status, "failed to drop Sentry role");
-  return Status::OK();
-}
-
-Status SentryClient::ListPrivilegesByUser(const TListSentryPrivilegesRequest& request,
-                                          TListSentryPrivilegesResponse* response)  {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs,
-                            "list Sentry privileges by user");
-  SENTRY_RET_NOT_OK(client_.list_sentry_privileges_by_user_and_itsgroups(*response, request),
-                    response->status, "failed to list Sentry privileges by user");
-  return Status::OK();
-}
-
-Status SentryClient::AlterRoleAddGroups(const TAlterSentryRoleAddGroupsRequest& request,
-                                        TAlterSentryRoleAddGroupsResponse* response)  {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs,
-                            "alter Sentry role add groups");
-  SENTRY_RET_NOT_OK(client_.alter_sentry_role_add_groups(*response, request),
-                    response->status, "failed to alter Sentry role add groups");
-  return Status::OK();
-}
-
-Status SentryClient::AlterRoleGrantPrivilege(const TAlterSentryRoleGrantPrivilegeRequest& request,
-                                             TAlterSentryRoleGrantPrivilegeResponse* response)  {
-  SCOPED_LOG_SLOW_EXECUTION(WARNING, kSlowExecutionWarningThresholdMs,
-                            "alter Sentry role grant privileges");
-  SENTRY_RET_NOT_OK(client_.alter_sentry_role_grant_privilege(*response, request),
-                    response->status, "failed to alter Sentry role grant privileges");
-  return Status::OK();
-}
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_client.h b/src/kudu/sentry/sentry_client.h
deleted file mode 100644
index c57f907..0000000
--- a/src/kudu/sentry/sentry_client.h
+++ /dev/null
@@ -1,117 +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.
-
-#pragma once
-
-#include <cstdint>
-
-#include "kudu/gutil/port.h"
-#include "kudu/sentry/SentryPolicyService.h"
-#include "kudu/util/status.h"
-
-namespace sentry {
-class TAlterSentryRoleAddGroupsRequest;
-class TAlterSentryRoleAddGroupsResponse;
-class TAlterSentryRoleGrantPrivilegeRequest;
-class TAlterSentryRoleGrantPrivilegeResponse;
-class TCreateSentryRoleRequest;
-class TDropSentryRoleRequest;
-class TListSentryPrivilegesRequest;
-class TListSentryPrivilegesResponse;
-}
-
-namespace kudu {
-
-class HostPort;
-
-namespace thrift {
-struct ClientOptions;
-} // namespace thrift
-
-namespace sentry {
-
-// A client for a Sentry service.
-//
-// All operations are synchronous, and may block.
-//
-// SentryClient is not thread safe.
-//
-// SentryClient wraps a single TCP connection to an HMS, and does not attempt to
-// retry on failure. If higher-level features like thread-safety, retrying, and
-// HA support are needed then use thrift::HaClient<SentryClient> to wrap the HMS
-// client.
-class SentryClient {
- public:
-
-  static const uint16_t kDefaultSentryPort;
-
-  static const char* const kServiceName;
-
-  // Create a SentryClient connection to the provided Sentry service Thrift RPC address.
-  SentryClient(const HostPort& address, const thrift::ClientOptions& options);
-  ~SentryClient();
-
-  // Starts the Sentry service client.
-  //
-  // This method will open a synchronous TCP connection to the Sentry service.
-  // If the Sentry service can not be reached within the connection timeout
-  // interval, an error is returned.
-  //
-  // Must be called before any subsequent operations using the client.
-  Status Start() WARN_UNUSED_RESULT;
-
-  // Stops the Sentry service client.
-  //
-  // This is optional; if not called the destructor will stop the client.
-  Status Stop() WARN_UNUSED_RESULT;
-
-  // Returns 'true' if the client is connected to the remote server.
-  bool IsConnected() WARN_UNUSED_RESULT;
-
-  // Creates a new role in Sentry.
-  Status CreateRole(const ::sentry::TCreateSentryRoleRequest& request) WARN_UNUSED_RESULT;
-
-  // Drops a role in Sentry.
-  Status DropRole(const ::sentry::TDropSentryRoleRequest& request) WARN_UNUSED_RESULT;
-
-  // Given an authorizable, list Sentry privileges granted to the user that match
-  // the authorizable in each privilege scope on the hierarchy (regardless of the
-  // action).
-  //
-  // For example, for authorizable 'server=server1->db=db1', it returns any privileges
-  // granted to the user that matches:
-  //   server == "server1" && (db == "db1" || db == NULL)
-  //
-  // If the user is granted both 'ALL on SERVER server1' and 'SELECT on TABLE db1.a'
-  // privileges, then both privileges are returned.
-  Status ListPrivilegesByUser(const ::sentry::TListSentryPrivilegesRequest& request,
-      ::sentry::TListSentryPrivilegesResponse* response) WARN_UNUSED_RESULT;
-
-  // Alter role to add groups in Sentry.
-  Status AlterRoleAddGroups(const ::sentry::TAlterSentryRoleAddGroupsRequest& request,
-      ::sentry::TAlterSentryRoleAddGroupsResponse* response) WARN_UNUSED_RESULT;
-
-  // Alter role to grant privileges in Sentry.
-  Status AlterRoleGrantPrivilege(const ::sentry::TAlterSentryRoleGrantPrivilegeRequest& request,
-      ::sentry::TAlterSentryRoleGrantPrivilegeResponse* response) WARN_UNUSED_RESULT;
-
- private:
-  ::sentry::SentryPolicyServiceClient client_;
-};
-
-} // namespace sentry
-} // namespace kudu
diff --git a/src/kudu/sentry/sentry_common_service.thrift b/src/kudu/sentry/sentry_common_service.thrift
deleted file mode 100644
index b24bd8a..0000000
--- a/src/kudu/sentry/sentry_common_service.thrift
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/local/bin/thrift -java
-
-/**
- * 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.
- */
-
-# DO NOT MODIFY! Copied from
-# https://raw.githubusercontent.com/apache/sentry/b71a78ed960702536b35e1f048dc40dfc79992d4/sentry-service/sentry-service-api/src/main/resources/sentry_common_service.thrift
-#
-# With edits:
-#   - Change cpp namespace to 'sentry' to match the Kudu codebase style.
-
-namespace java org.apache.sentry.service.thrift
-namespace php sentry.service.thrift
-namespace cpp sentry
-
-const i32 TSENTRY_SERVICE_V1 = 1;
-// Made a backward incompatible change when adding column level privileges.
-// We also added generalized model in this version
-const i32 TSENTRY_SERVICE_V2 = 2;
-
-const i32 TSENTRY_STATUS_OK = 0;
-const i32 TSENTRY_STATUS_ALREADY_EXISTS = 1;
-const i32 TSENTRY_STATUS_NO_SUCH_OBJECT = 2;
-const i32 TSENTRY_STATUS_RUNTIME_ERROR = 3;
-const i32 TSENTRY_STATUS_INVALID_INPUT = 4;
-const i32 TSENTRY_STATUS_ACCESS_DENIED = 5;
-const i32 TSENTRY_STATUS_THRIFT_VERSION_MISMATCH = 6;
-
-struct TSentryResponseStatus {
-1: required i32 value,
-// message will be set to empty string when status is OK
-2: required string message
-3: optional string stack
-}
diff --git a/src/kudu/sentry/sentry_policy_service.thrift b/src/kudu/sentry/sentry_policy_service.thrift
deleted file mode 100644
index 148d614..0000000
--- a/src/kudu/sentry/sentry_policy_service.thrift
+++ /dev/null
@@ -1,491 +0,0 @@
-#!/usr/local/bin/thrift -java
-
-/**
- * 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.
- */
-
-# DO NOT MODIFY! Copied from
-# https://raw.githubusercontent.com/apache/sentry/b71a78ed960702536b35e1f048dc40dfc79992d4/sentry-service/sentry-service-api/src/main/resources/sentry_policy_service.thrift
-#
-# With edits:
-#   - Change cpp namespace to 'sentry' to match the Kudu codebase style.
-#   - Rename enum TSentryGrantOption.TRUE and TSentryGrantOption.FALSE
-#     to avoid conflict with the macro definition in the macOS system header.
-
-#
-# Thrift Service that the MetaStore is built on
-#
-
-include "sentry_common_service.thrift"
-
-namespace java org.apache.sentry.api.service.thrift
-namespace php sentry.api.service.thrift
-namespace cpp sentry
-
-enum TSentryGrantOption {
-  ENABLED = 1,
-  DISABLED = 0,
-  # UNSET is used for revoke privilege, the component like 'hive'
-  # didn't support getting grant option, so use UNSET is stand
-  # for revoke both privileges with grant option and without grant
-  # option.
-  UNSET = -1
-}
-
-enum TSentryPrincipalType {
-  NONE = 0,
-  ROLE = 1,
-  USER = 2
-}
-
-# Represents a Privilege in transport from the client to the server
-struct TSentryPrivilege {
-1: required string privilegeScope, # Valid values are SERVER, DATABASE, TABLE, COLUMN, URI
-3: required string serverName,
-4: optional string dbName = "",
-5: optional string tableName = "",
-6: optional string URI = "",
-7: required string action = "",
-8: optional i64 createTime, # Set on server side
-9: optional TSentryGrantOption grantOption = TSentryGrantOption.DISABLED
-10: optional string columnName = "",
-}
-
-# TODO can this be deleted? it's not adding value to TAlterSentryRoleAddGroupsRequest
-struct TSentryGroup {
-1: required string groupName
-}
-
-struct TIsSentryAdminRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string userName,
-}
-struct TIsSentryAdminResponse {
-1: required sentry_common_service.TSentryResponseStatus status,
-2: required bool isAdmin,
-}
-
-# CREATE ROLE r1
-struct TCreateSentryRoleRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName, # TSentryRole is not required for this request
-}
-struct TCreateSentryRoleResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# DROP ROLE r1
-struct TDropSentryRoleRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName # role to drop
-}
-struct TDropSentryRoleResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# GRANT ROLE r1 TO GROUP g1
-struct TAlterSentryRoleAddGroupsRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName,
-5: required set<TSentryGroup> groups
-}
-
-struct TAlterSentryRoleAddGroupsResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# GRANT ROLE r1 TO USER u1
-struct TAlterSentryRoleAddUsersRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName,
-4: required set<string> users
-}
-
-struct TAlterSentryRoleAddUsersResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# REVOKE ROLE r1 FROM GROUP g1
-struct TAlterSentryRoleDeleteGroupsRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName,
-5: required set<TSentryGroup> groups
-}
-struct TAlterSentryRoleDeleteGroupsResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# REVOKE ROLE r1 FROM USER u1
-struct TAlterSentryRoleDeleteUsersRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName,
-4: required set<string> users
-}
-struct TAlterSentryRoleDeleteUsersResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# GRANT ... ON ... TO ROLE ...
-struct TAlterSentryRoleGrantPrivilegeRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName,
-5: optional TSentryPrivilege privilege,
-6: optional set<TSentryPrivilege> privileges
-}
-struct TAlterSentryRoleGrantPrivilegeResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: optional TSentryPrivilege privilege
-3: optional set<TSentryPrivilege> privileges
-}
-
-# REVOKE ... ON ... FROM ROLE ...
-struct TAlterSentryRoleRevokePrivilegeRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string roleName,
-5: optional TSentryPrivilege privilege,
-6: optional set<TSentryPrivilege> privileges
-}
-struct TAlterSentryRoleRevokePrivilegeResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# SHOW ROLE GRANT
-struct TListSentryRolesRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: optional string groupName # for this group, or all roles for all groups if null
-}
-
-struct TListSentryRolesForUserRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required string userName
-}
-
-# used only for TListSentryRolesResponse
-struct TSentryRole {
-1: required string roleName,
-2: required set<TSentryGroup> groups,
-3: required string grantorPrincipal #Deprecated
-}
-struct TListSentryRolesResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: optional set<TSentryRole> roles
-}
-
-struct TSentryAuthorizable {
-1: required string server,
-2: optional string uri,
-3: optional string db,
-4: optional string table,
-5: optional string column,
-}
-
-# SHOW GRANT
-struct TListSentryPrivilegesRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-
-# @Deprecated Use principalName instead to set role names or user names. This parameter will be
-# removed in the next major version of Sentry 3.0
-4: required string roleName, # get privileges assigned for this role
-5: optional TSentryAuthorizable authorizableHierarchy, # get privileges assigned for this role
-
-# Get privileges assigned for this principal name. This principalName should be set to a role name
-# or user name depending of which function you call, either list_sentry_privileges_by_role or
-# list_sentry_privileges_by_user
-6: optional string principalName
-}
-
-struct TListSentryPrivilegesResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: optional set<TSentryPrivilege> privileges
-}
-
-# Drop privilege
-struct TDropPrivilegesRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required TSentryAuthorizable authorizable
-}
-
-struct TDropPrivilegesResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-struct TRenamePrivilegesRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required TSentryAuthorizable oldAuthorizable
-4: required TSentryAuthorizable newAuthorizable
-}
-
-struct TRenamePrivilegesResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-# This API was created specifically for ProviderBackend.getPrivileges
-# and is not mean for general purpose privilege retrieval.
-# This request/response pair are created specifically so we can
-# efficiently obtain the specific privilges for a user query
-struct TSentryActiveRoleSet {
-1: required bool all,
-2: required set<string> roles,
-}
-struct TListSentryPrivilegesForProviderRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required set<string> groups,
-3: required TSentryActiveRoleSet roleSet,
-4: optional TSentryAuthorizable authorizableHierarchy,
-5: optional set<string> users
-}
-struct TListSentryPrivilegesForProviderResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: required set<string> privileges
-}
-
-# List role:set<privileges> for the given authorizable
-# Optionally use the set of groups to filter the roles
-struct TSentryPrivilegeMap {
-1: required map<string, set<TSentryPrivilege>> privilegeMap
-}
-struct TListSentryPrivilegesByAuthRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required set<TSentryAuthorizable> authorizableSet,
-4: optional set<string> groups,
-5: optional TSentryActiveRoleSet roleSet,
-6: optional set<string> users
-}
-struct TListSentryPrivilegesByAuthResponse {
-1: required sentry_common_service.TSentryResponseStatus status,
-
-# privilegesMapByAuth (legacy & compatible parameter) contains role privileges
-# (will not be set in case of an error)
-2: optional map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesMapByAuth,
-
-# privilegesMapByAuthForUsers contains user privileges
-# (will not be set in case of an error)
-3: optional map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesMapByAuthForUsers
-}
-
-struct TListSentryPrivilegesByAuthUserRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required set<TSentryAuthorizable> authorizableSet,
-4: required string user
-}
-
-struct TListSentryPrivilegesByAuthUserResponse {
-1: required sentry_common_service.TSentryResponseStatus status,
-# Authorizable to set of privileges map
-2: optional map<TSentryAuthorizable, set<TSentryPrivilege>> privilegesMapByAuth,
-}
-
-# Obtain a config value from the Sentry service
-struct TSentryConfigValueRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string propertyName, # Config attribute to obtain
-3: optional string defaultValue # Value if propertyName not found
-}
-struct TSentryConfigValueResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: optional string value
-}
-
-# struct for the mapping data like group to role, role to privilege
-struct TSentryMappingData {
-1: optional map<string, set<string>> groupRolesMap,                # for the groupName -> role mapping
-2: optional map<string, set<TSentryPrivilege>>  rolePrivilegesMap, # for the roleName -> privilege mapping
-3: optional map<string, set<string>> userRolesMap                  # for the userName -> role mapping
-}
-
-struct TSentryExportMappingDataRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: optional set<TSentryAuthorizable> authorizables # for which permission information needs to be exported.
-}
-
-struct TSentryExportMappingDataResponse {
-1: required sentry_common_service.TSentryResponseStatus status,
-2: required TSentryMappingData mappingData
-}
-
-struct TSentryImportMappingDataRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required bool overwriteRole = false, # if overwrite the exist role with the imported privileges, default is false
-4: required TSentryMappingData mappingData
-}
-
-struct TSentryImportMappingDataResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-}
-
-/*
- * API for synchronizing between HMS notification events and Sentry.
- *
- * When Sentry gets updates from HMS using HMS Notifications, HMS should
- * should wait after each notification event is generated until the notification
- * is handled by Sentry This preserves the synchronous semantics of DDL statements.
- *
- * The notification synchronization API is private between HMS and Sentry and should
- * not be used by anything else.
- *
- * The API should be used in the following way:
- *
- * 1) HMS creates a notification and stores its ID in the persistent storage
- * 2) HMS sends ID to Sentry
- * 3) Sentry blocks the response until the specified ID is processed by Sentry
- * 4) Sentry responds with the most recent processed ID.
- *
- * Note that the important part is blocking in Sentry until the specified ID
- * is processed. The returned most recent processed ID is intended for debugging
- * purposes only, but may be used in HMS for performance optimizations.
- */
-
-struct TSentrySyncIDRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required i64 id // Requested ID
-}
-
-struct TSentrySyncIDResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: required i64 id // Most recent processed ID
-}
-
-/*
- * This request is an extension to TSentrySyncIDRequest. Additionally this request
- * is used to update the HMS events and the owner changes associated with events.
- * To be backward compatible, TSentrySyncIDRequest is not updated. Instead new request
- * is created extending it.
-*/
-
-struct TSentryHmsEventNotification {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName, # user on whose behalf the request is issued
-3: required i64 id, # Requested ID
-#  Constructed from enum org.apache.hadoop.hive.metastore.messaging.EventMessage.EventType
-4: required string eventType, # Type of the event which resulted in owner update request
-5: required TSentryAuthorizable authorizable, # Authorizable object
-6: optional TSentryPrincipalType ownerType, # Type of the owner
-7: optional string ownerName # owner name
-
-}
-
-struct TSentryHmsEventNotificationResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: required i64 id // Most recent processed ID
-}
-
-/**
-* API that requests all roles and users privileges from the Sentry server.
-**/
-struct TSentryPrivilegesRequest {
-1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V2,
-2: required string requestorUserName # user on whose behalf the request is issued
-}
-
-/**
-* API that returns either all users or roles privileges found on the Sentry server.
-*
-* The response returns a mapping object that maps the role or user name to the privileges
-* they have in the server. An empty set of privileges may be returned to each role or user
-* name. Null values are not returned.
-**/
-struct TSentryPrivilegesResponse {
-1: required sentry_common_service.TSentryResponseStatus status
-2: required map<string, set<TSentryPrivilege>> privilegesMap;
-}
-
-service SentryPolicyService
-{
-  # Check if the given user is in the Sentry admin group.
-  TIsSentryAdminResponse is_sentry_admin(1:TIsSentryAdminRequest request)
-
-  TCreateSentryRoleResponse create_sentry_role(1:TCreateSentryRoleRequest request)
-  TDropSentryRoleResponse drop_sentry_role(1:TDropSentryRoleRequest request)
-
-  TAlterSentryRoleGrantPrivilegeResponse alter_sentry_role_grant_privilege(1:TAlterSentryRoleGrantPrivilegeRequest request)
-  TAlterSentryRoleRevokePrivilegeResponse alter_sentry_role_revoke_privilege(1:TAlterSentryRoleRevokePrivilegeRequest request)
-
-  TAlterSentryRoleAddGroupsResponse alter_sentry_role_add_groups(1:TAlterSentryRoleAddGroupsRequest request)
-  TAlterSentryRoleDeleteGroupsResponse alter_sentry_role_delete_groups(1:TAlterSentryRoleDeleteGroupsRequest request)
-
-  TAlterSentryRoleAddUsersResponse alter_sentry_role_add_users(1:TAlterSentryRoleAddUsersRequest request)
-  TAlterSentryRoleDeleteUsersResponse alter_sentry_role_delete_users(1:TAlterSentryRoleDeleteUsersRequest request)
-
-  TListSentryRolesResponse list_sentry_roles_by_group(1:TListSentryRolesRequest request)
-  TListSentryRolesResponse list_sentry_roles_by_user(1:TListSentryRolesForUserRequest request)
-
-  # List sentry privileges granted to the given role, filterted
-  # based on authorization hierarchy if present.
-  TListSentryPrivilegesResponse list_sentry_privileges_by_role(1:TListSentryPrivilegesRequest request)
-  # List sentry privileges granted to the given user, filterted
-  # based on authorization hierarchy if present.
-  TListSentryPrivilegesResponse list_sentry_privileges_by_user(1:TListSentryPrivilegesRequest request)
-  # List sentry privileges granted to the given user and the groups
-  # the user associated with, filterted based on authorization
-  # hierarchy if present.
-  TListSentryPrivilegesResponse list_sentry_privileges_by_user_and_itsgroups(1:TListSentryPrivilegesRequest request)
-
-  # For use with ProviderBackend.getPrivileges only
-  TListSentryPrivilegesForProviderResponse list_sentry_privileges_for_provider(1:TListSentryPrivilegesForProviderRequest request)
-
-  TDropPrivilegesResponse drop_sentry_privilege(1:TDropPrivilegesRequest request);
-
-  TRenamePrivilegesResponse rename_sentry_privilege(1:TRenamePrivilegesRequest request);
-
-  # List sentry privileges filterted based on a set of authorizables, that
-  # granted to the given user and the given role if present.
-  TListSentryPrivilegesByAuthResponse list_sentry_privileges_by_authorizable(1:TListSentryPrivilegesByAuthRequest request);
-
-  # List sentry privileges filterted based on a set of authorizables, that
-  # granted to the given user and the groups the user associated with.
-  TListSentryPrivilegesByAuthUserResponse list_sentry_privileges_by_authorizable_and_user(1:TListSentryPrivilegesByAuthUserRequest request);
-
-  TSentryConfigValueResponse get_sentry_config_value(1:TSentryConfigValueRequest request);
-
-  # export the mapping data in sentry
-  TSentryExportMappingDataResponse export_sentry_mapping_data(1:TSentryExportMappingDataRequest request);
-
-  # import the mapping data in sentry
-  TSentryImportMappingDataResponse import_sentry_mapping_data(1:TSentryImportMappingDataRequest request);
-
-  # Synchronize between HMS notifications and Sentry
-  TSentrySyncIDResponse sentry_sync_notifications(1:TSentrySyncIDRequest request);
-
-  # Notify Sentry about new events in HMS. Currently used to synchronize between HMS/Sentry
-  # and also update sentry with the owner information.
-  TSentryHmsEventNotificationResponse sentry_notify_hms_event(1:TSentryHmsEventNotification request);
-
-  # Returns a map of all roles and their privileges that exist in the Sentry server.
-  # The mapping object returned will be in the form of [roleName, set<privileges>]
-  TSentryPrivilegesResponse list_roles_privileges(1:TSentryPrivilegesRequest request);
-
-  # Returns a map of all users and their privileges that exist in the Sentry server.
-  # The mapping object returned will be in the form of [userName, set<privileges>]
-  TSentryPrivilegesResponse list_users_privileges(1:TSentryPrivilegesRequest request);
-}
diff --git a/src/kudu/sentry/thrift_operators-test.cc b/src/kudu/sentry/thrift_operators-test.cc
deleted file mode 100644
index b3c2b2c..0000000
--- a/src/kudu/sentry/thrift_operators-test.cc
+++ /dev/null
@@ -1,164 +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.
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include <glog/stl_logging.h>
-#include <gtest/gtest.h>
-
-#include "kudu/sentry/sentry_policy_service_types.h"
-#include "kudu/util/test_macros.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace sentry {
-
-template<typename T>
-void AssertCompareRequirements(const T& a, const T& b) {
-  // Values must not be less than themselves.
-  ASSERT_FALSE(a < a) << a;
-  ASSERT_FALSE(b < b) << b;
-
-  // Two values may not be simultaneously less than each other.
-  if (a < b) {
-    ASSERT_FALSE(b < a);
-  }
-}
-
-// Asserts the contains orderings are the same.
-template<typename T>
-void AssertContainersOrdered(const vector<T>& ordered_vec_t, const set<T>& set_t) {
-  ASSERT_EQ(ordered_vec_t.size(), set_t.size());
-  int i = 0;
-  for (const auto& t : set_t) {
-    ASSERT_EQ(ordered_vec_t[i++], t);
-  }
-}
-
-TEST(ThriftOperatorsTest, TestRoleOperatorLt) {
-  // TSentryRole::operator<
-  TSentryRole role_a;
-  role_a.__set_roleName("a");
-
-  TSentryRole role_b;
-  role_b.__set_roleName("b");
-
-  TSentryRole role_without_name;
-  role_without_name.__set_grantorPrincipal("grantor");
-
-  NO_FATALS(AssertCompareRequirements(role_a, role_b));
-  NO_FATALS(AssertCompareRequirements(role_a, role_without_name));
-  vector<TSentryRole> ordered_roles { role_without_name, role_a, role_b };
-  set<TSentryRole> roles(ordered_roles.begin(), ordered_roles.end());
-  NO_FATALS(AssertContainersOrdered(ordered_roles, roles));
-}
-
-TEST(ThriftOperatorsTest, TestGroupOperatorLt) {
-  // TSentryGroup::operator<
-  TSentryGroup group_a;
-  group_a.__set_groupName("a");
-
-  TSentryGroup group_b;
-  group_b.__set_groupName("b");
-
-  NO_FATALS(AssertCompareRequirements(group_a, group_b));
-  vector<TSentryGroup> ordered_groups { group_a, group_b };
-  set<TSentryGroup> groups(ordered_groups.begin(), ordered_groups.end());
-  NO_FATALS(AssertContainersOrdered(ordered_groups, groups));
-}
-
-TEST(ThriftOperatorsTest, TestPrivilegeOperatorLt) {
-  // TSentryPrivilege::operator<
-  const string kServer = "server1";
-  const string kDatabase = "db1";
-  const string kTable = "tbl1";
-
-  TSentryPrivilege db_priv;
-  db_priv.__set_serverName(kServer);
-  db_priv.__set_dbName(kDatabase);
-
-  TSentryPrivilege tbl1_priv;
-  tbl1_priv.__set_serverName(kServer);
-  tbl1_priv.__set_dbName(kDatabase);
-  tbl1_priv.__set_tableName(kTable);
-
-  TSentryPrivilege tbl1_priv_no_db;
-  tbl1_priv_no_db.__set_serverName(kServer);
-  tbl1_priv_no_db.__set_tableName(kTable);
-
-  TSentryPrivilege tbl2_priv;
-  tbl2_priv.__set_serverName(kServer);
-  tbl2_priv.__set_dbName(kDatabase);
-  tbl2_priv.__set_tableName("tbl2");
-
-  NO_FATALS(AssertCompareRequirements(db_priv, tbl1_priv));
-  NO_FATALS(AssertCompareRequirements(db_priv, tbl2_priv));
-  NO_FATALS(AssertCompareRequirements(db_priv, tbl1_priv_no_db));
-  NO_FATALS(AssertCompareRequirements(tbl1_priv, tbl2_priv));
-  vector<TSentryPrivilege> ordered_privileges { tbl1_priv_no_db, db_priv, tbl1_priv, tbl2_priv };
-  set<TSentryPrivilege> privileges(ordered_privileges.begin(), ordered_privileges.end());
-  NO_FATALS(AssertContainersOrdered(ordered_privileges, privileges));
-}
-
-TEST(ThriftOperatorsTest, TestAuthorizableOperatorLt) {
-  // TSentryAuthorizable::operator<
-  const string kServer = "server1";
-  const string kDatabase = "db1";
-  TSentryAuthorizable db_authorizable;
-  db_authorizable.__set_server(kServer);
-  db_authorizable.__set_db(kDatabase);
-
-  TSentryAuthorizable tbl1_authorizable;
-  tbl1_authorizable.__set_server(kServer);
-  tbl1_authorizable.__set_db(kDatabase);
-  tbl1_authorizable.__set_table("tbl1");
-
-  TSentryAuthorizable tbl2_authorizable;
-  tbl2_authorizable.__set_server(kServer);
-  tbl2_authorizable.__set_db(kDatabase);
-  tbl2_authorizable.__set_table("tbl2");
-
-  TSentryAuthorizable server_authorizable;
-  server_authorizable.__set_server("server2");
-
-  TSentryAuthorizable uri_authorizable;
-  uri_authorizable.__set_server(kServer);
-  uri_authorizable.__set_uri("http://uri");
-
-  NO_FATALS(AssertCompareRequirements(server_authorizable, db_authorizable));
-  NO_FATALS(AssertCompareRequirements(uri_authorizable, db_authorizable));
-  NO_FATALS(AssertCompareRequirements(db_authorizable, tbl1_authorizable));
-  NO_FATALS(AssertCompareRequirements(db_authorizable, tbl2_authorizable));
-  NO_FATALS(AssertCompareRequirements(tbl1_authorizable, tbl2_authorizable));
-  vector<TSentryAuthorizable> ordered_authorizables {
-      db_authorizable,
-      tbl1_authorizable,
-      tbl2_authorizable,
-      uri_authorizable,
-      server_authorizable,
-  };
-  set<TSentryAuthorizable> authorizables(
-      ordered_authorizables.begin(), ordered_authorizables.end());
-  ASSERT_EQ(5, authorizables.size()) << authorizables;
-  NO_FATALS(AssertContainersOrdered(ordered_authorizables, authorizables));
-}
-
-} // namespace sentry
diff --git a/src/kudu/sentry/thrift_operators.cc b/src/kudu/sentry/thrift_operators.cc
deleted file mode 100644
index 99f6750..0000000
--- a/src/kudu/sentry/thrift_operators.cc
+++ /dev/null
@@ -1,87 +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.
-
-#include <set>
-#include <string>
-
-#include "kudu/sentry/sentry_policy_service_types.h"
-
-// Thrift does not automatically generate operator< definitions for generated
-// classes, however it will happily translate a Thrift set in to a C++ set,
-// which requires the key type to implement operator<. Since Sentry uses Thrift
-// types as map keys and set items, we must provide our own definition. See
-// http://mail-archives.apache.org/mod_mbox/thrift-user/201311.mbox/%3cBAY407-EAS7268C0ADCDA8F02D874F8EB1F30@phx.gbl%3e
-// for more discussion.
-
-namespace sentry {
-
-// Returns true if lhs < rhs, false if lhs > rhs, and passes through if the two
-// are equal.
-#define RETURN_IF_DIFFERENT_LT(lhs, rhs) do { \
-  if ((lhs) != (rhs)) { \
-    return (lhs) < (rhs); \
-  } \
-} while (false)
-
-// Returns true if the optional field in 'this' is less than the optional field
-// in 'other', and false if greater than. Passes through if the two are equal.
-// Unset fields compare less than set fields.
-#define OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(field) do { \
-  if (this->__isset.field && other.__isset.field) { \
-    RETURN_IF_DIFFERENT_LT(this->field, other.field); \
-  } else if (this->__isset.field || other.__isset.field) { \
-    return other.__isset.field; \
-  } \
-} while (false)
-
-bool TSentryRole::operator<(const TSentryRole& other) const {
-  RETURN_IF_DIFFERENT_LT(this->roleName, other.roleName);
-  RETURN_IF_DIFFERENT_LT(this->groups, other.groups);
-  RETURN_IF_DIFFERENT_LT(this->grantorPrincipal, other.grantorPrincipal);
-  return false;
-}
-
-bool TSentryGroup::operator<(const TSentryGroup& other) const {
-  return this->groupName < other.groupName;
-}
-
-bool TSentryPrivilege::operator<(const TSentryPrivilege& other) const {
-  RETURN_IF_DIFFERENT_LT(this->privilegeScope, other.privilegeScope);
-  RETURN_IF_DIFFERENT_LT(this->serverName, other.serverName);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(dbName);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(tableName);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(URI);
-  RETURN_IF_DIFFERENT_LT(this->action, other.action);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(createTime);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(grantOption);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(columnName);
-  return false;
-}
-
-bool TSentryAuthorizable::operator<(const TSentryAuthorizable& other) const {
-  RETURN_IF_DIFFERENT_LT(this->server, other.server);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(uri);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(db);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(table);
-  OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT(column);
-  return false;
-}
-
-#undef OPTIONAL_FIELD_RETURN_IF_DIFFERENT_LT
-#undef RETURN_IF_DIFFERENT_LT
-
-} // namespace sentry
diff --git a/src/kudu/thrift/client.h b/src/kudu/thrift/client.h
index 6dad0aa..fa1210f 100644
--- a/src/kudu/thrift/client.h
+++ b/src/kudu/thrift/client.h
@@ -132,7 +132,7 @@
   std::vector<HostPort> addresses_;
   ClientOptions options_;
 
-  // The actual client service instance (HmsClient or SentryClient).
+  // The actual client service instance (ex: HmsClient).
   Service service_client_;
 
   // Fields which track consecutive reconnection attempts and backoff.
@@ -146,9 +146,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 // HaClient class definitions
 //
-// HaClient is defined inline so that it can be instantiated with HmsClient and
-// SentryClient as template parameters, which live in modules which are not
-// linked to the thrift module.
+// HaClient is defined inline so that it can be instantiated with HmsClient as
+// template parameters, which live in modules which are not linked to the
+// thrift module.
 ///////////////////////////////////////////////////////////////////////////////
 
 template<typename Service>
diff --git a/src/kudu/tools/kudu-admin-test.cc b/src/kudu/tools/kudu-admin-test.cc
index eae3b14..44835ad 100644
--- a/src/kudu/tools/kudu-admin-test.cc
+++ b/src/kudu/tools/kudu-admin-test.cc
@@ -52,7 +52,6 @@
 #include "kudu/gutil/basictypes.h"
 #include "kudu/gutil/map-util.h"
 #include "kudu/gutil/stl_util.h"
-#include "kudu/gutil/strings/join.h"
 #include "kudu/gutil/strings/split.h"
 #include "kudu/gutil/strings/strip.h"
 #include "kudu/gutil/strings/substitute.h"
@@ -2205,91 +2204,6 @@
   ASSERT_STR_CONTAINS(stdout, Substitute("\"parent_id\":\"$0\"", tablet_tracker_id));
 }
 
-TEST_F(AdminCliTest, TestAuthzResetCacheIncorrectMasterAddressList) {
-  NO_FATALS(BuildAndStart());
-
-  const auto& master_addr = cluster_->master()->bound_rpc_hostport().ToString();
-  const vector<string> dup_master_addresses = { master_addr, master_addr, };
-  const auto& dup_master_addresses_str = JoinStrings(dup_master_addresses, ",");
-  string out;
-  string err;
-  Status s;
-
-  s = RunKuduTool({
-    "master",
-    "authz_cache",
-    "reset",
-    dup_master_addresses_str,
-  }, &out, &err);
-  ASSERT_TRUE(s.IsRuntimeError()) << ToolRunInfo(s, out, err);
-
-  const auto ref_err_msg = Substitute(
-      "Invalid argument: list of master addresses provided ($0) "
-      "does not match the actual cluster configuration ($1)",
-      dup_master_addresses_str, master_addr);
-  ASSERT_STR_CONTAINS(err, ref_err_msg);
-
-  // However, the '--force' option makes it possible to run the tool even
-  // if the specified list of master addresses does not match the actual
-  // list of master addresses in the cluster. The default authz provider
-  // doesn't have a cache of privileges, so the 'Not implemented' result status
-  // is exactly what's expected.
-  out.clear();
-  err.clear();
-  s = RunKuduTool({
-    "master",
-    "authz_cache",
-    "reset",
-    "--force",
-    dup_master_addresses_str,
-  }, &out, &err);
-  ASSERT_TRUE(s.IsRuntimeError()) << ToolRunInfo(s, out, err);
-  ASSERT_STR_CONTAINS(err,
-      "Not implemented: provider does not have privileges cache");
-}
-
-TEST_F(AdminCliTest, TestAuthzResetCacheNotAuthorized) {
-  vector<string> master_flags{ "--superuser_acl=no-such-user" };
-  NO_FATALS(BuildAndStart({}, master_flags));
-
-  // The tool should report an error: it's not possible to reset the cache
-  // since the OS user under which the tools is invoked is not a superuser/admin
-  // (the --superuser_acl flag is set to contain a non-existent user only).
-  string out;
-  string err;
-  Status s = RunKuduTool({
-    "master",
-    "authz_cache",
-    "reset",
-    cluster_->master()->bound_rpc_hostport().ToString(),
-  }, &out, &err);
-  ASSERT_TRUE(s.IsRuntimeError()) << ToolRunInfo(s, out, err);
-  ASSERT_STR_CONTAINS(err,
-      "Remote error: Not authorized: unauthorized access to method: "
-      "ResetAuthzCache");
-}
-
-TEST_F(AdminCliTest, TestAuthzResetCacheNotImplemented) {
-  NO_FATALS(BuildAndStart());
-
-  // Even if the OS user under which account the tool is running has admin Kudu
-  // credentials, the tool should report application error: it's not possible to
-  // reset the cache since the default authz provider doesn't have one. The
-  // system uses the default authz provider because the integration with
-  // HMS+Sentry is not enabled by default.
-  string out;
-  string err;
-  Status s = RunKuduTool({
-    "master",
-    "authz_cache",
-    "reset",
-    cluster_->master()->bound_rpc_hostport().ToString(),
-  }, &out, &err);
-  ASSERT_TRUE(s.IsRuntimeError()) << ToolRunInfo(s, out, err);
-  ASSERT_STR_CONTAINS(err,
-      "Not implemented: provider does not have privileges cache");
-}
-
 TEST_F(AdminCliTest, TestExtraConfig) {
   NO_FATALS(BuildAndStart());
 
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index 09bfd31..000ab72 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -1069,7 +1069,6 @@
   }
   {
     const vector<string> kMasterModeRegexes = {
-        "authz_cache.*Operate on the authz cache of a Kudu Master",
         "dump_memtrackers.*Dump the memtrackers",
         "get_flags.*Get the gflags",
         "set_flag.*Change a gflag value",
@@ -1080,12 +1079,6 @@
     NO_FATALS(RunTestHelp("master", kMasterModeRegexes));
   }
   {
-    const vector<string> kMasterAuthzCacheModeRegexes = {
-        "reset.*Reset the privileges cache",
-    };
-    NO_FATALS(RunTestHelp("master authz_cache", kMasterAuthzCacheModeRegexes));
-  }
-  {
     const vector<string> kPbcModeRegexes = {
         "dump.*Dump a PBC",
     };
diff --git a/src/kudu/tools/tool_action_master.cc b/src/kudu/tools/tool_action_master.cc
index 4a8f105..97a0bc5 100644
--- a/src/kudu/tools/tool_action_master.cc
+++ b/src/kudu/tools/tool_action_master.cc
@@ -19,16 +19,12 @@
 #include <functional>
 #include <iostream>
 #include <iterator>
-#include <map>
 #include <memory>
-#include <set>
 #include <string>
 #include <unordered_map>
-#include <utility>
 #include <vector>
 
 #include <boost/algorithm/string/predicate.hpp>
-#include <boost/optional/optional.hpp>
 #include <gflags/gflags.h>
 #include <glog/logging.h>
 
@@ -45,11 +41,10 @@
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
 #include "kudu/master/master_runner.h"
-#include "kudu/rpc/rpc_controller.h"
+#include "kudu/rpc/response_callback.h"
 #include "kudu/tools/tool_action.h"
 #include "kudu/tools/tool_action_common.h"
 #include "kudu/util/init.h"
-#include "kudu/util/monotime.h"
 #include "kudu/util/status.h"
 
 DECLARE_bool(force);
@@ -62,13 +57,8 @@
 using kudu::master::ListMastersResponsePB;
 using kudu::master::Master;
 using kudu::master::MasterServiceProxy;
-using kudu::master::ResetAuthzCacheRequestPB;
-using kudu::master::ResetAuthzCacheResponsePB;
 using kudu::consensus::RaftPeerPB;
-using kudu::rpc::RpcController;
 using std::cout;
-using std::map;
-using std::set;
 using std::string;
 using std::unique_ptr;
 using std::vector;
@@ -199,118 +189,6 @@
   return DumpMemTrackers(address, Master::kDefaultPort);
 }
 
-// Make sure the list of master addresses specified in 'master_addresses'
-// corresponds to the actual list of masters addresses in the cluster,
-// as reported in ConnectToMasterResponsePB::master_addrs.
-Status VerifyMasterAddressList(const vector<string>& master_addresses) {
-  map<string, set<string>> addresses_per_master;
-  for (const auto& address : master_addresses) {
-    unique_ptr<MasterServiceProxy> proxy;
-    RETURN_NOT_OK(BuildProxy(address, Master::kDefaultPort, &proxy));
-
-    RpcController ctl;
-    ctl.set_timeout(MonoDelta::FromMilliseconds(FLAGS_timeout_ms));
-    ConnectToMasterRequestPB req;
-    ConnectToMasterResponsePB resp;
-    RETURN_NOT_OK(proxy->ConnectToMaster(req, &resp, &ctl));
-    const auto& resp_master_addrs = resp.master_addrs();
-    if (resp_master_addrs.size() != master_addresses.size()) {
-      const auto addresses_provided = JoinStrings(master_addresses, ",");
-      const auto addresses_cluster_config = JoinMapped(
-          resp_master_addrs,
-          [](const HostPortPB& pb) {
-            return Substitute("$0:$1", pb.host(), pb.port());
-          }, ",");
-      return Status::InvalidArgument(Substitute(
-          "list of master addresses provided ($0) "
-          "does not match the actual cluster configuration ($1) ",
-          addresses_provided, addresses_cluster_config));
-    }
-    set<string> addr_set;
-    for (const auto& hp : resp_master_addrs) {
-      addr_set.emplace(Substitute("$0:$1", hp.host(), hp.port()));
-    }
-    addresses_per_master.emplace(address, std::move(addr_set));
-  }
-
-  bool mismatch = false;
-  if (addresses_per_master.size() > 1) {
-    const auto it_0 = addresses_per_master.cbegin();
-    auto it_1 = addresses_per_master.begin();
-    ++it_1;
-    for (auto it = it_1; it != addresses_per_master.end(); ++it) {
-      if (it->second != it_0->second) {
-        mismatch = true;
-        break;
-      }
-    }
-  }
-
-  if (mismatch) {
-    string err_msg = Substitute("specified: ($0);",
-                                JoinStrings(master_addresses, ","));
-    for (const auto& e : addresses_per_master) {
-      err_msg += Substitute(" from master $0: ($1);",
-                            e.first, JoinStrings(e.second, ","));
-    }
-    return Status::ConfigurationError(
-        Substitute("master address lists mismatch: $0", err_msg));
-  }
-
-  return Status::OK();
-}
-
-Status ResetAuthzCacheAtMaster(const string& master_address) {
-  unique_ptr<MasterServiceProxy> proxy;
-  RETURN_NOT_OK(BuildProxy(master_address, Master::kDefaultPort, &proxy));
-
-  RpcController ctl;
-  ctl.set_timeout(MonoDelta::FromMilliseconds(FLAGS_timeout_ms));
-
-  ResetAuthzCacheRequestPB req;
-  ResetAuthzCacheResponsePB resp;
-  RETURN_NOT_OK(proxy->ResetAuthzCache(req, &resp, &ctl));
-  if (resp.has_error()) {
-    return StatusFromPB(resp.error().status());
-  }
-  return Status::OK();
-}
-
-Status ResetAuthzCache(const RunnerContext& context) {
-  vector<string> master_addresses;
-  RETURN_NOT_OK(ParseMasterAddresses(context, &master_addresses));
-
-  if (!FLAGS_force) {
-    // Make sure the list of master addresses specified for the command
-    // matches the actual list of masters in the cluster.
-    RETURN_NOT_OK(VerifyMasterAddressList(master_addresses));
-  }
-
-  // It makes sense to reset privileges cache at every master in the cluster.
-  // Otherwise, SentryAuthzProvider might return inconsistent results for authz
-  // requests upon master leadership change.
-  vector<Status> statuses;
-  statuses.reserve(master_addresses.size());
-  for (const auto& address : master_addresses) {
-    auto status = ResetAuthzCacheAtMaster(address);
-    statuses.emplace_back(std::move(status));
-  }
-  DCHECK_EQ(master_addresses.size(), statuses.size());
-  string err_str;
-  for (auto i = 0; i < statuses.size(); ++i) {
-    const auto& s = statuses[i];
-    if (s.ok()) {
-      continue;
-    }
-    err_str += Substitute(" error from master at $0: $1",
-                          master_addresses[i], s.ToString());
-  }
-  if (err_str.empty()) {
-    return Status::OK();
-  }
-  return Status::Incomplete(err_str);
-}
-
 } // anonymous namespace
 
 unique_ptr<Mode> BuildMasterMode() {
@@ -318,24 +196,6 @@
   builder.Description("Operate on a Kudu Master");
 
   {
-    unique_ptr<Action> action_reset =
-        ActionBuilder("reset", &ResetAuthzCache)
-        .Description("Reset the privileges cache")
-        .AddRequiredParameter({ kMasterAddressesArg, kMasterAddressesArgDesc })
-        .AddOptionalParameter(
-            "force",
-            boost::none,
-            string("Ignore mismatches of the specified and the actual lists "
-                   "of master addresses in the cluster"))
-        .Build();
-
-    unique_ptr<Mode> mode_authz_cache = ModeBuilder("authz_cache")
-        .Description("Operate on the authz cache of a Kudu Master")
-        .AddAction(std::move(action_reset))
-        .Build();
-    builder.AddMode(std::move(mode_authz_cache));
-  }
-  {
     unique_ptr<Action> dump_memtrackers =
         ActionBuilder("dump_memtrackers", &MasterDumpMemTrackers)
         .Description("Dump the memtrackers from a Kudu Master")
diff --git a/thirdparty/build-thirdparty.sh b/thirdparty/build-thirdparty.sh
index 404da46..6caf62a 100755
--- a/thirdparty/build-thirdparty.sh
+++ b/thirdparty/build-thirdparty.sh
@@ -98,7 +98,6 @@
       "bison")        F_BISON=1 ;;
       "hadoop")       F_HADOOP=1 ;;
       "hive")         F_HIVE=1 ;;
-      "sentry")       F_SENTRY=1 ;;
       "yaml")         F_YAML=1 ;;
       "chrony")       F_CHRONY=1 ;;
       "gumbo-parser") F_GUMBO_PARSER=1 ;;
@@ -264,7 +263,7 @@
   ln -nsf $POSTGRES_JDBC_SOURCE/$POSTGRES_JDBC_NAME.jar $PREFIX/opt/jdbc/postgresql.jar
 fi
 
-# Install Hadoop, Hive, and Sentry by symlinking their source directories (which
+# Install Hadoop, Hive, and Ranger by symlinking their source directories (which
 # are pre-built) into $PREFIX/opt.
 if [ -n "$F_COMMON" -o -n "$F_HADOOP" ]; then
   mkdir -p $PREFIX/opt
@@ -276,20 +275,10 @@
   ln -nsf $HIVE_SOURCE $PREFIX/opt/hive
 fi
 
-if [ -n "$F_COMMON" -o -n "$F_SENTRY" ]; then
-  mkdir -p $PREFIX/opt
-  # Remove any hadoop jars included in the Sentry package to avoid unexpected
-  # runtime behavior, due to different versions of hadoop jars are loaded
-  # (one from Kudu's third-party dependency, the other from the Sentry package).
-  rm -rf $SENTRY_SOURCE/lib/hadoop-[a-z-]*.jar
-  ln -nsf $SENTRY_SOURCE $PREFIX/opt/sentry
-fi
-
 if [ -n "$F_COMMON" -o -n "$F_RANGER" ]; then
   mkdir -p $PREFIX/opt
   # Remove any hadoop jars included in the Ranger package to avoid unexpected
-  # runtime behavior due to different versions of hadoop jars, similarly to
-  # Sentry.
+  # runtime behavior due to different versions of hadoop jars.
   rm -rf $RANGER_SOURCE/lib/hadoop-[a-z-]*.jar
   ln -nsf $RANGER_SOURCE $PREFIX/opt/ranger
 
diff --git a/thirdparty/download-thirdparty.sh b/thirdparty/download-thirdparty.sh
index 0466fea..aa666ed 100755
--- a/thirdparty/download-thirdparty.sh
+++ b/thirdparty/download-thirdparty.sh
@@ -416,12 +416,6 @@
  $HADOOP_SOURCE \
  $HADOOP_PATCHLEVEL
 
-SENTRY_PATCHLEVEL=0
-fetch_and_patch \
- $SENTRY_NAME.tar.gz \
- $SENTRY_SOURCE \
- $SENTRY_PATCHLEVEL
-
 YAML_PATCHLEVEL=0
 fetch_and_patch \
  $YAML_NAME.tar.gz \
diff --git a/thirdparty/vars.sh b/thirdparty/vars.sh
index f30380e..ac31b9b 100644
--- a/thirdparty/vars.sh
+++ b/thirdparty/vars.sh
@@ -216,15 +216,6 @@
 HADOOP_NAME=hadoop-$HADOOP_VERSION
 HADOOP_SOURCE=$TP_SOURCE_DIR/$HADOOP_NAME
 
-# TODO(dan): bump to a release version once SENTRY-2371, SENTRY-2440, SENTRY-2471
-# and SENTRY-2522 are published. The SHA below is the current head of the master branch.
-# Note: Sentry releases source code only. To build the binary tarball, use `dist`
-# maven profile. For example, `mvn clean install -Pdist`. After a successful build,
-# the tarball will be available under sentry-dist/target.
-SENTRY_VERSION=b71a78ed960702536b35e1f048dc40dfc79992d4
-SENTRY_NAME=sentry-$SENTRY_VERSION
-SENTRY_SOURCE=$TP_SOURCE_DIR/$SENTRY_NAME
-
 YAML_VERSION=0.6.2
 YAML_NAME=yaml-cpp-yaml-cpp-$YAML_VERSION
 YAML_SOURCE=$TP_SOURCE_DIR/$YAML_NAME