You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2016/11/15 15:00:53 UTC

[1/2] nifi git commit: NIFI-2926: add policy action item to the user table and add user centric policy dialog with user policy listing table compolete with GoTo action.

Repository: nifi
Updated Branches:
  refs/heads/master 59fea1cb4 -> 8f928e5d6


http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users-table.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users-table.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users-table.js
index 1656050..4a1f78d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users-table.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users-table.js
@@ -470,6 +470,238 @@ nf.UsersTable = (function () {
     };
 
     /**
+     * Initializes the user policies dialog.
+     */
+    var initUserPoliciesDialog = function () {
+        $('#user-policies-dialog').modal({
+            headerText: 'User Policies',
+            buttons: [{
+                buttonText: 'Close',
+                color: {
+                    base: '#728E9B',
+                    hover: '#004849',
+                    text: '#ffffff'
+                },
+                handler: {
+                    click: function () {
+                        $('#user-policies-dialog').modal('hide');
+                    }
+                }
+            }]
+        });
+    };
+
+    /**
+     * Generates a human readable global policy strung.
+     *
+     * @param dataContext
+     * @returns {string}
+     */
+    var globalResourceParser = function (dataContext) {
+        return 'Global policy to ' +
+            nf.Common.getPolicyTypeListing(nf.Common.substringAfterFirst(dataContext.component.resource, '/')).text;
+    };
+
+    /**
+     * Generates a human readable component policy string.
+     *
+     * @param dataContext
+     * @returns {string}
+     */
+    var componentResourceParser = function (dataContext) {
+        var resource = dataContext.component.resource;
+        var policyLabel = '';
+
+        //determine policy type
+        if (resource.startsWith('/policies')) {
+            resource = nf.Common.substringAfterFirst(resource, '/policies');
+            policyLabel += 'Admin policy for ';
+        } else if (resource.startsWith('/data-transfer')) {
+            resource = nf.Common.substringAfterFirst(resource, '/data-transfer');
+            policyLabel += 'Site to site policy for ';
+        } else if (resource.startsWith('/data')) {
+            resource = nf.Common.substringAfterFirst(resource, '/data');
+            policyLabel += 'Data policy for ';
+        } else {
+            policyLabel += 'Component policy for ';
+        }
+
+        if (resource.startsWith('/processors')) {
+            policyLabel += 'processor ';
+        } else if (resource.startsWith('/controller-services')) {
+            policyLabel += 'controller service ';
+        } else if (resource.startsWith('/funnels')) {
+            policyLabel += 'funnel ';
+        } else if (resource.startsWith('/input-ports')) {
+            policyLabel += 'input port ';
+        } else if (resource.startsWith('/labels')) {
+            policyLabel += 'label ';
+        } else if (resource.startsWith('/output-ports')) {
+            policyLabel += 'output port ';
+        } else if (resource.startsWith('/process-groups')) {
+            policyLabel += 'process group ';
+        } else if (resource.startsWith('/remote-process-groups')) {
+            policyLabel += 'remote process group ';
+        } else if (resource.startsWith('/reporting-tasks')) {
+            policyLabel += 'reporting task ';
+        } else if (resource.startsWith('/templates')) {
+            policyLabel += 'template ';
+        }
+
+        if (dataContext.component.componentReference.permissions.canRead === true) {
+            policyLabel += '<span style="font-weight: 500">' + dataContext.component.componentReference.component.name + '</span>';
+        } else {
+            policyLabel += '<span class="unset">' + dataContext.component.componentReference.id + '</span>'
+        }
+
+        return policyLabel;
+    };
+
+    /**
+     * Initializes the user policies table.
+     */
+    var initUserPoliciesTable = function () {
+
+        // function for formatting the human readable name of the policy
+        var policyDisplayNameFormatter = function (row, cell, value, columnDef, dataContext) {
+            // if the user has permission to the policy
+            if (dataContext.permissions.canRead === true) {
+                // check if Global policy
+                if (nf.Common.isUndefinedOrNull(dataContext.component.componentReference)) {
+                    return globalResourceParser(dataContext);
+                }
+                // not a global policy... check if user has access to the component reference
+                return componentResourceParser(dataContext);
+            } else {
+                return '<span class="unset">' + dataContext.id + '</span>';
+            }
+        };
+
+        // function for formatting the actions column
+        var actionsFormatter = function (row, cell, value, columnDef, dataContext) {
+            var markup = '';
+
+            if (dataContext.permissions.canRead === true) {
+                if (nf.Common.isDefinedAndNotNull(dataContext.component.componentReference)) {
+                    if (dataContext.component.resource.indexOf('/processors') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-component fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/controller-services') >= 0) {
+                        //TODO: implement go to for CS
+                    } else if (dataContext.component.resource.indexOf('/funnels') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-component fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/input-ports') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-component fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/labels') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-component fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/output-ports') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-component fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/process-groups') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-process-group fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/remote-process-groups') >= 0) {
+                        markup += '<div title="Go To" class="pointer go-to-component fa fa-long-arrow-right" style="float: left;"></div>';
+                    } else if (dataContext.component.resource.indexOf('/reporting-tasks') >= 0) {
+                        //TODO: implement go to for RT
+                    } else if (dataContext.component.resource.indexOf('/templates') >= 0) {
+                        //TODO: implement go to for Templates
+                    }
+                }
+            }
+
+            return markup;
+        };
+
+        // function for formatting the action column
+        var actionFormatter = function (row, cell, value, columnDef, dataContext) {
+            var markup = '';
+
+            if (dataContext.permissions.canRead === true) {
+                markup += dataContext.component.action;
+            }
+
+            return markup;
+        };
+
+        var userPoliciesColumns = [
+            {id: 'policy', name: 'Policy', sortable: true, resizable: true, formatter: policyDisplayNameFormatter, width: 150},
+            {id: 'action', name: 'Action', sortable: true, resizable: false, formatter: actionFormatter, width: 50}
+        ];
+
+        // add the actions if we're in the shell
+        if (top !== window) {
+            userPoliciesColumns.push({id: 'actions', name: '&nbsp;', sortable: false, resizable: false, formatter: actionsFormatter, width: 25});
+        }
+
+        var userPoliciesOptions = {
+            forceFitColumns: true,
+            enableTextSelectionOnCells: true,
+            enableCellNavigation: true,
+            enableColumnReorder: false,
+            autoEdit: false
+        };
+
+        // initialize the dataview
+        var userPoliciesData = new Slick.Data.DataView({
+            inlineFilters: false
+        });
+        userPoliciesData.setItems([]);
+
+        // initialize the sort
+        userPolicySort({
+            columnId: 'policy',
+            sortAsc: true
+        }, userPoliciesData);
+
+        // initialize the grid
+        var userPoliciesGrid = new Slick.Grid('#user-policies-table', userPoliciesData, userPoliciesColumns, userPoliciesOptions);
+        userPoliciesGrid.setSelectionModel(new Slick.RowSelectionModel());
+        userPoliciesGrid.registerPlugin(new Slick.AutoTooltips());
+        userPoliciesGrid.setSortColumn('policy', true);
+        userPoliciesGrid.onSort.subscribe(function (e, args) {
+            userPolicySort({
+                columnId: args.sortCol.id,
+                sortAsc: args.sortAsc
+            }, userPoliciesData);
+        });
+
+        // configure a click listener
+        userPoliciesGrid.onClick.subscribe(function (e, args) {
+            var target = $(e.target);
+
+            // get the node at this row
+            var item = userPoliciesData.getItem(args.row);
+
+            // determine the desired action
+            if (userPoliciesGrid.getColumns()[args.cell].id === 'actions') {
+                if (target.hasClass('go-to-component')) {
+                    parent.$('body').trigger('GoTo:Component', {
+                        id: item.component.componentReference.id,
+                        parentGroupId: item.component.componentReference.parentGroupId
+                    });
+                    parent.$('#shell-close-button').click();
+                } else if (target.hasClass('go-to-process-group')) {
+                    parent.$('body').trigger('GoTo:ProcessGroup', {
+                        id: item.component.componentReference.id
+                    });
+                    parent.$('#shell-close-button').click();
+                }
+            }
+        });
+
+        // wire up the dataview to the grid
+        userPoliciesData.onRowCountChanged.subscribe(function (e, args) {
+            userPoliciesGrid.updateRowCount();
+            userPoliciesGrid.render();
+        });
+        userPoliciesData.onRowsChanged.subscribe(function (e, args) {
+            userPoliciesGrid.invalidateRows(args.rows);
+            userPoliciesGrid.render();
+        });
+
+        // hold onto an instance of the grid
+        $('#user-policies-table').data('gridInstance', userPoliciesGrid);
+    };
+
+    /**
      * Initializes the processor list.
      */
     var initUsersTable = function () {
@@ -524,6 +756,10 @@ nf.UsersTable = (function () {
                 markup += '<div title="Remove" class="pointer delete-user fa fa-trash"></div>';
             }
 
+            if (!nf.Common.isEmpty(dataContext.component.accessPolicies)) {
+                markup += '<div title="View User Policies" class="pointer view-user-policies fa fa-key" style="margin-left: 3px;"></div>';
+            }
+
             return markup;
         };
 
@@ -553,7 +789,7 @@ nf.UsersTable = (function () {
         usersData.setFilter(filter);
 
         // initialize the sort
-        sort({
+        userSort({
             columnId: 'identity',
             sortAsc: true
         }, usersData);
@@ -564,7 +800,7 @@ nf.UsersTable = (function () {
         usersGrid.registerPlugin(new Slick.AutoTooltips());
         usersGrid.setSortColumn('identity', true);
         usersGrid.onSort.subscribe(function (e, args) {
-            sort({
+            userSort({
                 columnId: args.sortCol.id,
                 sortAsc: args.sortAsc
             }, usersData);
@@ -581,6 +817,8 @@ nf.UsersTable = (function () {
             if (usersGrid.getColumns()[args.cell].id === 'actions') {
                 if (target.hasClass('edit-user')) {
                     editUser(item);
+                } else if (target.hasClass('view-user-policies')) {
+                    viewUserPolicies(item);
                 } else if (target.hasClass('delete-user')) {
                     deleteUser(item);
                 }
@@ -613,7 +851,7 @@ nf.UsersTable = (function () {
      * @param {object} sortDetails
      * @param {object} data
      */
-    var sort = function (sortDetails, data) {
+    var userSort = function (sortDetails, data) {
         // defines a function for sorting
         var comparer = function (a, b) {
             if(a.permissions.canRead && b.permissions.canRead) {
@@ -637,6 +875,68 @@ nf.UsersTable = (function () {
     };
 
     /**
+     * Sorts the specified data using the specified sort details.
+     *
+     * @param {object} sortDetails
+     * @param {object} data
+     */
+    var userPolicySort = function (sortDetails, data) {
+        // defines a function for sorting
+        var comparer = function (a, b) {
+            if(a.permissions.canRead && b.permissions.canRead) {
+                if (sortDetails.columnId === 'action') {
+                    var aString = nf.Common.isDefinedAndNotNull(a.component[sortDetails.columnId]) ? a.component[sortDetails.columnId] : '';
+                    var bString = nf.Common.isDefinedAndNotNull(b.component[sortDetails.columnId]) ? b.component[sortDetails.columnId] : '';
+                    return aString === bString ? 0 : aString > bString ? 1 : -1;
+                } else if (sortDetails.columnId === 'policy') {
+                    var aString = '';
+                    var bString = '';
+
+                    // if the user has permission to the policy
+                    if (a.permissions.canRead === true) {
+                        // check if Global policy
+                        if (nf.Common.isUndefinedOrNull(a.component.componentReference)) {
+                            aString = globalResourceParser(a);
+                        } else {
+                            // not a global policy... check if user has access to the component reference
+                            aString = componentResourceParser(a);
+                        }
+                    } else {
+                        aString = a.id;
+                    }
+
+                    // if the user has permission to the policy
+                    if (b.permissions.canRead === true) {
+                        // check if Global policy
+                        if (nf.Common.isUndefinedOrNull(b.component.componentReference)) {
+                            bString = globalResourceParser(b);
+                        }else {
+                            // not a global policy... check if user has access to the component reference
+                            bString = componentResourceParser(b);
+                        }
+                    } else {
+                        bString = b.id;
+                    }
+
+                    return aString === bString ? 0 : aString > bString ? 1 : -1;
+                }
+            } else {
+                if (!a.permissions.canRead && !b.permissions.canRead){
+                    return 0;
+                }
+                if(a.permissions.canRead){
+                    return 1;
+                } else {
+                    return -1;
+                }
+            }
+        };
+
+        // perform the sort
+        data.sort(comparer, sortDetails.sortAsc);
+    };
+
+    /**
      * Get the text out of the filter field. If the filter field doesn't
      * have any text it will contain the text 'filter list' so this method
      * accounts for that.
@@ -814,9 +1114,43 @@ nf.UsersTable = (function () {
         $('#user-delete-dialog').modal('show');
     };
 
+    /**
+     * Open's a view of the specified user's policies.
+     *
+     * @argument {object} user        The user item
+     */
+    var viewUserPolicies = function (user) {
+        var userPoliciesGrid = $('#user-policies-table').data('gridInstance');
+        var userPoliciesData = userPoliciesGrid.getData();
+
+        // begin the update
+        userPoliciesData.beginUpdate();
+
+        // set the rows
+        if (nf.Common.isDefinedAndNotNull(user.component.accessPolicies)) {
+            userPoliciesData.setItems(user.component.accessPolicies);
+        }
+
+        $('#policies-dialog-user-name').text(user.component.identity);
+
+        // end the update
+        userPoliciesData.endUpdate();
+
+        // re-sort and clear selection after updating
+        userPoliciesData.reSort();
+        userPoliciesGrid.invalidate();
+        userPoliciesGrid.getSelectionModel().setSelectedRows([]);
+
+        // show the dialog
+        $('#user-policies-dialog').modal('show');
+        userPoliciesGrid.resizeCanvas();
+    };
+
     return {
         init: function () {
             initUserDialog();
+            initUserPoliciesDialog();
+            initUserPoliciesTable();
             initUserDeleteDialog();
             initUsersTable();
 
@@ -852,7 +1186,7 @@ nf.UsersTable = (function () {
         },
 
         /**
-         * Load the processor status table.
+         * Load the users table.
          */
         loadUsersTable: function () {
             var users = $.ajax({

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
index 8e7c005..34476a2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
@@ -145,6 +145,28 @@ nf.Users = (function () {
                             $('#users-header-text').text(countersTitle);
                         }).fail(nf.Common.handleAjaxError);
                     });
+
+                    $(window).on('resize', function (e) {
+                        // resize dialogs when appropriate
+                        var dialogs = $('.dialog');
+                        for (var i = 0, len = dialogs.length; i < len; i++) {
+                            if ($(dialogs[i]).is(':visible')){
+                                setTimeout(function(dialog){
+                                    dialog.modal('resize');
+                                }, 50, $(dialogs[i]));
+                            }
+                        }
+
+                        // resize grids when appropriate
+                        var gridElements = $('*[class*="slickgrid_"]');
+                        for (var j = 0, len = gridElements.length; j < len; j++) {
+                            if ($(gridElements[j]).is(':visible')){
+                                setTimeout(function(gridElement){
+                                    gridElement.data('gridInstance').resizeCanvas();
+                                }, 50, $(gridElements[j]));
+                            }
+                        }
+                    });
                 });
             });
         }


[2/2] nifi git commit: NIFI-2926: add policy action item to the user table and add user centric policy dialog with user policy listing table compolete with GoTo action.

Posted by ma...@apache.org.
NIFI-2926: add policy action item to the user table and add user centric policy dialog with user policy listing table compolete with GoTo action.

This closes #1188.


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/8f928e5d
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/8f928e5d
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/8f928e5d

Branch: refs/heads/master
Commit: 8f928e5d6e9701646947ad43ef0a42b461661cc8
Parents: 59fea1c
Author: Scott Aslan <sc...@gmail.com>
Authored: Fri Nov 11 15:04:20 2016 -0500
Committer: Mark Payne <ma...@hotmail.com>
Committed: Tue Nov 15 09:58:58 2016 -0500

----------------------------------------------------------------------
 .../authorization/resource/Authorizable.java    |   2 +-
 .../resource/ComponentAuthorizable.java         |  39 +++
 .../web/api/dto/AccessPolicySummaryDTO.java     |  13 +
 .../nifi/web/api/dto/ComponentReferenceDTO.java |  76 +++++
 .../apache/nifi/web/api/dto/UserGroupDTO.java   |   4 +-
 .../api/entity/ComponentReferenceEntity.java    |  61 ++++
 .../apache/nifi/connectable/Connectable.java    |  14 +-
 .../controller/AbstractConfiguredComponent.java |   2 -
 .../apache/nifi/controller/AbstractPort.java    |  38 ++-
 .../nifi/controller/ConfiguredComponent.java    |  10 +-
 .../apache/nifi/controller/StandardFunnel.java  |   6 +
 .../org/apache/nifi/controller/Template.java    |  10 +-
 .../org/apache/nifi/controller/label/Label.java |   4 +-
 .../org/apache/nifi/groups/ProcessGroup.java    |   4 +-
 .../apache/nifi/groups/RemoteProcessGroup.java  |   4 +-
 .../nifi/controller/StandardProcessorNode.java  |   2 +-
 .../nifi/controller/label/StandardLabel.java    |   6 +
 .../reporting/AbstractReportingTaskNode.java    |  14 +-
 .../service/StandardControllerServiceNode.java  |   2 +-
 .../nifi/groups/StandardProcessGroup.java       |  10 +
 .../nifi/remote/StandardRemoteProcessGroup.java |   6 +
 .../service/mock/MockProcessGroup.java          |   5 +
 .../nifi/web/StandardNiFiServiceFacade.java     |  76 +++--
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  43 ++-
 .../apache/nifi/web/api/dto/EntityFactory.java  |  16 +
 .../org/apache/nifi/web/dao/UserGroupDAO.java   |   8 +
 .../impl/StandardPolicyBasedAuthorizerDAO.java  |  10 +
 .../src/main/webapp/WEB-INF/pages/users.jsp     |   2 +
 .../partials/users/user-policies-dialog.jsp     |  29 ++
 .../nifi-web-ui/src/main/webapp/css/users.css   |  32 ++
 .../slickgrid/css/slick-default-theme.css       |  17 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  15 +
 .../webapp/js/nf/canvas/nf-policy-management.js |  47 +--
 .../src/main/webapp/js/nf/nf-common.js          |  55 ++-
 .../main/webapp/js/nf/users/nf-users-table.js   | 342 ++++++++++++++++++-
 .../src/main/webapp/js/nf/users/nf-users.js     |  22 ++
 36 files changed, 923 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
index cc0d8fc..39e9642 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
@@ -41,7 +41,7 @@ public interface Authorizable {
     /**
      * The Resource for this Authorizable.
      *
-     * @return the parent resource
+     * @return the resource
      */
     Resource getResource();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/ComponentAuthorizable.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/ComponentAuthorizable.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/ComponentAuthorizable.java
new file mode 100644
index 0000000..7fd3d5a
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/ComponentAuthorizable.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization.resource;
+
+/**
+ * Not all Authorizables are components, however all ComponentAuthorizable's are components. This ensures that they
+ * will have an identifier and a ProcessGroup identifier.
+ */
+public interface ComponentAuthorizable extends Authorizable {
+
+    /**
+     * The identifier of the underlying component.
+     *
+     * @return the identifier
+     */
+    String getIdentifier();
+
+    /**
+     * The identifier of the ProcessGroup this component belongs to.
+     *
+     * @return the ProcessGroup identifier
+     */
+    String getProcessGroupIdentifier();
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessPolicySummaryDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessPolicySummaryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessPolicySummaryDTO.java
index 0fb97c1..e5a6903 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessPolicySummaryDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessPolicySummaryDTO.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.web.api.dto;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.entity.ComponentReferenceEntity;
 
 import javax.xml.bind.annotation.XmlType;
 
@@ -28,6 +29,7 @@ public class AccessPolicySummaryDTO extends ComponentDTO {
 
     private String resource;
     private String action;
+    private ComponentReferenceEntity componentReference;
 
     /**
      * @return The action associated with this access policy.
@@ -56,4 +58,15 @@ public class AccessPolicySummaryDTO extends ComponentDTO {
         this.resource = resource;
     }
 
+    /**
+     * @return Component this policy references if applicable.
+     */
+    @ApiModelProperty(value="Component this policy references if applicable.")
+    public ComponentReferenceEntity getComponentReference() {
+        return componentReference;
+    }
+
+    public void setComponentReference(ComponentReferenceEntity componentReference) {
+        this.componentReference = componentReference;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ComponentReferenceDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ComponentReferenceDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ComponentReferenceDTO.java
new file mode 100644
index 0000000..48aacaa
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ComponentReferenceDTO.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details for the access configuration.
+ */
+@XmlType(name = "accessPolicy")
+public class ComponentReferenceDTO extends ComponentDTO {
+
+    private String id;
+    private String parentGroupId;
+    private String name;
+
+    /**
+     * The id for this component.
+     *
+     * @return The id
+     */
+    @ApiModelProperty(
+            value = "The id of the component."
+    )
+    public String getId() {
+        return this.id;
+    }
+
+    public void setId(final String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return id for the parent group of this component if applicable, null otherwise
+     */
+    @ApiModelProperty(
+            value = "The id of parent process group of this component if applicable."
+    )
+    public String getParentGroupId() {
+        return parentGroupId;
+    }
+
+    public void setParentGroupId(String parentGroupId) {
+        this.parentGroupId = parentGroupId;
+    }
+
+    /**
+     * @return id for the parent group of this component if applicable, null otherwise
+     */
+    @ApiModelProperty(
+            value = "The name of the component."
+    )
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/UserGroupDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/UserGroupDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/UserGroupDTO.java
index af63a14..17de4de 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/UserGroupDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/UserGroupDTO.java
@@ -48,7 +48,9 @@ public class UserGroupDTO extends TenantDTO {
      * @return policies this user group is part of
      */
     @ApiModelProperty(
-            value = "The access policies this user group belongs to.",
+            value = "The access policies this user group belongs to. This field was incorrectly defined as an AccessPolicyEntity. For "
+                    + "compatibility reasons the field will remain of this type, however only the fields that are present in the "
+                    + "AccessPolicySummaryEntity will be populated here.",
             readOnly = true
     )
     public Set<AccessPolicyEntity> getAccessPolicies() {

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentReferenceEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentReferenceEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentReferenceEntity.java
new file mode 100644
index 0000000..bc03ad8
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentReferenceEntity.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.ComponentReferenceDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A serialized representation of this class can be placed in the entity body of a request or response to or from the API.
+ * This particular entity holds a reference to an {@link ComponentReferenceDTO}.
+ */
+@XmlRootElement(name = "componentReferenceEntity")
+public class ComponentReferenceEntity extends ComponentEntity {
+
+    private String parentGroupId;
+    private ComponentReferenceDTO component;
+
+    /**
+     * @return id for the parent group of this component if applicable, null otherwise
+     */
+    @ApiModelProperty(
+            value = "The id of parent process group of this component if applicable."
+    )
+    public String getParentGroupId() {
+        return parentGroupId;
+    }
+
+    public void setParentGroupId(String parentGroupId) {
+        this.parentGroupId = parentGroupId;
+    }
+
+    /**
+     * The {@link ComponentReferenceDTO} that is being serialized.
+     *
+     * @return The {@link ComponentReferenceDTO} object
+     */
+    public ComponentReferenceDTO getComponent() {
+        return component;
+    }
+
+    public void setComponent(ComponentReferenceDTO component) {
+        this.component = component;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/connectable/Connectable.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/connectable/Connectable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/connectable/Connectable.java
index 99e06ed..94e0745 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/connectable/Connectable.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/connectable/Connectable.java
@@ -16,12 +16,7 @@
  */
 package org.apache.nifi.connectable;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.components.ValidationResult;
 import org.apache.nifi.controller.Triggerable;
 import org.apache.nifi.groups.ProcessGroup;
@@ -29,10 +24,15 @@ import org.apache.nifi.processor.ProcessSession;
 import org.apache.nifi.processor.Relationship;
 import org.apache.nifi.scheduling.SchedulingStrategy;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Represents a connectable component to which or from which data can flow.
  */
-public interface Connectable extends Triggerable, Authorizable, Positionable {
+public interface Connectable extends Triggerable, ComponentAuthorizable, Positionable {
 
     /**
      * @return the unique identifier for this <code>Connectable</code>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractConfiguredComponent.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractConfiguredComponent.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractConfiguredComponent.java
index cc9404e..671f4fb 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractConfiguredComponent.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractConfiguredComponent.java
@@ -371,8 +371,6 @@ public abstract class AbstractConfiguredComponent implements ConfigurableCompone
 
     public abstract void verifyModifiable() throws IllegalStateException;
 
-    protected abstract String getProcessGroupIdentifier();
-
     /**
      *
      */

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractPort.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractPort.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractPort.java
index 581d209..ff42f47 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractPort.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractPort.java
@@ -16,22 +16,6 @@
  */
 package org.apache.nifi.controller;
 
-import static java.util.Objects.requireNonNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.nifi.authorization.Resource;
@@ -52,6 +36,22 @@ import org.apache.nifi.processor.Relationship;
 import org.apache.nifi.processor.exception.ProcessException;
 import org.apache.nifi.util.FormatUtils;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import static java.util.Objects.requireNonNull;
+
 public abstract class AbstractPort implements Port {
 
     public static final Relationship PORT_RELATIONSHIP = new Relationship.Builder()
@@ -121,6 +121,12 @@ public abstract class AbstractPort implements Port {
     }
 
     @Override
+    public String getProcessGroupIdentifier() {
+        final ProcessGroup procGroup = getProcessGroup();
+        return procGroup == null ? null : procGroup.getIdentifier();
+    }
+
+    @Override
     public String getName() {
         return name.get();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
index 91119ec..7ec3a14 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
@@ -16,14 +16,14 @@
  */
 package org.apache.nifi.controller;
 
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.ValidationResult;
 
-public interface ConfiguredComponent extends Authorizable {
+import java.util.Collection;
+import java.util.Map;
+
+public interface ConfiguredComponent extends ComponentAuthorizable {
 
     public String getIdentifier();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/StandardFunnel.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/StandardFunnel.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/StandardFunnel.java
index c4cdf34..18bcc3c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/StandardFunnel.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/StandardFunnel.java
@@ -110,6 +110,12 @@ public class StandardFunnel implements Funnel {
     }
 
     @Override
+    public String getProcessGroupIdentifier() {
+        final ProcessGroup procGroup = getProcessGroup();
+        return procGroup == null ? null : procGroup.getIdentifier();
+    }
+
+    @Override
     public Collection<Relationship> getRelationships() {
         return relationships;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Template.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Template.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Template.java
index 7274458..f0771be 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Template.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Template.java
@@ -18,12 +18,13 @@ package org.apache.nifi.controller;
 
 import org.apache.nifi.authorization.Resource;
 import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.resource.ResourceType;
 import org.apache.nifi.groups.ProcessGroup;
 import org.apache.nifi.web.api.dto.TemplateDTO;
 
-public class Template implements Authorizable {
+public class Template implements ComponentAuthorizable {
 
     private final TemplateDTO dto;
     private volatile ProcessGroup processGroup;
@@ -32,10 +33,17 @@ public class Template implements Authorizable {
         this.dto = dto;
     }
 
+    @Override
     public String getIdentifier() {
         return dto.getId();
     }
 
+    @Override
+    public String getProcessGroupIdentifier() {
+        final ProcessGroup procGroup = getProcessGroup();
+        return procGroup == null ? null : procGroup.getIdentifier();
+    }
+
     /**
      * Returns a TemplateDTO object that describes the contents of this Template
      *

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/label/Label.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/label/Label.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/label/Label.java
index 352f73f..bc1be00 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/label/Label.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/label/Label.java
@@ -16,14 +16,14 @@
  */
 package org.apache.nifi.controller.label;
 
-import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.connectable.Positionable;
 import org.apache.nifi.connectable.Size;
 import org.apache.nifi.groups.ProcessGroup;
 
 import java.util.Map;
 
-public interface Label extends Authorizable, Positionable {
+public interface Label extends ComponentAuthorizable, Positionable {
 
     String getIdentifier();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
index fd4673d..be0bcd3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
@@ -16,7 +16,7 @@
  */
 package org.apache.nifi.groups;
 
-import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.connectable.Connectable;
 import org.apache.nifi.connectable.Connection;
 import org.apache.nifi.connectable.Funnel;
@@ -45,7 +45,7 @@ import java.util.function.Predicate;
  * <p>
  * MUST BE THREAD-SAFE</p>
  */
-public interface ProcessGroup extends Authorizable, Positionable {
+public interface ProcessGroup extends ComponentAuthorizable, Positionable {
 
     /**
      * Predicate for filtering schedulable Processors.

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/RemoteProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/RemoteProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/RemoteProcessGroup.java
index ff96fba..133f274 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/RemoteProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/RemoteProcessGroup.java
@@ -16,7 +16,7 @@
  */
 package org.apache.nifi.groups;
 
-import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.connectable.Positionable;
 import org.apache.nifi.controller.exception.CommunicationsException;
 import org.apache.nifi.events.EventReporter;
@@ -28,7 +28,7 @@ import java.util.Date;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-public interface RemoteProcessGroup extends Authorizable, Positionable {
+public interface RemoteProcessGroup extends ComponentAuthorizable, Positionable {
 
     String getIdentifier();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardProcessorNode.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardProcessorNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardProcessorNode.java
index aede825..bfa2129 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardProcessorNode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardProcessorNode.java
@@ -1443,7 +1443,7 @@ public class StandardProcessorNode extends ProcessorNode implements Connectable
     }
 
     @Override
-    protected String getProcessGroupIdentifier() {
+    public String getProcessGroupIdentifier() {
         final ProcessGroup group = getProcessGroup();
         return group == null ? null : group.getIdentifier();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/label/StandardLabel.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/label/StandardLabel.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/label/StandardLabel.java
index a95cb45..7044796 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/label/StandardLabel.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/label/StandardLabel.java
@@ -80,6 +80,12 @@ public class StandardLabel implements Label {
     }
 
     @Override
+    public String getProcessGroupIdentifier() {
+        final ProcessGroup procGroup = getProcessGroup();
+        return procGroup == null ? null : procGroup.getIdentifier();
+    }
+
+    @Override
     public Authorizable getParentAuthorizable() {
         return getProcessGroup();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/reporting/AbstractReportingTaskNode.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/reporting/AbstractReportingTaskNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/reporting/AbstractReportingTaskNode.java
index dc8056d..ac5525c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/reporting/AbstractReportingTaskNode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/reporting/AbstractReportingTaskNode.java
@@ -16,12 +16,6 @@
  */
 package org.apache.nifi.controller.reporting;
 
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
 import org.apache.nifi.components.ValidationResult;
 import org.apache.nifi.controller.AbstractConfiguredComponent;
 import org.apache.nifi.controller.ConfigurationContext;
@@ -39,6 +33,12 @@ import org.apache.nifi.reporting.ReportingTask;
 import org.apache.nifi.scheduling.SchedulingStrategy;
 import org.apache.nifi.util.FormatUtils;
 
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
 public abstract class AbstractReportingTaskNode extends AbstractConfiguredComponent implements ReportingTaskNode {
 
     private final ReportingTask reportingTask;
@@ -238,7 +238,7 @@ public abstract class AbstractReportingTaskNode extends AbstractConfiguredCompon
     }
 
     @Override
-    protected String getProcessGroupIdentifier() {
+    public String getProcessGroupIdentifier() {
         return null;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
index e5a3b83..c61325a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
@@ -428,7 +428,7 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
     }
 
     @Override
-    protected String getProcessGroupIdentifier() {
+    public String getProcessGroupIdentifier() {
         final ProcessGroup procGroup = getProcessGroup();
         return procGroup == null ? null : procGroup.getIdentifier();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
index fcfe838..312103e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
@@ -162,6 +162,16 @@ public final class StandardProcessGroup implements ProcessGroup {
     }
 
     @Override
+    public String getProcessGroupIdentifier() {
+        final ProcessGroup parentProcessGroup = getParent();
+        if (parentProcessGroup == null) {
+            return null;
+        } else {
+            return parentProcessGroup.getIdentifier();
+        }
+    }
+
+    @Override
     public String getName() {
         return name.get();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/remote/StandardRemoteProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/remote/StandardRemoteProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/remote/StandardRemoteProcessGroup.java
index 78968e2..091f00e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/remote/StandardRemoteProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/remote/StandardRemoteProcessGroup.java
@@ -206,6 +206,12 @@ public class StandardRemoteProcessGroup implements RemoteProcessGroup {
     }
 
     @Override
+    public String getProcessGroupIdentifier() {
+        final ProcessGroup procGroup = getProcessGroup();
+        return procGroup == null ? null : procGroup.getIdentifier();
+    }
+
+    @Override
     public Authorizable getParentAuthorizable() {
         return getProcessGroup();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
index 27c629c..47faca5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
@@ -61,6 +61,11 @@ public class MockProcessGroup implements ProcessGroup {
     }
 
     @Override
+    public String getProcessGroupIdentifier() {
+        return null;
+    }
+
+    @Override
     public void setParent(final ProcessGroup group) {
 
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 18c029b..53c0fe6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -37,6 +37,7 @@ import org.apache.nifi.authorization.Resource;
 import org.apache.nifi.authorization.User;
 import org.apache.nifi.authorization.UserContextKeys;
 import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.EnforcePolicyPermissionsThroughBaseResource;
 import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
@@ -95,6 +96,7 @@ import org.apache.nifi.web.api.dto.BulletinQueryDTO;
 import org.apache.nifi.web.api.dto.ClusterDTO;
 import org.apache.nifi.web.api.dto.ComponentDTO;
 import org.apache.nifi.web.api.dto.ComponentHistoryDTO;
+import org.apache.nifi.web.api.dto.ComponentReferenceDTO;
 import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.ConnectionDTO;
 import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
@@ -154,6 +156,7 @@ import org.apache.nifi.web.api.entity.AccessPolicyEntity;
 import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
 import org.apache.nifi.web.api.entity.ActionEntity;
 import org.apache.nifi.web.api.entity.BulletinEntity;
+import org.apache.nifi.web.api.entity.ComponentReferenceEntity;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
 import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
 import org.apache.nifi.web.api.entity.ControllerBulletinsEntity;
@@ -485,7 +488,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 accessPolicy -> {
                     final Set<TenantEntity> users = accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
                     final Set<TenantEntity> userGroups = accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
-                    return dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users);
+                    final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource());
+                    return dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users, componentReference);
                 });
 
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizable);
@@ -513,10 +517,16 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     @Override
     public UserGroupEntity updateUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
         final Authorizable userGroupsAuthorizable = authorizableLookup.getTenant();
+        final Set<AccessPolicy> policies = userGroupDAO.getAccessPoliciesForUserGroup(userGroupDTO.getId());
         final RevisionUpdate<UserGroupDTO> snapshot = updateComponent(revision,
                 userGroupsAuthorizable,
                 () -> userGroupDAO.updateUserGroup(userGroupDTO),
-                userGroup -> dtoFactory.createUserGroupDto(userGroup, userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet())));
+                userGroup -> {
+                    final Set<TenantEntity> tenantEntities = userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+                    final Set<AccessPolicySummaryEntity> policyEntities = policies.stream().map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
+                    return dtoFactory.createUserGroupDto(userGroup, tenantEntities, policyEntities);
+                }
+        );
 
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(userGroupsAuthorizable);
         return entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
@@ -966,8 +976,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
         final Set<TenantEntity> users = userGroup != null ? userGroup.getUsers().stream()
-                .map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) :
-                null;
+                .map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
+        final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream()
+                .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
 
         final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userGroupId;
         final UserGroupDTO snapshot = deleteComponent(
@@ -985,7 +996,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 },
                 () -> userGroupDAO.deleteUserGroup(userGroupId),
                 false, // no user group specific policies to remove
-                dtoFactory.createUserGroupDto(userGroup, users));
+                dtoFactory.createUserGroupDto(userGroup, users, policyEntities));
 
         return entityFactory.createUserGroupEntity(snapshot, null, permissions);
     }
@@ -993,6 +1004,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     @Override
     public AccessPolicyEntity deleteAccessPolicy(final Revision revision, final String accessPolicyId) {
         final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
+        final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource());
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyId));
         final Set<TenantEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
         final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
@@ -1011,8 +1023,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 },
                 () -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId),
                 false, // no need to clean up any policies as it's already been removed above
-                dtoFactory.createAccessPolicyDto(accessPolicy, userGroups,
-                        users));
+                dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users, componentReference));
 
         return entityFactory.createAccessPolicyEntity(snapshot, null, permissions);
     }
@@ -1350,13 +1361,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         final String creator = NiFiUserUtils.getNiFiUserIdentity();
 
         final AccessPolicy newAccessPolicy = accessPolicyDAO.createAccessPolicy(accessPolicyDTO);
+        final ComponentReferenceEntity componentReference = createComponentReferenceEntity(newAccessPolicy.getResource());
         final AccessPolicyDTO newAccessPolicyDto = dtoFactory.createAccessPolicyDto(newAccessPolicy,
                 newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
                 newAccessPolicy.getUsers().stream().map(userId -> {
                     final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
                     return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
                             dtoFactory.createPermissionsDto(tenantAuthorizable));
-                }).collect(Collectors.toSet()));
+                }).collect(Collectors.toSet()), componentReference);
 
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyDTO.getId()));
         return entityFactory.createAccessPolicyEntity(newAccessPolicyDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions);
@@ -1376,8 +1388,34 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         return entityFactory.createUserEntity(newUserDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions);
     }
 
+    private ComponentReferenceEntity createComponentReferenceEntity(final String resource) {
+        ComponentReferenceEntity componentReferenceEntity = null;
+        try {
+            // get the component authorizable
+            Authorizable componentAuthorizable = authorizableLookup.getAuthorizableFromResource(resource);
+
+            // if this represents an authorizable whose policy permissions are enforced through the base resource,
+            // get the underlying base authorizable for the component reference
+            if (componentAuthorizable instanceof EnforcePolicyPermissionsThroughBaseResource) {
+                componentAuthorizable = ((EnforcePolicyPermissionsThroughBaseResource) componentAuthorizable).getBaseAuthorizable();
+            }
+
+            final ComponentReferenceDTO componentReference = dtoFactory.createComponentReferenceDto(componentAuthorizable);
+            if (componentReference != null) {
+                final PermissionsDTO componentReferencePermissions = dtoFactory.createPermissionsDto(componentAuthorizable);
+                final RevisionDTO componentReferenceRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(componentReference.getId()));
+                componentReferenceEntity = entityFactory.createComponentReferenceEntity(componentReference, componentReferenceRevision, componentReferencePermissions);
+            }
+        } catch (final ResourceNotFoundException e) {
+            // component not found for the specified resource
+        }
+
+        return componentReferenceEntity;
+    }
+
     private AccessPolicySummaryEntity createAccessPolicySummaryEntity(final AccessPolicy ap) {
-        final AccessPolicySummaryDTO apSummary = dtoFactory.createAccessPolicySummaryDto(ap);
+        final ComponentReferenceEntity componentReference = createComponentReferenceEntity(ap.getResource());
+        final AccessPolicySummaryDTO apSummary = dtoFactory.createAccessPolicySummaryDto(ap, componentReference);
         final PermissionsDTO apPermissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(ap.getIdentifier()));
         final RevisionDTO apRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(ap.getIdentifier()));
         return entityFactory.createAccessPolicySummaryEntity(apSummary, apRevision, apPermissions);
@@ -1385,15 +1423,12 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     @Override
     public UserGroupEntity createUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
-        final Authorizable tenantAuthorizable = authorizableLookup.getTenant();
         final String creator = NiFiUserUtils.getNiFiUserIdentity();
         final Group newUserGroup = userGroupDAO.createUserGroup(userGroupDTO);
-        final UserGroupDTO newUserGroupDto = dtoFactory.createUserGroupDto(newUserGroup, newUserGroup.getUsers().stream()
-                .map(userId -> {
-                    final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
-                    return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
-                            dtoFactory.createPermissionsDto(tenantAuthorizable));
-                }).collect(Collectors.toSet()));
+        final Set<TenantEntity> tenantEntities = newUserGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+        final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(newUserGroup.getIdentifier()).stream()
+                .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
+        final UserGroupDTO newUserGroupDto = dtoFactory.createUserGroupDto(newUserGroup, tenantEntities, policyEntities);
 
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
         return entityFactory.createUserGroupEntity(newUserGroupDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions);
@@ -2657,10 +2692,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     private AccessPolicyEntity createAccessPolicyEntity(final AccessPolicy accessPolicy) {
         final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(accessPolicy.getIdentifier()));
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicy.getIdentifier()));
+        final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource());
         return entityFactory.createAccessPolicyEntity(
                 dtoFactory.createAccessPolicyDto(accessPolicy,
                         accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
-                        accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet())),
+                        accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()), componentReference),
                 revision, permissions);
     }
 
@@ -2690,9 +2726,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     private UserGroupEntity createUserGroupEntity(final Group userGroup) {
         final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroup.getIdentifier()));
+        final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
         final Set<TenantEntity> users = userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
-        return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, users), userGroupRevision,
-            dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
+        final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream()
+                .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
+        return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, users, policyEntities), userGroupRevision, permissions);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index c39af2f..3383632 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -42,6 +42,7 @@ import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.Resource;
 import org.apache.nifi.authorization.User;
 import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.resource.ComponentAuthorizable;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
 import org.apache.nifi.cluster.coordination.heartbeat.NodeHeartbeat;
 import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus;
@@ -140,9 +141,11 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
 import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.entity.AccessPolicyEntity;
 import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
 import org.apache.nifi.web.api.entity.AllowableValueEntity;
 import org.apache.nifi.web.api.entity.BulletinEntity;
+import org.apache.nifi.web.api.entity.ComponentReferenceEntity;
 import org.apache.nifi.web.api.entity.ConnectionStatusSnapshotEntity;
 import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
 import org.apache.nifi.web.api.entity.PortStatusSnapshotEntity;
@@ -737,15 +740,32 @@ public final class DtoFactory {
      * @param userGroup user group
      * @return dto
      */
-    public UserGroupDTO createUserGroupDto(final Group userGroup, Set<TenantEntity> users) {
+    public UserGroupDTO createUserGroupDto(final Group userGroup, Set<TenantEntity> users, final Set<AccessPolicySummaryEntity> accessPolicies) {
         if (userGroup == null) {
             return null;
         }
 
+        // convert to access policies to handle backward compatibility due to incorrect
+        // type in the UserGroupDTO
+        final Set<AccessPolicyEntity> policies = accessPolicies.stream().map(summaryEntity -> {
+            final AccessPolicyDTO policy = new AccessPolicyDTO();
+            policy.setId(summaryEntity.getId());
+
+            if (summaryEntity.getPermissions().getCanRead()) {
+                final AccessPolicySummaryDTO summary = summaryEntity.getComponent();
+                policy.setResource(summary.getResource());
+                policy.setAction(summary.getAction());
+                policy.setComponentReference(summary.getComponentReference());
+            }
+
+            return entityFactory.createAccessPolicyEntity(policy, summaryEntity.getRevision(), summaryEntity.getPermissions());
+        }).collect(Collectors.toSet());
+
         final UserGroupDTO dto = new UserGroupDTO();
         dto.setId(userGroup.getIdentifier());
         dto.setUsers(users);
         dto.setIdentity(userGroup.getName());
+        dto.setAccessPolicies(policies);
 
         return dto;
     }
@@ -1584,7 +1604,20 @@ public final class DtoFactory {
         return dto;
     }
 
-    public AccessPolicySummaryDTO createAccessPolicySummaryDto(final AccessPolicy accessPolicy) {
+    public ComponentReferenceDTO createComponentReferenceDto(final Authorizable authorizable) {
+        if (authorizable == null || !(authorizable instanceof ComponentAuthorizable)) {
+            return null;
+        }
+
+        final ComponentAuthorizable componentAuthorizable = (ComponentAuthorizable) authorizable;
+        final ComponentReferenceDTO dto = new ComponentReferenceDTO();
+        dto.setId(componentAuthorizable.getIdentifier());
+        dto.setParentGroupId(componentAuthorizable.getProcessGroupIdentifier());
+        dto.setName(authorizable.getResource().getName());
+        return dto;
+    }
+
+    public AccessPolicySummaryDTO createAccessPolicySummaryDto(final AccessPolicy accessPolicy, final ComponentReferenceEntity componentReference) {
         if (accessPolicy == null) {
             return null;
         }
@@ -1593,10 +1626,13 @@ public final class DtoFactory {
         dto.setId(accessPolicy.getIdentifier());
         dto.setResource(accessPolicy.getResource());
         dto.setAction(accessPolicy.getAction().toString());
+        dto.setComponentReference(componentReference);
         return dto;
     }
 
-    public AccessPolicyDTO createAccessPolicyDto(final AccessPolicy accessPolicy, Set<TenantEntity> userGroups, Set<TenantEntity> users) {
+    public AccessPolicyDTO createAccessPolicyDto(final AccessPolicy accessPolicy, final Set<TenantEntity> userGroups,
+                                                 final Set<TenantEntity> users, final ComponentReferenceEntity componentReference) {
+
         if (accessPolicy == null) {
             return null;
         }
@@ -1607,6 +1643,7 @@ public final class DtoFactory {
         dto.setId(accessPolicy.getIdentifier());
         dto.setResource(accessPolicy.getResource());
         dto.setAction(accessPolicy.getAction().toString());
+        dto.setComponentReference(componentReference);
         return dto;
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
index 2a25447..41249ba 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
@@ -35,6 +35,7 @@ import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
 import org.apache.nifi.web.api.entity.ActionEntity;
 import org.apache.nifi.web.api.entity.AllowableValueEntity;
 import org.apache.nifi.web.api.entity.BulletinEntity;
+import org.apache.nifi.web.api.entity.ComponentReferenceEntity;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
 import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
 import org.apache.nifi.web.api.entity.ConnectionStatusSnapshotEntity;
@@ -294,6 +295,21 @@ public final class EntityFactory {
         return entity;
     }
 
+    public ComponentReferenceEntity createComponentReferenceEntity(final ComponentReferenceDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
+        final ComponentReferenceEntity entity = new ComponentReferenceEntity();
+        entity.setRevision(revision);
+        if (dto != null) {
+            entity.setPermissions(permissions);
+            entity.setId(dto.getId());
+            entity.setParentGroupId(dto.getParentGroupId());
+
+            if (permissions != null && permissions.getCanRead()) {
+                entity.setComponent(dto);
+            }
+        }
+        return entity;
+    }
+
     public UserGroupEntity createUserGroupEntity(final UserGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
         final UserGroupEntity entity = new UserGroupEntity();
         entity.setRevision(revision);

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/UserGroupDAO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/UserGroupDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/UserGroupDAO.java
index 1dc9a6d..9a579ef 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/UserGroupDAO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/UserGroupDAO.java
@@ -63,6 +63,14 @@ public interface UserGroupDAO {
     Set<AccessPolicy> getAccessPoliciesForUser(String userId);
 
     /**
+     * Gets the access policies for the user group with the specified ID.
+     *
+     * @param userGroupId The user group ID
+     * @return The set of access policies
+     */
+    Set<AccessPolicy> getAccessPoliciesForUserGroup(String userGroupId);
+
+    /**
      * Gets all user groups.
      *
      * @return The user group transfer objects

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardPolicyBasedAuthorizerDAO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardPolicyBasedAuthorizerDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardPolicyBasedAuthorizerDAO.java
index 24bcbef..a47c051 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardPolicyBasedAuthorizerDAO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardPolicyBasedAuthorizerDAO.java
@@ -278,6 +278,16 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
     }
 
     @Override
+    public Set<AccessPolicy> getAccessPoliciesForUserGroup(String userGroupId) {
+        return authorizer.getAccessPolicies().stream()
+                .filter(p -> {
+                    // policy contains the user group
+                    return p.getGroups().contains(userGroupId);
+                })
+                .collect(Collectors.toSet());
+    }
+
+    @Override
     public Set<Group> getUserGroups() {
         return authorizer.getGroups();
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/users.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/users.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/users.jsp
index 473f538..28ecd52 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/users.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/users.jsp
@@ -32,6 +32,7 @@
         <link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
         <link rel="stylesheet" href="fonts/flowfont/flowfont.css" type="text/css" />
         <link rel="stylesheet" href="assets/font-awesome/css/font-awesome.min.css" type="text/css" />
+        <script type="text/javascript" src="js/d3/d3.min.js"></script>
         <script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
         <script type="text/javascript" src="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
@@ -64,6 +65,7 @@
         <jsp:include page="/WEB-INF/partials/banners-utility.jsp"/>
         <jsp:include page="/WEB-INF/partials/ok-dialog.jsp"/>
         <jsp:include page="/WEB-INF/partials/users/user-dialog.jsp"/>
+        <jsp:include page="/WEB-INF/partials/users/user-policies-dialog.jsp"/>
         <jsp:include page="/WEB-INF/partials/users/user-delete-dialog.jsp"/>
         <jsp:include page="/WEB-INF/partials/users/users-content.jsp"/>
     </body>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-policies-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-policies-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-policies-dialog.jsp
new file mode 100644
index 0000000..b38a101
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-policies-dialog.jsp
@@ -0,0 +1,29 @@
+<%--
+ 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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<div id="user-policies-dialog" class="hidden large-dialog">
+    <div class="dialog-content">
+        <div class="setting">
+            <div class="setting-name">User</div>
+            <div class="setting-field">
+                <div id="policies-dialog-user-name"></div>
+            </div>
+        </div>
+        <div id="user-policy-message" title="Some policies may be inherited by descendant components unless explicitly overridden.">
+            Some policies may be inherited by descendant components unless explicitly overridden.
+        </div>
+        <div id="user-policies-table"></div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
index 1cacd2b..f380c89 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
@@ -81,6 +81,38 @@
     background-color: #fff;
 }
 
+/* user policies table */
+
+#policies-dialog-user-name {
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+}
+
+#user-policies-table {
+    position: absolute;
+    top: 40px;
+    left: 0px;
+    bottom: 33px;
+    right: 0px;
+    overflow: hidden;
+    background-color: #fff;
+}
+
+#user-policy-message {
+    position: absolute;
+    color: #775351;
+    font-family: Roboto;
+    font-size: 13px;
+    right: 0px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    left: 0px;
+    bottom: 0px;
+    height: 13px;
+}
+
 /* users dialog */
 
 #user-dialog {

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/css/slick-default-theme.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/css/slick-default-theme.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/css/slick-default-theme.css
index 780d0d3..ecb4c63 100755
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/css/slick-default-theme.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/css/slick-default-theme.css
@@ -7,6 +7,7 @@ classes should alter those!
 
 .slick-header-columns {
     color: #fff;
+    background-color: #728E9B;
 }
 
 .slick-header-column {
@@ -23,7 +24,7 @@ classes should alter those!
 .slick-row {
     position: absolute;
     background: white;
-    border: 0px;
+    border: 0;
     line-height: 22px;
 }
 
@@ -98,14 +99,14 @@ classes should alter those!
     to { box-shadow: none; }
 }
 
-.grid-canvas *:last-child{
-    border-right: 0px !important;
+.grid-canvas .slick-cell:first-child{
+    border-left: 0;
 }
 
 .slick-viewport .fa {
     color: #004849;
     line-height: 22px;
-    margin-top: 0px !important;
+    margin-top: 0 !important;
     width: 12px;
     height: 12px;
     float: left;
@@ -115,7 +116,7 @@ classes should alter those!
 .slick-viewport .icon {
     color: #004849;
     line-height: 24px;
-    margin-top: 0px !important;
+    margin-top: 0 !important;
     width: 12px;
     height: 12px;
     float: left;
@@ -148,9 +149,11 @@ classes should alter those!
 }
 
 .slick-cell, .slick-headerrow-column {
-    border-right: 1px solid #c7d2d7;
+    border-right: 0;
+    border-top: 0;
+    border-left: 1px solid #c7d2d7;
     border-bottom: 1px solid #c7d2d7;
-    padding: 0px 2px 6px 10px;
+    padding: 0 2px 6px 10px;
 }
 
 div.status-text {

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index 5076dc8..a1301d4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -505,6 +505,21 @@ nf.Canvas = (function () {
         };
         updateFlowStatusContainerSize();
 
+        // listen for events to go to components
+        $('body').on('GoTo:Component', function (e, item) {
+            nf.CanvasUtils.showComponent(item.parentGroupId, item.id);
+        });
+
+        // listen for events to go to process groups
+        $('body').on('GoTo:ProcessGroup', function (e, item) {
+            nf.CanvasUtils.enterGroup(item.id).done(function () {
+                nf.CanvasUtils.getSelection().classed('selected', false);
+
+                // inform Angular app that values have changed
+                nf.ng.Bridge.digest();
+            });
+        });
+
         // listen for browser resize events to reset the graph size
         $(window).on('resize', function (e) {
             if (e.target === window) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
index c693297..19ea71e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
@@ -339,43 +339,16 @@ nf.PolicyManagement = (function () {
 
         // policy type listing
         $('#policy-type-list').combo({
-            options: [{
-                text: 'view the user interface',
-                value: 'flow',
-                description: 'Allows users to view the user interface'
-            }, {
-                text: 'access the controller',
-                value: 'controller',
-                description: 'Allows users to view/modify the controller including Reporting Tasks, Controller Services, and Nodes in the Cluster'
-            }, {
-                text: 'query provenance',
-                value: 'provenance',
-                description: 'Allows users to submit a Provenance Search and request Event Lineage'
-            }, {
-                text: 'access all policies',
-                value: 'policies',
-                description: 'Allows users to view/modify the policies for all components'
-            }, {
-                text: 'access users/user groups',
-                value: 'tenants',
-                description: 'Allows users to view/modify the users and user groups'
-            }, {
-                text: 'retrieve site-to-site details',
-                value: 'site-to-site',
-                description: 'Allows other NiFi instances to retrieve Site-To-Site details of this NiFi'
-            }, {
-                text: 'view system diagnostics',
-                value: 'system',
-                description: 'Allows users to view System Diagnostics'
-            }, {
-                text: 'proxy user requests',
-                value: 'proxy',
-                description: 'Allows proxy machines to send requests on the behalf of others'
-            }, {
-                text: 'access counters',
-                value: 'counters',
-                description: 'Allows users to view/modify Counters'
-            }],
+            options: [
+                nf.Common.getPolicyTypeListing('flow'),
+                nf.Common.getPolicyTypeListing('controller'),
+                nf.Common.getPolicyTypeListing('provenance'),
+                nf.Common.getPolicyTypeListing('policies'),
+                nf.Common.getPolicyTypeListing('tenants'),
+                nf.Common.getPolicyTypeListing('site-to-site'),
+                nf.Common.getPolicyTypeListing('system'),
+                nf.Common.getPolicyTypeListing('proxy'),
+                nf.Common.getPolicyTypeListing('counters')],
             select: function (option) {
                 if (initialized) {
                     // record the policy type

http://git-wip-us.apache.org/repos/asf/nifi/blob/8f928e5d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 9dcf7d3..5d7054c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -77,7 +77,45 @@ $(document).ready(function () {
 nf.Common = (function () {
     // interval for cancelling token refresh when necessary
     var tokenRefreshInterval = null;
-    
+
+    var policyTypeListing = [{
+        text: 'view the user interface',
+        value: 'flow',
+        description: 'Allows users to view the user interface'
+    }, {
+        text: 'access the controller',
+        value: 'controller',
+        description: 'Allows users to view/modify the controller including Reporting Tasks, Controller Services, and Nodes in the Cluster'
+    }, {
+        text: 'query provenance',
+        value: 'provenance',
+        description: 'Allows users to submit a Provenance Search and request Event Lineage'
+    }, {
+        text: 'access all policies',
+        value: 'policies',
+        description: 'Allows users to view/modify the policies for all components'
+    }, {
+        text: 'access users/user groups',
+        value: 'tenants',
+        description: 'Allows users to view/modify the users and user groups'
+    }, {
+        text: 'retrieve site-to-site details',
+        value: 'site-to-site',
+        description: 'Allows other NiFi instances to retrieve Site-To-Site details of this NiFi'
+    }, {
+        text: 'view system diagnostics',
+        value: 'system',
+        description: 'Allows users to view System Diagnostics'
+    }, {
+        text: 'proxy user requests',
+        value: 'proxy',
+        description: 'Allows proxy machines to send requests on the behalf of others'
+    }, {
+        text: 'access counters',
+        value: 'counters',
+        description: 'Allows users to view/modify Counters'
+    }];
+
     return {
         ANONYMOUS_USER_TEXT: 'Anonymous user',
 
@@ -652,12 +690,12 @@ nf.Common = (function () {
         formatValue: function (value) {
             if (nf.Common.isDefinedAndNotNull(value)) {
                 if (value === '') {
-                    return '<span class="blank" style="font-size: 13px; padding-top: 2px;">Empty string previously set</span>';
+                    return '<span class="blank" style="font-size: 13px; padding-top: 2px;">Empty string set</span>';
                 } else {
                     return nf.Common.escapeHtml(value);
                 }
             } else {
-                return '<span class="unset" style="font-size: 13px; padding-top: 2px;">No value previously set</span>';
+                return '<span class="unset" style="font-size: 13px; padding-top: 2px;">No value set</span>';
             }
         },
 
@@ -1052,10 +1090,10 @@ nf.Common = (function () {
             if (!nf.Common.isDefinedAndNotNull(rawDateTime)) {
                 return new Date();
             }
-            if (rawDateTime === 'No value previously set') {
+            if (rawDateTime === 'No value set') {
                 return new Date();
             }
-            if (rawDateTime === 'Empty string previously set') {
+            if (rawDateTime === 'Empty string set') {
                 return new Date();
             }
 
@@ -1271,6 +1309,13 @@ nf.Common = (function () {
                 }
             });
             return formattedBulletinEntities;
+        },
+
+        getPolicyTypeListing: function (value) {
+            var nest = d3.nest()
+                .key(function(d) { return d.value; })
+                .map(policyTypeListing, d3.map);
+            return nest.get(value)[0];
         }
     };
 }());