@Override
        public Map<byte[], List<Path>> run() {
          FileSystem fs = null;
          try {
            /*
             * This is creating and caching a new FileSystem instance. Other code called "beneath"
             * this method will rely on this FileSystem instance being in the cache. This is
             * important as those methods make _no_ attempt to close this FileSystem instance. It is
             * critical that here, in SecureBulkLoadManager, we are tracking the lifecycle and
             * closing the FS when safe to do so.
             */
            fs = FileSystem.get(conf);
            for (Pair<byte[], String> el : familyPaths) {
              Path stageFamily = new Path(bulkToken, Bytes.toString(el.getFirst()));
              if (!fs.exists(stageFamily)) {
                fs.mkdirs(stageFamily);
                fs.setPermission(stageFamily, PERM_ALL_ACCESS);
              }
            }
            if (fsCreatedListener != null) {
              fsCreatedListener.accept(region);
            }
            // We call bulkLoadHFiles as requesting user
            // To enable access prior to staging
            return region.bulkLoadHFiles(familyPaths, true,
              new SecureBulkLoadListener(fs, bulkToken, conf), request.getCopyFile(), clusterIds,
              request.getReplicate());
          } catch (Exception e) {
            LOG.error("Failed to complete bulk load", e);
          }
          return null;
        }
Bulk loads in secure mode. This service addresses two issues:
<ol>
<li>Moving files in a secure filesystem wherein the HBase Client and HBase Server are different
filesystem users.</li>
<li>Does moving in a secure manner. Assuming that the filesystem is POSIX compliant.</li>
</ol>
The algorithm is as follows:
<ol>
<li>Create an hbase owned staging directory which is world traversable (711):
{@code /hbase/staging}</li>
<li>A user writes out data to his secure output directory: {@code /user/foo/data}</li>
<li>A call is made to hbase to create a secret staging directory which globally rwx (777):
{@code /user/staging/averylongandrandomdirectoryname}</li>
<li>The user moves the data into the random staging directory, then calls bulkLoadHFiles()</li>
</ol>
Like delegation tokens the strength of the security lies in the length and randomness of the
secret directory.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SecureBulkLoadManager.java