http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 5d41c2c..b72d72c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -19,10 +19,6 @@ package org.apache.nifi.web.controller;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authorization.AccessDeniedException;
-import org.apache.nifi.authorization.AuthorizationRequest;
-import org.apache.nifi.authorization.AuthorizationResult;
-import org.apache.nifi.authorization.AuthorizationResult.Result;
 import org.apache.nifi.authorization.Authorizer;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.Resource;
@@ -31,6 +27,7 @@ import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.resource.ResourceType;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
 import org.apache.nifi.cluster.coordination.ClusterCoordinator;
 import org.apache.nifi.cluster.coordination.node.NodeConnectionState;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
@@ -116,7 +113,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
 import java.io.IOException;
 import java.io.InputStream;
 import java.text.Collator;
@@ -803,7 +799,7 @@ public class ControllerFacade implements Authorizable {
         // add each processor
         for (final ProcessorNode processor : root.findAllProcessors()) {
             
resources.add(ResourceFactory.getComponentResource(ResourceType.Processor, 
processor.getIdentifier(), processor.getName()));
-            
resources.add(ResourceFactory.getComponentProvenanceResource(ResourceType.Processor,
 processor.getIdentifier(), processor.getName()));
+            
resources.add(ResourceFactory.getProvenanceEventResource(processor.getResource()));
         }
 
         // add each connection
@@ -820,25 +816,25 @@ public class ControllerFacade implements Authorizable {
         // add each process group
         for (final ProcessGroup processGroup : root.findAllProcessGroups()) {
             
resources.add(ResourceFactory.getComponentResource(ResourceType.ProcessGroup, 
processGroup.getIdentifier(), processGroup.getName()));
-            
resources.add(ResourceFactory.getComponentProvenanceResource(ResourceType.ProcessGroup,
 processGroup.getIdentifier(), processGroup.getName()));
+            
resources.add(ResourceFactory.getProvenanceEventResource(processGroup.getResource()));
         }
 
         // add each remote process group
         for (final RemoteProcessGroup remoteProcessGroup : 
root.findAllRemoteProcessGroups()) {
             
resources.add(ResourceFactory.getComponentResource(ResourceType.RemoteProcessGroup,
 remoteProcessGroup.getIdentifier(), remoteProcessGroup.getName()));
-            
resources.add(ResourceFactory.getComponentProvenanceResource(ResourceType.RemoteProcessGroup,
 remoteProcessGroup.getIdentifier(), remoteProcessGroup.getName()));
+            
resources.add(ResourceFactory.getProvenanceEventResource(remoteProcessGroup.getResource()));
         }
 
         // add each input port
         for (final Port inputPort : root.findAllInputPorts()) {
             
resources.add(ResourceFactory.getComponentResource(ResourceType.InputPort, 
inputPort.getIdentifier(), inputPort.getName()));
-            
resources.add(ResourceFactory.getComponentProvenanceResource(ResourceType.InputPort,
 inputPort.getIdentifier(), inputPort.getName()));
+            
resources.add(ResourceFactory.getProvenanceEventResource(inputPort.getResource()));
         }
 
         // add each output port
         for (final Port outputPort : root.findAllOutputPorts()) {
             
resources.add(ResourceFactory.getComponentResource(ResourceType.OutputPort, 
outputPort.getIdentifier(), outputPort.getName()));
-            
resources.add(ResourceFactory.getComponentProvenanceResource(ResourceType.OutputPort,
 outputPort.getIdentifier(), outputPort.getName()));
+            
resources.add(ResourceFactory.getProvenanceEventResource(outputPort.getResource()));
         }
 
         // add each controller service
@@ -943,7 +939,7 @@ public class ControllerFacade implements Authorizable {
 
         // submit the query to the provenance repository
         final ProvenanceEventRepository provenanceRepository = 
flowController.getProvenanceRepository();
-        final QuerySubmission querySubmission = 
provenanceRepository.submitQuery(query);
+        final QuerySubmission querySubmission = 
provenanceRepository.submitQuery(query, NiFiUserUtils.getNiFiUser());
 
         // return the query with the results populated at this point
         return getProvenanceQuery(querySubmission.getQueryIdentifier());
@@ -959,7 +955,7 @@ public class ControllerFacade implements Authorizable {
         try {
             // get the query to the provenance repository
             final ProvenanceEventRepository provenanceRepository = 
flowController.getProvenanceRepository();
-            final QuerySubmission querySubmission = 
provenanceRepository.retrieveQuerySubmission(provenanceId);
+            final QuerySubmission querySubmission = 
provenanceRepository.retrieveQuerySubmission(provenanceId, 
NiFiUserUtils.getNiFiUser());
 
             // ensure the query results could be found
             if (querySubmission == null) {
@@ -1056,13 +1052,13 @@ public class ControllerFacade implements Authorizable {
         // submit the event
         if 
(LineageRequestType.FLOWFILE.equals(requestDto.getLineageRequestType())) {
             // submit uuid
-            result = 
provenanceRepository.submitLineageComputation(requestDto.getUuid());
+            result = 
provenanceRepository.submitLineageComputation(requestDto.getUuid(), 
NiFiUserUtils.getNiFiUser());
         } else {
             // submit event... (parents or children)
             if 
(LineageRequestType.PARENTS.equals(requestDto.getLineageRequestType())) {
-                result = 
provenanceRepository.submitExpandParents(requestDto.getEventId());
+                result = 
provenanceRepository.submitExpandParents(requestDto.getEventId(), 
NiFiUserUtils.getNiFiUser());
             } else {
-                result = 
provenanceRepository.submitExpandChildren(requestDto.getEventId());
+                result = 
provenanceRepository.submitExpandChildren(requestDto.getEventId(), 
NiFiUserUtils.getNiFiUser());
             }
         }
 
@@ -1078,7 +1074,7 @@ public class ControllerFacade implements Authorizable {
     public LineageDTO getLineage(final String lineageId) {
         // get the query to the provenance repository
         final ProvenanceEventRepository provenanceRepository = 
flowController.getProvenanceRepository();
-        final ComputeLineageSubmission computeLineageSubmission = 
provenanceRepository.retrieveLineageSubmission(lineageId);
+        final ComputeLineageSubmission computeLineageSubmission = 
provenanceRepository.retrieveLineageSubmission(lineageId, 
NiFiUserUtils.getNiFiUser());
 
         // ensure the submission was found
         if (computeLineageSubmission == null) {
@@ -1096,7 +1092,7 @@ public class ControllerFacade implements Authorizable {
     public void deleteProvenanceQuery(final String provenanceId) {
         // get the query to the provenance repository
         final ProvenanceEventRepository provenanceRepository = 
flowController.getProvenanceRepository();
-        final QuerySubmission querySubmission = 
provenanceRepository.retrieveQuerySubmission(provenanceId);
+        final QuerySubmission querySubmission = 
provenanceRepository.retrieveQuerySubmission(provenanceId, 
NiFiUserUtils.getNiFiUser());
         if (querySubmission != null) {
             querySubmission.cancel();
         }
@@ -1110,7 +1106,7 @@ public class ControllerFacade implements Authorizable {
     public void deleteLineage(final String lineageId) {
         // get the query to the provenance repository
         final ProvenanceEventRepository provenanceRepository = 
flowController.getProvenanceRepository();
-        final ComputeLineageSubmission computeLineageSubmission = 
provenanceRepository.retrieveLineageSubmission(lineageId);
+        final ComputeLineageSubmission computeLineageSubmission = 
provenanceRepository.retrieveLineageSubmission(lineageId, 
NiFiUserUtils.getNiFiUser());
         if (computeLineageSubmission != null) {
             computeLineageSubmission.cancel();
         }
@@ -1129,7 +1125,7 @@ public class ControllerFacade implements Authorizable {
             final NiFiUser user = NiFiUserUtils.getNiFiUser();
 
             // get the event in order to get the filename
-            final ProvenanceEventRecord event = 
flowController.getProvenanceRepository().getEvent(eventId);
+            final ProvenanceEventRecord event = 
flowController.getProvenanceRepository().getEvent(eventId, 
NiFiUserUtils.getNiFiUser());
             if (event == null) {
                 throw new ResourceNotFoundException("Unable to find the 
specified event.");
             }
@@ -1145,54 +1141,18 @@ public class ControllerFacade implements Authorizable {
             // calculate the dn chain
             final List<String> dnChain = 
ProxiedEntitiesUtils.buildProxiedEntitiesChain(user);
             dnChain.forEach(identity -> {
-                final String rootGroupId = flowController.getRootGroupId();
-                final ProcessGroup rootGroup = 
flowController.getGroup(rootGroupId);
-
-                final Resource eventResource;
-                if (rootGroupId.equals(event.getComponentId())) {
-                    eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.ProcessGroup, 
rootGroup.getIdentifier(), rootGroup.getName());
-                } else {
-                    final Connectable connectable = 
rootGroup.findConnectable(event.getComponentId());
-
-                    if (connectable == null) {
-                        throw new AccessDeniedException("The component that 
generated this event is no longer part of the data flow. Unable to determine 
access policy.");
-                    }
-
-                    switch (connectable.getConnectableType()) {
-                        case PROCESSOR:
-                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.Processor, 
connectable.getIdentifier(), connectable.getName());
-                            break;
-                        case INPUT_PORT:
-                        case REMOTE_INPUT_PORT:
-                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.InputPort, 
connectable.getIdentifier(), connectable.getName());
-                            break;
-                        case OUTPUT_PORT:
-                        case REMOTE_OUTPUT_PORT:
-                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.OutputPort, 
connectable.getIdentifier(), connectable.getName());
-                            break;
-                        case FUNNEL:
-                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.Funnel, 
connectable.getIdentifier(), connectable.getName());
-                            break;
-                        default:
-                            throw new 
WebApplicationException(Response.serverError().entity("An unexpected type of 
component generated this event.").build());
+                final Authorizable eventAuthorizable = 
flowController.createProvenanceAuthorizable(event.getComponentId());
+                final NiFiUser chainUser = new StandardNiFiUser(identity) {
+                    private static final long serialVersionUID = 
7589311627013017356L;
+
+                    @Override
+                    public boolean isAnonymous() {
+                        // allow current user to drive anonymous flag as 
anonymous users are never chained... supports single user case
+                        return user.isAnonymous();
                     }
-                }
+                };
 
-                // build the request
-                final AuthorizationRequest request = new 
AuthorizationRequest.Builder()
-                        .identity(identity)
-                        .anonymous(user.isAnonymous()) // allow current user 
to drive anonymous flag as anonymous users are never chained... supports single 
user case
-                        .accessAttempt(false)
-                        .action(RequestAction.READ)
-                        .resource(eventResource)
-                        .eventAttributes(attributes)
-                        .build();
-
-                // perform the authorization
-                final AuthorizationResult result = 
authorizer.authorize(request);
-                if (!Result.Approved.equals(result.getResult())) {
-                    throw new AccessDeniedException(result.getExplanation());
-                }
+                eventAuthorizable.authorize(authorizer, RequestAction.READ, 
chainUser);
             });
 
             // get the filename and fall back to the identifier (should never 
happen)
@@ -1229,13 +1189,13 @@ public class ControllerFacade implements Authorizable {
             }
 
             // lookup the original event
-            final ProvenanceEventRecord originalEvent = 
flowController.getProvenanceRepository().getEvent(eventId);
+            final ProvenanceEventRecord originalEvent = 
flowController.getProvenanceRepository().getEvent(eventId, 
NiFiUserUtils.getNiFiUser());
             if (originalEvent == null) {
                 throw new ResourceNotFoundException("Unable to find the 
specified event.");
             }
 
             // replay the flow file
-            final ProvenanceEventRecord event = 
flowController.replayFlowFile(originalEvent, user.getIdentity());
+            final ProvenanceEventRecord event = 
flowController.replayFlowFile(originalEvent, user);
 
             // convert the event record
             return createProvenanceEventDto(event);
@@ -1252,7 +1212,7 @@ public class ControllerFacade implements Authorizable {
      */
     public ProvenanceEventDTO getProvenanceEvent(final Long eventId) {
         try {
-            final ProvenanceEventRecord event = 
flowController.getProvenanceRepository().getEvent(eventId);
+            final ProvenanceEventRecord event = 
flowController.getProvenanceRepository().getEvent(eventId, 
NiFiUserUtils.getNiFiUser());
             if (event == null) {
                 throw new ResourceNotFoundException("Unable to find the 
specified event.");
             }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.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/StandardConnectionDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
index e16dd05..1a2669b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
@@ -298,7 +298,7 @@ public class StandardConnectionDAO extends ComponentDAO 
implements ConnectionDAO
         }
 
         // ensure the user has write access to the source component
-        source.authorize(authorizer, RequestAction.WRITE);
+        source.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
 
         // find the destination
         final Connectable destination;
@@ -324,7 +324,7 @@ public class StandardConnectionDAO extends ComponentDAO 
implements ConnectionDAO
         }
 
         // ensure the user has write access to the source component
-        destination.authorize(authorizer, RequestAction.WRITE);
+        destination.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
 
         // determine the relationships
         final Set<String> relationships = new HashSet<>();

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/StandardNiFiServiceFacadeSpec.groovy
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/StandardNiFiServiceFacadeSpec.groovy
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/StandardNiFiServiceFacadeSpec.groovy
index 7b5f594..87dbf86 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/StandardNiFiServiceFacadeSpec.groovy
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/StandardNiFiServiceFacadeSpec.groovy
@@ -20,6 +20,7 @@ import org.apache.nifi.authorization.*
 import org.apache.nifi.authorization.resource.Authorizable
 import org.apache.nifi.authorization.resource.ResourceFactory
 import org.apache.nifi.authorization.user.NiFiUser
+import org.apache.nifi.authorization.user.StandardNiFiUser
 import org.apache.nifi.authorization.user.NiFiUserDetails
 import org.apache.nifi.controller.service.ControllerServiceProvider
 import org.apache.nifi.web.api.dto.*
@@ -39,7 +40,7 @@ import spock.lang.Unroll
 class StandardNiFiServiceFacadeSpec extends Specification {
 
     def setup() {
-        final NiFiUser user = new NiFiUser("nifi-user");
+        final NiFiUser user = new StandardNiFiUser("nifi-user");
         final NiFiAuthenticationToken auth = new NiFiAuthenticationToken(new 
NiFiUserDetails(user));
         SecurityContextHolder.getContext().setAuthentication(auth);
     }
@@ -867,17 +868,17 @@ class StandardNiFiServiceFacadeSpec extends Specification 
{
         }
 
         @Override
-        boolean isAuthorized(Authorizer authorzr, RequestAction action) {
+        boolean isAuthorized(Authorizer authorzr, RequestAction action, 
NiFiUser user) {
             return isAuthorized
         }
 
         @Override
-        AuthorizationResult checkAuthorization(Authorizer authorzr, 
RequestAction action) {
+        AuthorizationResult checkAuthorization(Authorizer authorzr, 
RequestAction action, NiFiUser user) {
             return authorizationResult
         }
 
         @Override
-        void authorize(Authorizer authorzr, RequestAction action) throws 
AccessDeniedException {
+        void authorize(Authorizer authorzr, RequestAction action, NiFiUser 
user) throws AccessDeniedException {
             if (!isAuthorized) {
                 throw new AccessDeniedException("test exception, access 
denied")
             }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/src/test/java/org/apache/nifi/web/revision/TestNaiveRevisionManager.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/src/test/java/org/apache/nifi/web/revision/TestNaiveRevisionManager.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/src/test/java/org/apache/nifi/web/revision/TestNaiveRevisionManager.java
index e3148d3..a4e17e8 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/src/test/java/org/apache/nifi/web/revision/TestNaiveRevisionManager.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/src/test/java/org/apache/nifi/web/revision/TestNaiveRevisionManager.java
@@ -39,6 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
 import org.apache.nifi.web.FlowModification;
 import org.apache.nifi.web.InvalidRevisionException;
 import org.apache.nifi.web.Revision;
@@ -49,7 +50,7 @@ import org.junit.Test;
 public class TestNaiveRevisionManager {
     private static final String CLIENT_1 = "client-1";
     private static final String COMPONENT_1 = "component-1";
-    private static final NiFiUser USER_1 = new NiFiUser("user-1");
+    private static final NiFiUser USER_1 = new StandardNiFiUser("user-1");
 
     private RevisionUpdate<Object> components(final Revision revision) {
         return new StandardRevisionUpdate<Object>(null, new 
FlowModification(revision, null));
@@ -302,7 +303,7 @@ public class TestNaiveRevisionManager {
         final RevisionClaim firstClaim = 
revisionManager.requestClaim(firstRevision, USER_1);
         assertNotNull(firstClaim);
 
-        final NiFiUser user2 = new NiFiUser("user-2");
+        final NiFiUser user2 = new StandardNiFiUser("user-2");
         try {
             revisionManager.updateRevision(firstClaim, user2, () -> null);
             Assert.fail("Expected updateRevision to fail with a different user 
but it succeeded");
@@ -318,7 +319,7 @@ public class TestNaiveRevisionManager {
         final RevisionClaim firstClaim = 
revisionManager.requestClaim(firstRevision, USER_1);
         assertNotNull(firstClaim);
 
-        final NiFiUser user2 = new NiFiUser("user-2");
+        final NiFiUser user2 = new StandardNiFiUser("user-2");
         try {
             revisionManager.deleteRevision(firstClaim, user2, () -> null);
             Assert.fail("Expected deleteRevision to fail with a different user 
but it succeeded");

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
index b1a9a66..da9c52e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
@@ -16,14 +16,14 @@
  */
 package org.apache.nifi.web.security.anonymous;
 
-import org.apache.nifi.authorization.user.NiFiUser;
+import javax.servlet.http.HttpServletRequest;
+
 import org.apache.nifi.authorization.user.NiFiUserDetails;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
 import org.apache.nifi.web.security.token.NiFiAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
 
-import javax.servlet.http.HttpServletRequest;
-
 public class NiFiAnonymousUserFilter extends AnonymousAuthenticationFilter {
 
     private static final String ANONYMOUS_KEY = "anonymousNifiKey";
@@ -34,7 +34,7 @@ public class NiFiAnonymousUserFilter extends 
AnonymousAuthenticationFilter {
 
     @Override
     protected Authentication createAuthentication(HttpServletRequest request) {
-        return new NiFiAuthenticationToken(new 
NiFiUserDetails(NiFiUser.ANONYMOUS));
+        return new NiFiAuthenticationToken(new 
NiFiUserDetails(StandardNiFiUser.ANONYMOUS));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
index 7634123..f68935e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
@@ -16,15 +16,17 @@
  */
 package org.apache.nifi.web.security.jwt;
 
-import io.jsonwebtoken.JwtException;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserDetails;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
 import org.apache.nifi.web.security.InvalidAuthenticationException;
 import org.apache.nifi.web.security.token.NiFiAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 
+import io.jsonwebtoken.JwtException;
+
 /**
  *
  */
@@ -42,7 +44,7 @@ public class JwtAuthenticationProvider implements 
AuthenticationProvider {
 
         try {
             final String jwtPrincipal = 
jwtService.getAuthenticationFromToken(request.getToken());
-            final NiFiUser user = new NiFiUser(jwtPrincipal);
+            final NiFiUser user = new StandardNiFiUser(jwtPrincipal);
             return new NiFiAuthenticationToken(new NiFiUserDetails(user));
         } catch (JwtException e) {
             throw new InvalidAuthenticationException(e.getMessage(), e);

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpAuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpAuthenticationProvider.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpAuthenticationProvider.java
index 8f2712c..b80a97e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpAuthenticationProvider.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpAuthenticationProvider.java
@@ -18,6 +18,7 @@ package org.apache.nifi.web.security.otp;
 
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserDetails;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
 import org.apache.nifi.web.security.InvalidAuthenticationException;
 import org.apache.nifi.web.security.token.NiFiAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationProvider;
@@ -46,7 +47,7 @@ public class OtpAuthenticationProvider implements 
AuthenticationProvider {
             } else {
                 otpPrincipal = 
otpService.getAuthenticationFromUiExtensionToken(request.getToken());
             }
-            final NiFiUser user = new NiFiUser(otpPrincipal);
+            final NiFiUser user = new StandardNiFiUser(otpPrincipal);
             return new NiFiAuthenticationToken(new NiFiUserDetails(user));
         } catch (OtpAuthenticationException e) {
             throw new InvalidAuthenticationException(e.getMessage(), e);

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationToken.java
index f7964f5..564ac5f 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationToken.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationToken.java
@@ -47,4 +47,9 @@ public class NiFiAuthenticationToken extends 
AbstractAuthenticationToken {
     public final void setAuthenticated(boolean authenticated) {
         throw new IllegalArgumentException("Cannot change the authenticated 
state.");
     }
+
+    @Override
+    public String toString() {
+        return nifiUserDetails.getUsername();
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
index 43d6958..b72d5e1 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
@@ -26,6 +26,7 @@ import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserDetails;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
 import org.apache.nifi.web.security.InvalidAuthenticationException;
 import org.apache.nifi.web.security.ProxiedEntitiesUtils;
 import org.apache.nifi.web.security.UntrustedProxyException;
@@ -64,7 +65,7 @@ public class X509AuthenticationProvider implements 
AuthenticationProvider {
         }
 
         if (StringUtils.isBlank(request.getProxiedEntitiesChain())) {
-            return new NiFiAuthenticationToken(new NiFiUserDetails(new 
NiFiUser(authenticationResponse.getIdentity(), 
authenticationResponse.getUsername(), null)));
+            return new NiFiAuthenticationToken(new NiFiUserDetails(new 
StandardNiFiUser(authenticationResponse.getIdentity(), 
authenticationResponse.getUsername(), null)));
         } else {
             // build the entire proxy chain if applicable - 
<end-user><proxy1><proxy2>
             final List<String> proxyChain = new 
ArrayList<>(ProxiedEntitiesUtils.tokenizeProxiedEntitiesChain(request.getProxiedEntitiesChain()));
@@ -91,7 +92,7 @@ public class X509AuthenticationProvider implements 
AuthenticationProvider {
                     }
                 }
 
-                proxy = new NiFiUser(chainIter.previous(), proxy);
+                proxy = new StandardNiFiUser(chainIter.previous(), proxy);
             }
 
             return new NiFiAuthenticationToken(new NiFiUserDetails(proxy));

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
index 7c27746..04a2204 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
@@ -145,9 +145,9 @@ nf.ProvenanceLineage = (function () {
      */
     var getLineage = function (lineage) {
         var url = lineage.uri;
-        if (nf.Common.isDefinedAndNotNull(lineage.clusterNodeId)) {
+        if (nf.Common.isDefinedAndNotNull(lineage.request.clusterNodeId)) {
             url += '?' + $.param({
-                    clusterNodeId: lineage.clusterNodeId
+                    clusterNodeId: lineage.request.clusterNodeId
                 });
         }
 
@@ -166,9 +166,9 @@ nf.ProvenanceLineage = (function () {
      */
     var cancelLineage = function (lineage) {
         var url = lineage.uri;
-        if (nf.Common.isDefinedAndNotNull(lineage.clusterNodeId)) {
+        if (nf.Common.isDefinedAndNotNull(lineage.request.clusterNodeId)) {
             url += '?' + $.param({
-                    clusterNodeId: lineage.clusterNodeId
+                    clusterNodeId: lineage.request.clusterNodeId
                 });
         }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
index ca1a83e..f024866 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
@@ -384,7 +384,7 @@ nf.ProvenanceTable = (function () {
                                 startTime = config.defaultStartTime;
                                 
$('#provenance-search-start-time').val(startTime);
                             }
-                            search['startDate'] = startDate + ' ' + startTime;
+                            search['startDate'] = startDate + ' ' + startTime 
+ ' ' + $('.timezone:first').text();
                         }
 
                         // extract the end date time
@@ -395,7 +395,7 @@ nf.ProvenanceTable = (function () {
                                 endTime = config.defaultEndTime;
                                 $('#provenance-search-end-time').val(endTime);
                             }
-                            search['endDate'] = endDate + ' ' + endTime;
+                            search['endDate'] = endDate + ' ' + endTime + ' ' 
+ $('.timezone:first').text();
                         }
 
                         // extract the min/max file size

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
index e1891a2..a04aad7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
@@ -29,7 +29,7 @@ nf.Provenance = (function () {
      */
     var config = {
         urls: {
-            cluster: '../nifi-api/controller/cluster',
+            flowConfig: '../nifi-api/flow/config',
             banners: '../nifi-api/flow/banners',
             about: '../nifi-api/flow/about',
             authorities: '../nifi-api/flow/authorities'
@@ -45,23 +45,12 @@ nf.Provenance = (function () {
      * Determines if this NiFi is clustered.
      */
     var detectedCluster = function () {
-        return $.Deferred(function (deferred) {
-            $.ajax({
-                type: 'HEAD',
-                url: config.urls.cluster
-            }).done(function () {
-                isClustered = true;
-                deferred.resolve();
-            }).fail(function (xhr, status, error) {
-                if (xhr.status === 404) {
-                    isClustered = false;
-                    deferred.resolve();
-                } else {
-                    nf.Common.handleAjaxError(xhr, status, error);
-                    deferred.reject();
-                }
-            });
-        }).promise();
+        return $.ajax({
+                type: 'GET',
+                url: config.urls.flowConfig
+            }).done(function (response) {
+                isClustered = response.flowConfiguration.clustered;
+            }).fail(nf.Common.handleAjaxError);
     };
 
     /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
index b8c1a58..8476621 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
@@ -51,7 +51,7 @@ nf.Summary = (function () {
         urls: {
             banners: '../nifi-api/flow/banners',
             about: '../nifi-api/flow/about',
-            cluster: '../nifi-api/controller/cluster'
+            flowConfig: '../nifi-api/flow/config'
         }
     };
 
@@ -61,26 +61,15 @@ nf.Summary = (function () {
     var initializeSummaryTable = function () {
         return $.Deferred(function (deferred) {
             $.ajax({
-                type: 'HEAD',
-                url: config.urls.cluster
-            }).done(function () {
-                nf.SummaryTable.init(true).done(function () {
+                type: 'GET',
+                url: config.urls.flowConfig
+            }).done(function (response) {
+                
nf.SummaryTable.init(response.flowConfiguration.clustered).done(function () {
                     deferred.resolve();
                 }).fail(function () {
                     deferred.reject();
                 });
-            }).fail(function (xhr, status, error) {
-                if (xhr.status === 404) {
-                    nf.SummaryTable.init(false).done(function () {
-                        deferred.resolve();
-                    }).fail(function () {
-                        deferred.reject();
-                    });
-                } else {
-                    nf.Common.handleAjaxError(xhr, status, error);
-                    deferred.reject();
-                }
-            });
+            }).fail(nf.Common.handleAjaxError);
         }).promise();
     };
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
index b8d6f35..adb335c 100644
--- 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
+++ 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
@@ -59,6 +59,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.DirectoryReader;
@@ -68,6 +69,13 @@ import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.store.FSDirectory;
+import org.apache.nifi.authorization.AccessDeniedException;
+import org.apache.nifi.authorization.AuthorizationResult;
+import org.apache.nifi.authorization.AuthorizationResult.Result;
+import org.apache.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.RequestAction;
+import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.events.EventReporter;
 import org.apache.nifi.processor.DataUnit;
 import org.apache.nifi.provenance.expiration.ExpirationAction;
@@ -99,6 +107,7 @@ import org.apache.nifi.util.RingBuffer;
 import org.apache.nifi.util.RingBuffer.ForEachEvaluator;
 import org.apache.nifi.util.StopWatch;
 import org.apache.nifi.util.Tuple;
+import org.apache.nifi.web.ResourceNotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -163,7 +172,9 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     // we keep the last 1000 records on hand so that when the UI is opened and 
it asks for the last 1000 records we don't need to
     // read them. Since this is a very cheap operation to keep them, it's 
worth the tiny expense for the improved user experience.
     private final RingBuffer<ProvenanceEventRecord> latestRecords = new 
RingBuffer<>(1000);
-    private EventReporter eventReporter;
+    private EventReporter eventReporter; // effectively final
+    private Authorizer authorizer;  // effectively final
+    private ProvenanceAuthorizableFactory resourceFactory;  // effectively 
final
 
     public PersistentProvenanceRepository() throws IOException {
         this(createRepositoryConfiguration(), 10000);
@@ -207,7 +218,7 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     }
 
     @Override
-    public void initialize(final EventReporter eventReporter) throws 
IOException {
+    public void initialize(final EventReporter eventReporter, final Authorizer 
authorizer, final ProvenanceAuthorizableFactory resourceFactory) throws 
IOException {
         writeLock.lock();
         try {
             if (initialized.getAndSet(true)) {
@@ -215,6 +226,8 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
             }
 
             this.eventReporter = eventReporter;
+            this.authorizer = authorizer;
+            this.resourceFactory = resourceFactory;
 
             recover();
 
@@ -391,8 +404,46 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         persistRecord(events);
     }
 
+    public boolean isAuthorized(final ProvenanceEventRecord event, final 
NiFiUser user) {
+        if (authorizer == null || user == null) {
+            return true;
+        }
+
+        final Authorizable eventAuthorizable;
+        try {
+            eventAuthorizable = 
resourceFactory.createProvenanceAuthorizable(event.getComponentId());
+        } catch (final ResourceNotFoundException rnfe) {
+            return false;
+        }
+
+        final AuthorizationResult result = 
eventAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user);
+        return Result.Approved.equals(result.getResult());
+    }
+
+    protected void authorize(final ProvenanceEventRecord event, final NiFiUser 
user) {
+        if (authorizer == null) {
+            return;
+        }
+
+        final Authorizable eventAuthorizable = 
resourceFactory.createProvenanceAuthorizable(event.getComponentId());
+        eventAuthorizable.authorize(authorizer, RequestAction.READ, user);
+    }
+
+    private List<ProvenanceEventRecord> filterUnauthorizedEvents(final 
List<ProvenanceEventRecord> events, final NiFiUser user) {
+        return events.stream().filter(event -> isAuthorized(event, 
user)).collect(Collectors.<ProvenanceEventRecord> toList());
+    }
+
+    private Set<ProvenanceEventRecord> 
replaceUnauthorizedWithPlaceholders(final Set<ProvenanceEventRecord> events, 
final NiFiUser user) {
+        return events.stream().map(event -> isAuthorized(event, user) ? event 
: new PlaceholderProvenanceEvent(event)).collect(Collectors.toSet());
+    }
+
     @Override
     public List<ProvenanceEventRecord> getEvents(final long firstRecordId, 
final int maxRecords) throws IOException {
+        return getEvents(firstRecordId, maxRecords, null);
+    }
+
+    @Override
+    public List<ProvenanceEventRecord> getEvents(final long firstRecordId, 
final int maxRecords, final NiFiUser user) throws IOException {
         final List<ProvenanceEventRecord> records = new 
ArrayList<>(maxRecords);
 
         final List<Path> paths = getPathsForId(firstRecordId);
@@ -417,7 +468,7 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
 
                 StandardProvenanceEventRecord record;
                 while (records.size() < maxRecords && (record = 
reader.nextRecord()) != null) {
-                    if (record.getEventId() >= firstRecordId) {
+                    if (record.getEventId() >= firstRecordId && 
isAuthorized(record, user)) {
                         records.add(record);
                     }
                 }
@@ -1807,8 +1858,8 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         return new ArrayList<>(configuration.getSearchableAttributes());
     }
 
-    QueryResult queryEvents(final Query query) throws IOException {
-        final QuerySubmission submission = submitQuery(query);
+    QueryResult queryEvents(final Query query, final NiFiUser user) throws 
IOException {
+        final QuerySubmission submission = submitQuery(query, user);
         final QueryResult result = submission.getResult();
         while (!result.isFinished()) {
             try {
@@ -1826,8 +1877,10 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     }
 
     @Override
-    public QuerySubmission submitQuery(final Query query) {
+    public QuerySubmission submitQuery(final Query query, final NiFiUser user) 
{
+        final String userId = user.getIdentity();
         final int numQueries = querySubmissionMap.size();
+
         if (numQueries > MAX_UNDELETED_QUERY_RESULTS) {
             throw new IllegalStateException("Cannot process query because 
there are currently " + numQueries + " queries whose results have not "
                     + "been deleted due to poorly behaving clients not issuing 
DELETE requests. Please try again later.");
@@ -1838,10 +1891,10 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         }
 
         if (query.getSearchTerms().isEmpty() && query.getStartDate() == null 
&& query.getEndDate() == null) {
-            final AsyncQuerySubmission result = new 
AsyncQuerySubmission(query, 1);
+            final AsyncQuerySubmission result = new 
AsyncQuerySubmission(query, 1, userId);
 
             if (latestRecords.getSize() >= query.getMaxResults()) {
-                final List<ProvenanceEventRecord> latestList = 
latestRecords.asList();
+                final List<ProvenanceEventRecord> latestList = 
filterUnauthorizedEvents(latestRecords.asList(), user);
                 final List<ProvenanceEventRecord> trimmed;
                 if (latestList.size() > query.getMaxResults()) {
                     trimmed = latestList.subList(latestList.size() - 
query.getMaxResults(), latestList.size());
@@ -1863,7 +1916,7 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
 
                 result.getResult().update(trimmed, totalNumDocs);
             } else {
-                queryExecService.submit(new GetMostRecentRunnable(query, 
result));
+                queryExecService.submit(new GetMostRecentRunnable(query, 
result, user));
             }
 
             querySubmissionMap.put(query.getIdentifier(), result);
@@ -1874,14 +1927,14 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         final List<File> indexDirectories = indexConfig.getIndexDirectories(
                 query.getStartDate() == null ? null : 
query.getStartDate().getTime(),
                         query.getEndDate() == null ? null : 
query.getEndDate().getTime());
-        final AsyncQuerySubmission result = new AsyncQuerySubmission(query, 
indexDirectories.size());
+        final AsyncQuerySubmission result = new AsyncQuerySubmission(query, 
indexDirectories.size(), userId);
         querySubmissionMap.put(query.getIdentifier(), result);
 
         if (indexDirectories.isEmpty()) {
             
result.getResult().update(Collections.<ProvenanceEventRecord>emptyList(), 0L);
         } else {
             for (final File indexDir : indexDirectories) {
-                queryExecService.submit(new QueryRunnable(query, result, 
indexDir, retrievalCount));
+                queryExecService.submit(new QueryRunnable(query, result, user, 
indexDir, retrievalCount));
             }
         }
 
@@ -2054,13 +2107,13 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         };
     }
 
-    Lineage computeLineage(final String flowFileUuid) throws IOException {
-        return computeLineage(Collections.<String>singleton(flowFileUuid), 
LineageComputationType.FLOWFILE_LINEAGE, null, 0L, Long.MAX_VALUE);
+    Lineage computeLineage(final String flowFileUuid, final NiFiUser user) 
throws IOException {
+        return computeLineage(Collections.<String> singleton(flowFileUuid), 
user, LineageComputationType.FLOWFILE_LINEAGE, null, 0L, Long.MAX_VALUE);
     }
 
-    private Lineage computeLineage(final Collection<String> flowFileUuids, 
final LineageComputationType computationType, final Long eventId, final Long 
startTimestamp,
+    private Lineage computeLineage(final Collection<String> flowFileUuids, 
final NiFiUser user, final LineageComputationType computationType, final Long 
eventId, final Long startTimestamp,
             final Long endTimestamp) throws IOException {
-        final AsyncLineageSubmission submission = 
submitLineageComputation(flowFileUuids, computationType, eventId, 
startTimestamp, endTimestamp);
+        final AsyncLineageSubmission submission = 
submitLineageComputation(flowFileUuids, user, computationType, eventId, 
startTimestamp, endTimestamp);
         final StandardLineageResult result = submission.getResult();
         while (!result.isFinished()) {
             try {
@@ -2077,29 +2130,31 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     }
 
     @Override
-    public AsyncLineageSubmission submitLineageComputation(final String 
flowFileUuid) {
-        return submitLineageComputation(Collections.singleton(flowFileUuid), 
LineageComputationType.FLOWFILE_LINEAGE, null, 0L, Long.MAX_VALUE);
+    public AsyncLineageSubmission submitLineageComputation(final String 
flowFileUuid, final NiFiUser user) {
+        return submitLineageComputation(Collections.singleton(flowFileUuid), 
user, LineageComputationType.FLOWFILE_LINEAGE, null, 0L, Long.MAX_VALUE);
     }
 
-    private AsyncLineageSubmission submitLineageComputation(final 
Collection<String> flowFileUuids, final LineageComputationType computationType,
+    private AsyncLineageSubmission submitLineageComputation(final 
Collection<String> flowFileUuids, final NiFiUser user, final 
LineageComputationType computationType,
             final Long eventId, final long startTimestamp, final long 
endTimestamp) {
         final List<File> indexDirs = 
indexConfig.getIndexDirectories(startTimestamp, endTimestamp);
-        final AsyncLineageSubmission result = new 
AsyncLineageSubmission(computationType, eventId, flowFileUuids, 
indexDirs.size());
+        final AsyncLineageSubmission result = new 
AsyncLineageSubmission(computationType, eventId, flowFileUuids, 
indexDirs.size(), user.getIdentity());
         lineageSubmissionMap.put(result.getLineageIdentifier(), result);
 
         for (final File indexDir : indexDirs) {
-            queryExecService.submit(new ComputeLineageRunnable(flowFileUuids, 
result, indexDir));
+            queryExecService.submit(new ComputeLineageRunnable(flowFileUuids, 
user, result, indexDir));
         }
 
         return result;
     }
 
     @Override
-    public AsyncLineageSubmission submitExpandChildren(final long eventId) {
+    public AsyncLineageSubmission submitExpandChildren(final long eventId, 
final NiFiUser user) {
+        final String userId = user.getIdentity();
+
         try {
             final ProvenanceEventRecord event = getEvent(eventId);
             if (event == null) {
-                final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String>emptyList(), 1);
+                final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String> emptyList(), 1, userId);
                 lineageSubmissionMap.put(submission.getLineageIdentifier(), 
submission);
                 
submission.getResult().update(Collections.<ProvenanceEventRecord>emptyList());
                 return submission;
@@ -2110,15 +2165,15 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
                 case FORK:
                 case JOIN:
                 case REPLAY:
-                    return submitLineageComputation(event.getChildUuids(), 
LineageComputationType.EXPAND_CHILDREN, eventId, event.getEventTime(), 
Long.MAX_VALUE);
+                    return submitLineageComputation(event.getChildUuids(), 
user, LineageComputationType.EXPAND_CHILDREN, eventId, event.getEventTime(), 
Long.MAX_VALUE);
                 default:
-                    final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String>emptyList(), 1);
+                    final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String> emptyList(), 1, userId);
                     
lineageSubmissionMap.put(submission.getLineageIdentifier(), submission);
                     submission.getResult().setError("Event ID " + eventId + " 
indicates an event of type " + event.getEventType() + " so its children cannot 
be expanded");
                     return submission;
             }
         } catch (final IOException ioe) {
-            final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String>emptyList(), 1);
+            final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String> emptyList(), 1, userId);
             lineageSubmissionMap.put(submission.getLineageIdentifier(), 
submission);
 
             if (ioe.getMessage() == null) {
@@ -2132,11 +2187,13 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     }
 
     @Override
-    public AsyncLineageSubmission submitExpandParents(final long eventId) {
+    public AsyncLineageSubmission submitExpandParents(final long eventId, 
final NiFiUser user) {
+        final String userId = user.getIdentity();
+
         try {
             final ProvenanceEventRecord event = getEvent(eventId);
             if (event == null) {
-                final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String>emptyList(), 1);
+                final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_CHILDREN, eventId, 
Collections.<String> emptyList(), 1, userId);
                 lineageSubmissionMap.put(submission.getLineageIdentifier(), 
submission);
                 
submission.getResult().update(Collections.<ProvenanceEventRecord>emptyList());
                 return submission;
@@ -2147,16 +2204,16 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
                 case FORK:
                 case CLONE:
                 case REPLAY:
-                    return submitLineageComputation(event.getParentUuids(), 
LineageComputationType.EXPAND_PARENTS, eventId, event.getLineageStartDate(), 
event.getEventTime());
+                    return submitLineageComputation(event.getParentUuids(), 
user, LineageComputationType.EXPAND_PARENTS, eventId, 
event.getLineageStartDate(), event.getEventTime());
                 default: {
-                    final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_PARENTS, eventId, 
Collections.<String>emptyList(), 1);
+                    final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_PARENTS, eventId, 
Collections.<String> emptyList(), 1, userId);
                     
lineageSubmissionMap.put(submission.getLineageIdentifier(), submission);
                     submission.getResult().setError("Event ID " + eventId + " 
indicates an event of type " + event.getEventType() + " so its parents cannot 
be expanded");
                     return submission;
                 }
             }
         } catch (final IOException ioe) {
-            final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_PARENTS, eventId, 
Collections.<String>emptyList(), 1);
+            final AsyncLineageSubmission submission = new 
AsyncLineageSubmission(LineageComputationType.EXPAND_PARENTS, eventId, 
Collections.<String> emptyList(), 1, userId);
             lineageSubmissionMap.put(submission.getLineageIdentifier(), 
submission);
 
             if (ioe.getMessage() == null) {
@@ -2170,17 +2227,47 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     }
 
     @Override
-    public AsyncLineageSubmission retrieveLineageSubmission(final String 
lineageIdentifier) {
-        return lineageSubmissionMap.get(lineageIdentifier);
+    public AsyncLineageSubmission retrieveLineageSubmission(final String 
lineageIdentifier, final NiFiUser user) {
+        final AsyncLineageSubmission submission = 
lineageSubmissionMap.get(lineageIdentifier);
+        final String userId = submission.getSubmitterIdentity();
+
+        if (user == null && userId == null) {
+            return submission;
+        }
+
+        if (user == null) {
+            throw new AccessDeniedException("Cannot retrieve Provenance 
Lineage Submission because no user id was provided");
+        }
+
+        if (userId == null || userId.equals(user.getIdentity())) {
+            return submission;
+        }
+
+        throw new AccessDeniedException("Cannot retrieve Provenance Lineage 
Submission because " + user.getIdentity() + " is not the user who submitted the 
request");
     }
 
     @Override
-    public QuerySubmission retrieveQuerySubmission(final String 
queryIdentifier) {
-        return querySubmissionMap.get(queryIdentifier);
+    public QuerySubmission retrieveQuerySubmission(final String 
queryIdentifier, final NiFiUser user) {
+        final QuerySubmission submission = 
querySubmissionMap.get(queryIdentifier);
+
+        final String userId = submission.getSubmitterIdentity();
+
+        if (user == null && userId == null) {
+            return submission;
+        }
+
+        if (user == null) {
+            throw new AccessDeniedException("Cannot retrieve Provenance Query 
Submission because no user id was provided");
+        }
+
+        if (userId == null || userId.equals(user.getIdentity())) {
+            return submission;
+        }
+
+        throw new AccessDeniedException("Cannot retrieve Provenance Query 
Submission because " + user.getIdentity() + " is not the user who submitted the 
request");
     }
 
-    @Override
-    public ProvenanceEventRecord getEvent(final long id) throws IOException {
+    private ProvenanceEventRecord getEvent(final long id) throws IOException {
         final List<ProvenanceEventRecord> records = getEvents(id, 1);
         if (records.isEmpty()) {
             return null;
@@ -2192,6 +2279,17 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         return record;
     }
 
+    @Override
+    public ProvenanceEventRecord getEvent(final long id, final NiFiUser user) 
throws IOException {
+        final ProvenanceEventRecord event = getEvent(id);
+        if (event == null) {
+            return null;
+        }
+
+        authorize(event, user);
+        return event;
+    }
+
     private boolean needToRollover() {
         final long writtenSinceRollover = bytesWrittenSinceRollover.get();
 
@@ -2268,10 +2366,12 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
 
         private final Query query;
         private final AsyncQuerySubmission submission;
+        private final NiFiUser user;
 
-        public GetMostRecentRunnable(final Query query, final 
AsyncQuerySubmission submission) {
+        public GetMostRecentRunnable(final Query query, final 
AsyncQuerySubmission submission, final NiFiUser user) {
             this.query = query;
             this.submission = submission;
+            this.user = user;
         }
 
         @Override
@@ -2293,7 +2393,7 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
                 }
                 final long totalNumDocs = maxEventId - minIndexedId;
 
-                final List<ProvenanceEventRecord> mostRecent = 
getEvents(startIndex, maxResults);
+                final List<ProvenanceEventRecord> mostRecent = 
getEvents(startIndex, maxResults, user);
                 submission.getResult().update(mostRecent, totalNumDocs);
             } catch (final IOException ioe) {
                 logger.error("Failed to retrieve records from Provenance 
Repository: " + ioe.toString());
@@ -2314,12 +2414,14 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
 
         private final Query query;
         private final AsyncQuerySubmission submission;
+        private final NiFiUser user;
         private final File indexDir;
         private final AtomicInteger retrievalCount;
 
-        public QueryRunnable(final Query query, final AsyncQuerySubmission 
submission, final File indexDir, final AtomicInteger retrievalCount) {
+        public QueryRunnable(final Query query, final AsyncQuerySubmission 
submission, final NiFiUser user, final File indexDir, final AtomicInteger 
retrievalCount) {
             this.query = query;
             this.submission = submission;
+            this.user = user;
             this.indexDir = indexDir;
             this.retrievalCount = retrievalCount;
         }
@@ -2328,7 +2430,7 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
         public void run() {
             try {
                 final IndexSearch search = new 
IndexSearch(PersistentProvenanceRepository.this, indexDir, indexManager, 
maxAttributeChars);
-                final StandardQueryResult queryResult = search.search(query, 
retrievalCount, firstEventTimestamp);
+                final StandardQueryResult queryResult = search.search(query, 
user, retrievalCount, firstEventTimestamp);
                 submission.getResult().update(queryResult.getMatchingEvents(), 
queryResult.getTotalHitCount());
             } catch (final Throwable t) {
                 logger.error("Failed to query Provenance Repository Index {} 
due to {}", indexDir, t.toString());
@@ -2348,11 +2450,13 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
     private class ComputeLineageRunnable implements Runnable {
 
         private final Collection<String> flowFileUuids;
+        private final NiFiUser user;
         private final File indexDir;
         private final AsyncLineageSubmission submission;
 
-        public ComputeLineageRunnable(final Collection<String> flowFileUuids, 
final AsyncLineageSubmission submission, final File indexDir) {
+        public ComputeLineageRunnable(final Collection<String> flowFileUuids, 
final NiFiUser user, final AsyncLineageSubmission submission, final File 
indexDir) {
             this.flowFileUuids = flowFileUuids;
+            this.user = user;
             this.submission = submission;
             this.indexDir = indexDir;
         }
@@ -2368,7 +2472,7 @@ public class PersistentProvenanceRepository implements 
ProvenanceEventRepository
                     indexManager, indexDir, null, flowFileUuids, 
maxAttributeChars);
 
                 final StandardLineageResult result = submission.getResult();
-                result.update(matchingRecords);
+                
result.update(replaceUnauthorizedWithPlaceholders(matchingRecords, user));
 
                 logger.info("Successfully created Lineage for FlowFiles with 
UUIDs {} in {} milliseconds; Lineage contains {} nodes and {} edges",
                         flowFileUuids, 
result.getComputationTime(TimeUnit.MILLISECONDS), result.getNodes().size(), 
result.getEdges().size());

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/authorization/AuthorizationCheck.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/authorization/AuthorizationCheck.java
 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/authorization/AuthorizationCheck.java
new file mode 100644
index 0000000..3627572
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/authorization/AuthorizationCheck.java
@@ -0,0 +1,24 @@
+/*
+ * 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.provenance.authorization;
+
+import org.apache.nifi.provenance.ProvenanceEventRecord;
+
+public interface AuthorizationCheck {
+    boolean isAuthorized(ProvenanceEventRecord event);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/DocsReader.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/DocsReader.java
 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/DocsReader.java
index b195559..e448f27 100644
--- 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/DocsReader.java
+++ 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/DocsReader.java
@@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.nifi.provenance.ProvenanceEventRecord;
 import org.apache.nifi.provenance.SearchableFields;
 import org.apache.nifi.provenance.StandardProvenanceEventRecord;
+import org.apache.nifi.provenance.authorization.AuthorizationCheck;
 import org.apache.nifi.provenance.serialization.RecordReader;
 import org.apache.nifi.provenance.serialization.RecordReaders;
 import org.apache.nifi.provenance.toc.TocReader;
@@ -47,7 +48,7 @@ import org.slf4j.LoggerFactory;
 class DocsReader {
     private final Logger logger = LoggerFactory.getLogger(DocsReader.class);
 
-    public Set<ProvenanceEventRecord> read(final TopDocs topDocs, final 
IndexReader indexReader, final Collection<Path> allProvenanceLogFiles,
+    public Set<ProvenanceEventRecord> read(final TopDocs topDocs, final 
AuthorizationCheck authCheck, final IndexReader indexReader, final 
Collection<Path> allProvenanceLogFiles,
             final AtomicInteger retrievalCount, final int maxResults, final 
int maxAttributeChars) throws IOException {
         if (retrievalCount.get() >= maxResults) {
             return Collections.emptySet();
@@ -65,7 +66,7 @@ class DocsReader {
 
         final long readDocuments = System.nanoTime() - start;
         logger.debug("Reading {} Lucene Documents took {} millis", 
docs.size(), TimeUnit.NANOSECONDS.toMillis(readDocuments));
-        return read(docs, allProvenanceLogFiles, retrievalCount, maxResults, 
maxAttributeChars);
+        return read(docs, authCheck, allProvenanceLogFiles, retrievalCount, 
maxResults, maxAttributeChars);
     }
 
 
@@ -104,7 +105,7 @@ class DocsReader {
         return record;
     }
 
-    public Set<ProvenanceEventRecord> read(final List<Document> docs, final 
Collection<Path> allProvenanceLogFiles,
+    public Set<ProvenanceEventRecord> read(final List<Document> docs, final 
AuthorizationCheck authCheck, final Collection<Path> allProvenanceLogFiles,
             final AtomicInteger retrievalCount, final int maxResults, final 
int maxAttributeChars) throws IOException {
 
         if (retrievalCount.get() >= maxResults) {
@@ -128,9 +129,9 @@ class DocsReader {
 
                     Iterator<Document> docIter = 
byStorageNameDocGroups.get(storageFileName).iterator();
                     while (docIter.hasNext() && 
retrievalCount.getAndIncrement() < maxResults) {
-                        ProvenanceEventRecord eRec = 
this.getRecord(docIter.next(), reader);
-                        if (eRec != null) {
-                            matchingRecords.add(eRec);
+                        ProvenanceEventRecord event = 
this.getRecord(docIter.next(), reader);
+                        if (event != null && authCheck.isAuthorized(event)) {
+                            matchingRecords.add(event);
                             eventsReadThisFile++;
                         }
                     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/IndexSearch.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/IndexSearch.java
 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/IndexSearch.java
index 65a06ac..00e5f38 100644
--- 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/IndexSearch.java
+++ 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/IndexSearch.java
@@ -28,9 +28,11 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TopDocs;
+import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.provenance.PersistentProvenanceRepository;
 import org.apache.nifi.provenance.ProvenanceEventRecord;
 import org.apache.nifi.provenance.StandardQueryResult;
+import org.apache.nifi.provenance.authorization.AuthorizationCheck;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,7 +50,8 @@ public class IndexSearch {
         this.maxAttributeChars = maxAttributeChars;
     }
 
-    public StandardQueryResult search(final 
org.apache.nifi.provenance.search.Query provenanceQuery, final AtomicInteger 
retrievedCount, final long firstEventTimestamp) throws IOException {
+    public StandardQueryResult search(final 
org.apache.nifi.provenance.search.Query provenanceQuery, final NiFiUser user, 
final AtomicInteger retrievedCount,
+        final long firstEventTimestamp) throws IOException {
         if (retrievedCount.get() >= provenanceQuery.getMaxResults()) {
             final StandardQueryResult sqr = new 
StandardQueryResult(provenanceQuery, 1);
             sqr.update(Collections.<ProvenanceEventRecord> emptyList(), 0L);
@@ -102,7 +105,10 @@ public class IndexSearch {
             }
 
             final DocsReader docsReader = new DocsReader();
-            matchingRecords = docsReader.read(topDocs, 
searcher.getIndexReader(), repository.getAllLogFiles(), retrievedCount,
+
+            final AuthorizationCheck authCheck = event -> 
repository.isAuthorized(event, user);
+
+            matchingRecords = docsReader.read(topDocs, authCheck, 
searcher.getIndexReader(), repository.getAllLogFiles(), retrievedCount,
                 provenanceQuery.getMaxResults(), maxAttributeChars);
 
             final long readRecordsNanos = System.nanoTime() - finishSearch;

http://git-wip-us.apache.org/repos/asf/nifi/blob/ae9e2fdf/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/LineageQuery.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/LineageQuery.java
 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/LineageQuery.java
index ce60e03..3a2d6e1 100644
--- 
a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/LineageQuery.java
+++ 
b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/lucene/LineageQuery.java
@@ -36,6 +36,7 @@ import org.apache.lucene.search.TopDocs;
 import org.apache.nifi.provenance.PersistentProvenanceRepository;
 import org.apache.nifi.provenance.ProvenanceEventRecord;
 import org.apache.nifi.provenance.SearchableFields;
+import org.apache.nifi.provenance.authorization.AuthorizationCheck;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -93,8 +94,12 @@ public class LineageQuery {
                 final TopDocs uuidQueryTopDocs = searcher.search(query, 
MAX_QUERY_RESULTS);
                 final long searchEnd = System.nanoTime();
 
+                // Always authorized. We do this because we need to pull back 
the event, regardless of whether or not
+                // the user is truly authorized, because instead of ignoring 
unauthorized events, we want to replace them.
+                final AuthorizationCheck authCheck = event -> true;
+
                 final DocsReader docsReader = new DocsReader();
-                final Set<ProvenanceEventRecord> recs = 
docsReader.read(uuidQueryTopDocs, searcher.getIndexReader(), 
repo.getAllLogFiles(),
+                final Set<ProvenanceEventRecord> recs = 
docsReader.read(uuidQueryTopDocs, authCheck, searcher.getIndexReader(), 
repo.getAllLogFiles(),
                     new AtomicInteger(0), Integer.MAX_VALUE, 
maxAttributeChars);
 
                 final long readDocsEnd = System.nanoTime();

Reply via email to