You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2016/07/14 22:33:11 UTC

[05/10] nifi git commit: NIFI-1896 This closes #650. Refactored nifi-api into nifi-framework-api and other locations. The nifi-api is specific to that which is needed for intended extension points.

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java b/nifi-framework-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java
new file mode 100644
index 0000000..1e12146
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.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.authentication.exception;
+
+/**
+ * Represents the exceptional case when an AuthorityProvider fails destruction.
+ *
+ */
+public class ProviderDestructionException extends RuntimeException {
+
+    public ProviderDestructionException() {
+    }
+
+    public ProviderDestructionException(String msg) {
+        super(msg);
+    }
+
+    public ProviderDestructionException(Throwable cause) {
+        super(cause);
+    }
+
+    public ProviderDestructionException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
new file mode 100644
index 0000000..8fbe0fb
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
@@ -0,0 +1,552 @@
+/*
+ * 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;
+
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * An Authorizer that provides management of users, groups, and policies.
+ */
+public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
+
+    static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
+    static final XMLOutputFactory XML_OUTPUT_FACTORY = XMLOutputFactory.newInstance();
+
+    static final String USER_ELEMENT = "user";
+    static final String GROUP_USER_ELEMENT = "groupUser";
+    static final String GROUP_ELEMENT = "group";
+    static final String POLICY_ELEMENT = "policy";
+    static final String POLICY_USER_ELEMENT = "policyUser";
+    static final String POLICY_GROUP_ELEMENT = "policyGroup";
+    static final String IDENTIFIER_ATTR = "identifier";
+    static final String IDENTITY_ATTR = "identity";
+    static final String NAME_ATTR = "name";
+    static final String RESOURCE_ATTR = "resource";
+    static final String ACTIONS_ATTR = "actions";
+
+    public static final String EMPTY_FINGERPRINT = "EMPTY";
+
+    @Override
+    public final void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+        doOnConfigured(configurationContext);
+
+        // ensure that only one policy per resource-action exists
+        for (AccessPolicy accessPolicy : getAccessPolicies()) {
+            if (policyExists(accessPolicy)) {
+                throw new AuthorizerCreationException("Found multiple policies for " + accessPolicy.getResource()
+                        + " with " + accessPolicy.getAction());
+            }
+        }
+    }
+
+    /**
+     * Allows sub-classes to take action when onConfigured is called.
+     *
+     * @param configurationContext the configuration context
+     * @throws AuthorizerCreationException if an error occurs during onConfigured process
+     */
+    protected abstract void doOnConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException;
+
+    /**
+     * Checks if another policy exists with the same resource and action as the given policy.
+     *
+     * @param checkAccessPolicy an access policy being checked
+     * @return true if another access policy exists with the same resource and action, false otherwise
+     */
+    private boolean policyExists(final AccessPolicy checkAccessPolicy) {
+        for (AccessPolicy accessPolicy : getAccessPolicies()) {
+            if (!accessPolicy.getIdentifier().equals(checkAccessPolicy.getIdentifier())
+                    && accessPolicy.getResource().equals(checkAccessPolicy.getResource())
+                    && accessPolicy.getAction().equals(checkAccessPolicy.getAction())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public final AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException {
+        final UsersAndAccessPolicies usersAndAccessPolicies = getUsersAndAccessPolicies();
+        final String resourceIdentifier = request.getResource().getIdentifier();
+
+        final AccessPolicy policy = usersAndAccessPolicies.getAccessPolicy(resourceIdentifier, request.getAction());
+        if (policy == null) {
+            return AuthorizationResult.resourceNotFound();
+        }
+
+        final User user = usersAndAccessPolicies.getUser(request.getIdentity());
+        if (user == null) {
+            return AuthorizationResult.denied("Unknown user with identity " + request.getIdentity());
+        }
+
+        final Set<Group> userGroups = usersAndAccessPolicies.getGroups(user.getIdentity());
+        if (policy.getUsers().contains(user.getIdentifier()) || containsGroup(userGroups, policy)) {
+            return AuthorizationResult.approved();
+        }
+
+
+        return AuthorizationResult.denied();
+    }
+
+    /**
+     * Determines if the policy contains one of the user's groups.
+     *
+     * @param userGroups the set of the user's groups
+     * @param policy the policy
+     * @return true if one of the Groups in userGroups is contained in the policy
+     */
+    private boolean containsGroup(final Set<Group> userGroups, final AccessPolicy policy) {
+        if (userGroups.isEmpty() || policy.getGroups().isEmpty()) {
+            return false;
+        }
+
+        for (Group userGroup : userGroups) {
+            if (policy.getGroups().contains(userGroup.getIdentifier())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Adds a new group.
+     *
+     * @param group the Group to add
+     * @return the added Group
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Group addGroup(Group group) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves a Group by id.
+     *
+     * @param identifier the identifier of the Group to retrieve
+     * @return the Group with the given identifier, or null if no matching group was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Group getGroup(String identifier) throws AuthorizationAccessException;
+
+    /**
+     * The group represented by the provided instance will be updated based on the provided instance.
+     *
+     * @param group an updated group instance
+     * @return the updated group instance, or null if no matching group was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Group updateGroup(Group group) throws AuthorizationAccessException;
+
+    /**
+     * Deletes the given group.
+     *
+     * @param group the group to delete
+     * @return the deleted group, or null if no matching group was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Group deleteGroup(Group group) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves all groups.
+     *
+     * @return a list of groups
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Set<Group> getGroups() throws AuthorizationAccessException;
+
+
+    /**
+     * Adds the given user.
+     *
+     * @param user the user to add
+     * @return the user that was added
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract User addUser(User user) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves the user with the given identifier.
+     *
+     * @param identifier the id of the user to retrieve
+     * @return the user with the given id, or null if no matching user was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract User getUser(String identifier) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves the user with the given identity.
+     *
+     * @param identity the identity of the user to retrieve
+     * @return the user with the given identity, or null if no matching user was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract User getUserByIdentity(String identity) throws AuthorizationAccessException;
+
+    /**
+     * The user represented by the provided instance will be updated based on the provided instance.
+     *
+     * @param user an updated user instance
+     * @return the updated user instance, or null if no matching user was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract User updateUser(User user) throws AuthorizationAccessException;
+
+    /**
+     * Deletes the given user.
+     *
+     * @param user the user to delete
+     * @return the user that was deleted, or null if no matching user was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract User deleteUser(User user) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves all users.
+     *
+     * @return a list of users
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Set<User> getUsers() throws AuthorizationAccessException;
+
+    /**
+     * Adds the given policy ensuring that multiple policies can not be added for the same resource and action.
+     *
+     * @param accessPolicy the policy to add
+     * @return the policy that was added
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public final synchronized AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+        if (policyExists(accessPolicy)) {
+            throw new IllegalStateException("Found multiple policies for " + accessPolicy.getResource()
+                    + " with " + accessPolicy.getAction());
+        }
+        return doAddAccessPolicy(accessPolicy);
+    }
+
+    /**
+     * Adds the given policy.
+     *
+     * @param accessPolicy the policy to add
+     * @return the policy that was added
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    protected abstract AccessPolicy doAddAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves the policy with the given identifier.
+     *
+     * @param identifier the id of the policy to retrieve
+     * @return the policy with the given id, or null if no matching policy exists
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException;
+
+    /**
+     * The policy represented by the provided instance will be updated based on the provided instance.
+     *
+     * @param accessPolicy an updated policy
+     * @return the updated policy, or null if no matching policy was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException;
+
+    /**
+     * Deletes the given policy.
+     *
+     * @param policy the policy to delete
+     * @return the deleted policy, or null if no matching policy was found
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract AccessPolicy deleteAccessPolicy(AccessPolicy policy) throws AuthorizationAccessException;
+
+    /**
+     * Retrieves all access policies.
+     *
+     * @return a list of policies
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException;
+
+    /**
+     * Returns the UserAccessPolicies instance.
+     *
+     * @return the UserAccessPolicies instance
+     * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+     */
+    public abstract UsersAndAccessPolicies getUsersAndAccessPolicies() throws AuthorizationAccessException;
+
+    /**
+     * Parses the fingerprint and adds any users, groups, and policies to the current Authorizer.
+     *
+     * @param fingerprint the fingerprint that was obtained from calling getFingerprint() on another Authorizer.
+     */
+    public final void inheritFingerprint(final String fingerprint) throws AuthorizationAccessException {
+        if (fingerprint == null || fingerprint.trim().isEmpty()) {
+            return;
+        }
+
+        final byte[] fingerprintBytes = fingerprint.getBytes(StandardCharsets.UTF_8);
+
+        try (final ByteArrayInputStream in = new ByteArrayInputStream(fingerprintBytes)) {
+            final DocumentBuilder docBuilder = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
+            final Document document = docBuilder.parse(in);
+            final Element rootElement = document.getDocumentElement();
+
+            // parse all the users and add them to the current authorizer
+            NodeList userNodes = rootElement.getElementsByTagName(USER_ELEMENT);
+            for (int i=0; i < userNodes.getLength(); i++) {
+                Node userNode = userNodes.item(i);
+                User user = parseUser((Element) userNode);
+                addUser(user);
+            }
+
+            // parse all the groups and add them to the current authorizer
+            NodeList groupNodes = rootElement.getElementsByTagName(GROUP_ELEMENT);
+            for (int i=0; i < groupNodes.getLength(); i++) {
+                Node groupNode = groupNodes.item(i);
+                Group group = parseGroup((Element) groupNode);
+                addGroup(group);
+            }
+
+            // parse all the policies and add them to the current authorizer
+            NodeList policyNodes = rootElement.getElementsByTagName(POLICY_ELEMENT);
+            for (int i=0; i < policyNodes.getLength(); i++) {
+                Node policyNode = policyNodes.item(i);
+                AccessPolicy policy = parsePolicy((Element) policyNode);
+                addAccessPolicy(policy);
+            }
+
+        } catch (SAXException | ParserConfigurationException | IOException e) {
+            throw new AuthorizationAccessException("Unable to parse fingerprint", e);
+        }
+    }
+
+    private User parseUser(final Element element) {
+        final User.Builder builder = new User.Builder()
+                .identifier(element.getAttribute(IDENTIFIER_ATTR))
+                .identity(element.getAttribute(IDENTITY_ATTR));
+
+        return builder.build();
+    }
+
+    private Group parseGroup(final Element element) {
+        final Group.Builder builder = new Group.Builder()
+                .identifier(element.getAttribute(IDENTIFIER_ATTR))
+                .name(element.getAttribute(NAME_ATTR));
+
+        NodeList groupUsers = element.getElementsByTagName(GROUP_USER_ELEMENT);
+        for (int i=0; i < groupUsers.getLength(); i++) {
+            Element groupUserNode = (Element) groupUsers.item(i);
+            builder.addUser(groupUserNode.getAttribute(IDENTIFIER_ATTR));
+        }
+
+        return builder.build();
+    }
+
+    private AccessPolicy parsePolicy(final Element element) {
+        final AccessPolicy.Builder builder = new AccessPolicy.Builder()
+                .identifier(element.getAttribute(IDENTIFIER_ATTR))
+                .resource(element.getAttribute(RESOURCE_ATTR));
+
+        final String actions = element.getAttribute(ACTIONS_ATTR);
+        if (actions.equals(RequestAction.READ.name())) {
+            builder.action(RequestAction.READ);
+        } else if (actions.equals(RequestAction.WRITE.name())) {
+            builder.action(RequestAction.WRITE);
+        } else {
+            throw new IllegalStateException("Unknown Policy Action: " + actions);
+        }
+
+        NodeList policyUsers = element.getElementsByTagName(POLICY_USER_ELEMENT);
+        for (int i=0; i < policyUsers.getLength(); i++) {
+            Element policyUserNode = (Element) policyUsers.item(i);
+            builder.addUser(policyUserNode.getAttribute(IDENTIFIER_ATTR));
+        }
+
+        NodeList policyGroups = element.getElementsByTagName(POLICY_GROUP_ELEMENT);
+        for (int i=0; i < policyGroups.getLength(); i++) {
+            Element policyGroupNode = (Element) policyGroups.item(i);
+            builder.addGroup(policyGroupNode.getAttribute(IDENTIFIER_ATTR));
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Returns a fingerprint representing the authorizations managed by this authorizer. The fingerprint will be
+     * used for comparison to determine if two policy-based authorizers represent a compatible set of users,
+     * groups, and policies.
+     *
+     * @return the fingerprint for this Authorizer
+     */
+    public final String getFingerprint() throws AuthorizationAccessException {
+        final List<User> users = getSortedUsers();
+        final List<Group> groups = getSortedGroups();
+        final List<AccessPolicy> policies = getSortedAccessPolicies();
+
+        // when there are no users, groups, policies we want to always return a simple indicator so
+        // it can easily be determined when comparing fingerprints
+        if (users.isEmpty() && groups.isEmpty() && policies.isEmpty()) {
+            return EMPTY_FINGERPRINT;
+        }
+
+        XMLStreamWriter writer = null;
+        final StringWriter out = new StringWriter();
+        try {
+            writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
+            writer.writeStartDocument();
+            writer.writeStartElement("authorizations");
+
+            for (User user : users) {
+                writeUser(writer, user);
+            }
+            for (Group group : groups) {
+                writeGroup(writer, group);
+            }
+            for (AccessPolicy policy : policies) {
+                writePolicy(writer, policy);
+            }
+
+            writer.writeEndElement();
+            writer.writeEndDocument();
+            writer.flush();
+        } catch (XMLStreamException e) {
+            throw new AuthorizationAccessException("Unable to generate fingerprint", e);
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (XMLStreamException e) {
+                    // nothing to do here
+                }
+            }
+        }
+
+        return out.toString();
+    }
+
+    private void writeUser(final XMLStreamWriter writer, final User user) throws XMLStreamException {
+        writer.writeStartElement(USER_ELEMENT);
+        writer.writeAttribute(IDENTIFIER_ATTR, user.getIdentifier());
+        writer.writeAttribute(IDENTITY_ATTR, user.getIdentity());
+        writer.writeEndElement();
+    }
+
+    private void writeGroup(final XMLStreamWriter writer, final Group group) throws XMLStreamException {
+        List<String> users = new ArrayList<>(group.getUsers());
+        Collections.sort(users);
+
+        writer.writeStartElement(GROUP_ELEMENT);
+        writer.writeAttribute(IDENTIFIER_ATTR, group.getIdentifier());
+        writer.writeAttribute(NAME_ATTR, group.getName());
+
+        for (String user : users) {
+            writer.writeStartElement(GROUP_USER_ELEMENT);
+            writer.writeAttribute(IDENTIFIER_ATTR, user);
+            writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
+    }
+
+    private void writePolicy(final XMLStreamWriter writer, final AccessPolicy policy) throws XMLStreamException {
+        // sort the users for the policy
+        List<String> policyUsers = new ArrayList<>(policy.getUsers());
+        Collections.sort(policyUsers);
+
+        // sort the groups for this policy
+        List<String> policyGroups = new ArrayList<>(policy.getGroups());
+        Collections.sort(policyGroups);
+
+        writer.writeStartElement(POLICY_ELEMENT);
+        writer.writeAttribute(IDENTIFIER_ATTR, policy.getIdentifier());
+        writer.writeAttribute(RESOURCE_ATTR, policy.getResource());
+        writer.writeAttribute(ACTIONS_ATTR, policy.getAction().name());
+
+        for (String policyUser : policyUsers) {
+            writer.writeStartElement(POLICY_USER_ELEMENT);
+            writer.writeAttribute(IDENTIFIER_ATTR, policyUser);
+            writer.writeEndElement();
+        }
+
+        for (String policyGroup : policyGroups) {
+            writer.writeStartElement(POLICY_GROUP_ELEMENT);
+            writer.writeAttribute(IDENTIFIER_ATTR, policyGroup);
+            writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
+    }
+
+    private List<AccessPolicy> getSortedAccessPolicies() {
+        final List<AccessPolicy> policies = new ArrayList<>(getAccessPolicies());
+
+        Collections.sort(policies, new Comparator<AccessPolicy>() {
+            @Override
+            public int compare(AccessPolicy p1, AccessPolicy p2) {
+                return p1.getIdentifier().compareTo(p2.getIdentifier());
+            }
+        });
+        return policies;
+    }
+
+    private List<Group> getSortedGroups() {
+        final List<Group> groups = new ArrayList<>(getGroups());
+
+        Collections.sort(groups, new Comparator<Group>() {
+            @Override
+            public int compare(Group g1, Group g2) {
+                return g1.getIdentifier().compareTo(g2.getIdentifier());
+            }
+        });
+        return groups;
+    }
+
+    private List<User> getSortedUsers() {
+        final List<User> users = new ArrayList<>(getUsers());
+
+        Collections.sort(users, new Comparator<User>() {
+            @Override
+            public int compare(User u1, User u2) {
+                return u1.getIdentifier().compareTo(u2.getIdentifier());
+            }
+        });
+        return users;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessDeniedException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessDeniedException.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessDeniedException.java
new file mode 100644
index 0000000..8712d28
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessDeniedException.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;
+
+/**
+ * Represents any error that might occur while authorizing user requests.
+ */
+public class AccessDeniedException extends RuntimeException {
+    private static final long serialVersionUID = -5683444815269084134L;
+
+    public AccessDeniedException(Throwable cause) {
+        super(cause);
+    }
+
+    public AccessDeniedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AccessDeniedException(String message) {
+        super(message);
+    }
+
+    public AccessDeniedException() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
new file mode 100644
index 0000000..93cabb2
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
@@ -0,0 +1,330 @@
+/*
+ * 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;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Defines a policy for a set of userIdentifiers to perform a set of actions on a given resource.
+ */
+public class AccessPolicy {
+
+    private final String identifier;
+
+    private final String resource;
+
+    private final Set<String> users;
+
+    private final Set<String> groups;
+
+    private final RequestAction action;
+
+    private AccessPolicy(final Builder builder) {
+        this.identifier = builder.identifier;
+        this.resource = builder.resource;
+        this.action = builder.action;
+        this.users = Collections.unmodifiableSet(new HashSet<>(builder.users));
+        this.groups = Collections.unmodifiableSet(new HashSet<>(builder.groups));
+
+        if (this.identifier == null || this.identifier.trim().isEmpty()) {
+            throw new IllegalArgumentException("Identifier can not be null or empty");
+        }
+
+        if (this.resource == null) {
+            throw new IllegalArgumentException("Resource can not be null");
+        }
+
+        if (this.action == null) {
+            throw new IllegalArgumentException("Action can not be null");
+        }
+    }
+
+    /**
+     * @return the identifier for this policy
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @return the resource for this policy
+     */
+    public String getResource() {
+        return resource;
+    }
+
+    /**
+     * @return an unmodifiable set of user ids for this policy
+     */
+    public Set<String> getUsers() {
+        return users;
+    }
+
+    /**
+     * @return an unmodifiable set of group ids for this policy
+     */
+    public Set<String> getGroups() {
+        return groups;
+    }
+
+    /**
+     * @return the action for this policy
+     */
+    public RequestAction getAction() {
+        return action;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final AccessPolicy other = (AccessPolicy) obj;
+        return Objects.equals(this.identifier, other.identifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.identifier);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("identifier[%s], resource[%s], users[%s], groups[%s], action[%s]",
+                getIdentifier(), getResource(), getUsers(), getGroups(), getAction());
+    }
+
+    /**
+     * Builder for Access Policies.
+     */
+    public static class Builder {
+
+        private String identifier;
+        private String resource;
+        private RequestAction action;
+        private Set<String> users = new HashSet<>();
+        private Set<String> groups = new HashSet<>();
+        private final boolean fromPolicy;
+
+        /**
+         * Default constructor for building a new AccessPolicy.
+         */
+        public Builder() {
+            this.fromPolicy = false;
+        }
+
+        /**
+         * Initializes the builder with the state of the provided policy. When using this constructor
+         * the identifier field of the builder can not be changed and will result in an IllegalStateException
+         * if attempting to do so.
+         *
+         * @param other the existing access policy to initialize from
+         */
+        public Builder(final AccessPolicy other) {
+            if (other == null) {
+                throw new IllegalArgumentException("Can not initialize builder with a null access policy");
+            }
+
+            this.identifier = other.getIdentifier();
+            this.resource = other.getResource();
+            this.action = other.getAction();
+            this.users.clear();
+            this.users.addAll(other.getUsers());
+            this.groups.clear();
+            this.groups.addAll(other.getGroups());
+            this.fromPolicy = true;
+        }
+
+        /**
+         * Sets the identifier of the builder.
+         *
+         * @param identifier the identifier to set
+         * @return the builder
+         * @throws IllegalStateException if this method is called when this builder was constructed from an existing Policy
+         */
+        public Builder identifier(final String identifier) {
+            if (fromPolicy) {
+                throw new IllegalStateException(
+                        "Identifier can not be changed when initialized from an existing policy");
+            }
+
+            this.identifier = identifier;
+            return this;
+        }
+
+        /**
+         * Sets the resource of the builder.
+         *
+         * @param resource the resource to set
+         * @return the builder
+         */
+        public Builder resource(final String resource) {
+            this.resource = resource;
+            return this;
+        }
+
+        /**
+         * Adds all the users from the provided set to the builder's set of users.
+         *
+         * @param users the users to add
+         * @return the builder
+         */
+        public Builder addUsers(final Set<String> users) {
+            if (users != null) {
+                this.users.addAll(users);
+            }
+            return this;
+        }
+
+        /**
+         * Adds the given user to the builder's set of users.
+         *
+         * @param user the user to add
+         * @return the builder
+         */
+        public Builder addUser(final String user) {
+            if (user != null) {
+                this.users.add(user);
+            }
+            return this;
+        }
+
+        /**
+         * Removes all users in the provided set from the builder's set of users.
+         *
+         * @param users the users to remove
+         * @return the builder
+         */
+        public Builder removeUsers(final Set<String> users) {
+            if (users != null) {
+                this.users.removeAll(users);
+            }
+            return this;
+        }
+
+        /**
+         * Removes the provided user from the builder's set of users.
+         *
+         * @param user the user to remove
+         * @return the builder
+         */
+        public Builder removeUser(final String user) {
+            if (user != null) {
+                this.users.remove(user);
+            }
+            return this;
+        }
+
+        /**
+         * Clears the builder's set of users so that it is non-null and size == 0.
+         *
+         * @return the builder
+         */
+        public Builder clearUsers() {
+            this.users.clear();
+            return this;
+        }
+
+        /**
+         * Adds all the groups from the provided set to the builder's set of groups.
+         *
+         * @param groups the groups to add
+         * @return the builder
+         */
+        public Builder addGroups(final Set<String> groups) {
+            if (groups != null) {
+                this.groups.addAll(groups);
+            }
+            return this;
+        }
+
+        /**
+         * Adds the given group to the builder's set of groups.
+         *
+         * @param group the group to add
+         * @return the builder
+         */
+        public Builder addGroup(final String group) {
+            if (group != null) {
+                this.groups.add(group);
+            }
+            return this;
+        }
+
+        /**
+         * Removes all groups in the provided set from the builder's set of groups.
+         *
+         * @param groups the groups to remove
+         * @return the builder
+         */
+        public Builder removeGroups(final Set<String> groups) {
+            if (groups != null) {
+                this.groups.removeAll(groups);
+            }
+            return this;
+        }
+
+        /**
+         * Removes the provided groups from the builder's set of groups.
+         *
+         * @param group the group to remove
+         * @return the builder
+         */
+        public Builder removeGroup(final String group) {
+            if (group != null) {
+                this.groups.remove(group);
+            }
+            return this;
+        }
+
+        /**
+         * Clears the builder's set of groups so that it is non-null and size == 0.
+         *
+         * @return the builder
+         */
+        public Builder clearGroups() {
+            this.groups.clear();
+            return this;
+        }
+
+        /**
+         * Sets the action for this builder.
+         *
+         * @param action the action to set
+         * @return the builder
+         */
+        public Builder action(final RequestAction action) {
+            this.action = action;
+            return this;
+        }
+
+        /**
+         * @return a new AccessPolicy constructed from the state of the builder
+         */
+        public AccessPolicy build() {
+            return new AccessPolicy(this);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
new file mode 100644
index 0000000..da0a276
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
@@ -0,0 +1,171 @@
+/*
+ * 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;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Represents an authorization request for a given user/entity performing an action against a resource within some userContext.
+ */
+public class AuthorizationRequest {
+
+    private final Resource resource;
+    private final String identity;
+    private final RequestAction action;
+    private final boolean isAccessAttempt;
+    private final boolean isAnonymous;
+    private final Map<String, String> userContext;
+    private final Map<String, String> resourceContext;
+
+    private AuthorizationRequest(final Builder builder) {
+        Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
+        Objects.requireNonNull(builder.action, "The action is required when creating an authorization request");
+        Objects.requireNonNull(builder.isAccessAttempt, "Whether this request is an access attempt is request");
+        Objects.requireNonNull(builder.isAnonymous, "Whether this request is being performed by an anonymous user is required");
+
+        this.resource = builder.resource;
+        this.identity = builder.identity;
+        this.action = builder.action;
+        this.isAccessAttempt = builder.isAccessAttempt;
+        this.isAnonymous = builder.isAnonymous;
+        this.userContext = builder.userContext == null ? null : Collections.unmodifiableMap(builder.userContext);
+        this.resourceContext = builder.resourceContext == null ? null : Collections.unmodifiableMap(builder.resourceContext);
+    }
+
+    /**
+     * The Resource being authorized. Not null.
+     *
+     * @return The resource
+     */
+    public Resource getResource() {
+        return resource;
+    }
+
+    /**
+     * The identity accessing the Resource. May be null if the user could not authenticate.
+     *
+     * @return The identity
+     */
+    public String getIdentity() {
+        return identity;
+    }
+
+    /**
+     * Whether this is a direct access attempt of the Resource if if it's being checked as part of another response.
+     *
+     * @return if this is a direct access attempt
+     */
+    public boolean isAccessAttempt() {
+        return isAccessAttempt;
+    }
+
+    /**
+     * Whether the entity accessing is anonymous.
+     *
+     * @return whether the entity is anonymous
+     */
+    public boolean isAnonymous() {
+        return isAnonymous;
+    }
+
+    /**
+     * The action being taken against the Resource. Not null.
+     *
+     * @return The action
+     */
+    public RequestAction getAction() {
+        return action;
+    }
+
+    /**
+     * The userContext of the user request to make additional access decisions. May be null.
+     *
+     * @return  The userContext of the user request
+     */
+    public Map<String, String> getUserContext() {
+        return userContext;
+    }
+
+    /**
+     * The event attributes to make additional access decisions for provenance events. May be null.
+     *
+     * @return  The event attributes
+     */
+    public Map<String, String> getResourceContext() {
+        return resourceContext;
+    }
+
+    /**
+     * AuthorizationRequest builder.
+     */
+    public static final class Builder {
+
+        private Resource resource;
+        private String identity;
+        private Boolean isAnonymous;
+        private Boolean isAccessAttempt;
+        private RequestAction action;
+        private Map<String, String> userContext;
+        private Map<String, String> resourceContext;
+
+        public Builder resource(final Resource resource) {
+            this.resource = resource;
+            return this;
+        }
+
+        public Builder identity(final String identity) {
+            this.identity = identity;
+            return this;
+        }
+
+        public Builder anonymous(final Boolean isAnonymous) {
+            this.isAnonymous = isAnonymous;
+            return this;
+        }
+
+        public Builder accessAttempt(final Boolean isAccessAttempt) {
+            this.isAccessAttempt = isAccessAttempt;
+            return this;
+        }
+
+        public Builder action(final RequestAction action) {
+            this.action = action;
+            return this;
+        }
+
+        public Builder userContext(final Map<String, String> userContext) {
+            if (userContext != null) {
+                this.userContext = new HashMap<>(userContext);
+            }
+            return this;
+        }
+
+        public Builder resourceContext(final Map<String, String> resourceContext) {
+            if (resourceContext != null) {
+                this.resourceContext = new HashMap<>(resourceContext);
+            }
+            return this;
+        }
+
+        public AuthorizationRequest build() {
+            return new AuthorizationRequest(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
new file mode 100644
index 0000000..a3f520c
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
@@ -0,0 +1,99 @@
+/*
+ * 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;
+
+/**
+ * Represents a decision whether authorization is granted.
+ */
+public class AuthorizationResult {
+
+    public enum Result {
+        Approved,
+        Denied,
+        ResourceNotFound
+    }
+
+    private static final AuthorizationResult APPROVED = new AuthorizationResult(Result.Approved, null);
+    private static final AuthorizationResult RESOURCE_NOT_FOUND = new AuthorizationResult(Result.ResourceNotFound, null);
+
+    private final Result result;
+    private final String explanation;
+
+    /**
+     * Creates a new AuthorizationResult with the specified result and explanation.
+     *
+     * @param result of the authorization
+     * @param explanation for the authorization attempt
+     */
+    private AuthorizationResult(Result result, String explanation) {
+        if (Result.Denied.equals(result) && explanation == null) {
+            throw new IllegalArgumentException("An explanation is required when the authorization request is denied.");
+        }
+
+        this.result = result;
+        this.explanation = explanation;
+    }
+
+    /**
+     * @return Whether or not the request is approved
+     */
+    public Result getResult() {
+        return result;
+    }
+
+    /**
+     * @return If the request is denied, the reason why. Null otherwise
+     */
+    public String getExplanation() {
+        return explanation;
+    }
+
+    /**
+     * @return a new approved AuthorizationResult
+     */
+    public static AuthorizationResult approved() {
+        return APPROVED;
+    }
+
+    /**
+     * Resource not found will indicate that there are no specific authorization rules for this resource.
+     * @return a new resource not found AuthorizationResult
+     */
+    public static AuthorizationResult resourceNotFound() {
+        return RESOURCE_NOT_FOUND;
+    }
+
+    /**
+     * Creates a new denied AuthorizationResult with a message indicating 'Access is denied'.
+     *
+     * @return a new denied AuthorizationResult
+     */
+    public static AuthorizationResult denied() {
+        return denied("Access is denied");
+    }
+
+    /**
+     * Creates a new denied AuthorizationResult with the specified explanation.
+     *
+     * @param explanation for why it was denied
+     * @return a new denied AuthorizationResult with the specified explanation
+     * @throws IllegalArgumentException if explanation is null
+     */
+    public static AuthorizationResult denied(String explanation) {
+        return new AuthorizationResult(Result.Denied, explanation);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Authorizer.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
new file mode 100644
index 0000000..cb8c7f1
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+
+/**
+ * Authorizes user requests.
+ */
+public interface Authorizer {
+
+    /**
+     * Determines if the specified user/entity is authorized to access the specified resource within the given context.
+     *
+     * @param   request The authorization request
+     * @return  the authorization result
+     * @throws  AuthorizationAccessException if unable to access the policies
+     */
+    AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException;
+
+    /**
+     * Called immediately after instance creation for implementers to perform additional setup
+     *
+     * @param initializationContext in which to initialize
+     */
+    void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException;
+
+    /**
+     * Called to configure the Authorizer.
+     *
+     * @param configurationContext at the time of configuration
+     * @throws AuthorizerCreationException for any issues configuring the provider
+     */
+    void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException;
+
+    /**
+     * Called immediately before instance destruction for implementers to release resources.
+     *
+     * @throws AuthorizerDestructionException If pre-destruction fails.
+     */
+    void preDestruction() throws AuthorizerDestructionException;
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
new file mode 100644
index 0000000..3721ab4
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import org.apache.nifi.components.PropertyValue;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface AuthorizerConfigurationContext {
+
+    /**
+     * @return identifier for the authorizer
+     */
+    String getIdentifier();
+
+    /**
+     * Retrieves all properties the component currently understands regardless
+     * of whether a value has been set for them or not. If no value is present
+     * then its value is null and thus any registered default for the property
+     * descriptor applies.
+     *
+     * @return Map of all properties
+     */
+    Map<String, String> getProperties();
+
+    /**
+     * @param property to lookup the descriptor and value of
+     * @return the value the component currently understands for the given
+     * PropertyDescriptor. This method does not substitute default
+     * PropertyDescriptor values, so the value returned will be null if not set
+     */
+    PropertyValue getProperty(String property);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java
new file mode 100644
index 0000000..4b3d77c
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * Initialization content for Authorizers.
+ */
+public interface AuthorizerInitializationContext {
+
+    /**
+     * The identifier of the Authorizer.
+     *
+     * @return  The identifier
+     */
+    public String getIdentifier();
+
+    /**
+     * The lookup for accessing other configured Authorizers.
+     *
+     * @return  The Authorizer lookup
+     */
+    public AuthorizerLookup getAuthorizerLookup();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java
new file mode 100644
index 0000000..9669976
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ *
+ */
+public interface AuthorizerLookup {
+
+    /**
+     * Looks up the Authorizer with the specified identifier
+     *
+     * @param identifier        The identifier of the Authorizer
+     * @return                  The Authorizer
+     */
+    Authorizer getAuthorizer(String identifier);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Group.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Group.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Group.java
new file mode 100644
index 0000000..7db619a
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Group.java
@@ -0,0 +1,226 @@
+/*
+ * 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;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A group that users can belong to.
+ */
+public class Group { // TODO rename to UserGroup
+
+    private final String identifier;
+
+    private final String name;
+
+    private final Set<String> users;
+
+    private Group(final Builder builder) {
+        this.identifier = builder.identifier;
+        this.name = builder.name;
+        this.users = Collections.unmodifiableSet(new HashSet<>(builder.users));
+
+        if (this.identifier == null || this.identifier.trim().isEmpty()) {
+            throw new IllegalArgumentException("Identifier can not be null or empty");
+        }
+
+        if (this.name == null || this.name.trim().isEmpty()) {
+            throw new IllegalArgumentException("Name can not be null or empty");
+        }
+    }
+
+    /**
+     * @return the identifier of the group
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @return the name of the group
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return an unmodifiable set of user identifiers that belong to this group
+     */
+    public Set<String> getUsers() {
+        return users;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final Group other = (Group) obj;
+        return Objects.equals(this.identifier, other.identifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.identifier);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("identifier[%s], name[%s]", getIdentifier(), getName());
+    }
+
+
+    /**
+     * Builder for creating Groups.
+     */
+    public static class Builder {
+
+        private String identifier;
+        private String name;
+        private Set<String> users = new HashSet<>();
+        private final boolean fromGroup;
+
+        public Builder() {
+            this.fromGroup = false;
+        }
+
+        /**
+         * Initializes the builder with the state of the provided group. When using this constructor
+         * the identifier field of the builder can not be changed and will result in an IllegalStateException
+         * if attempting to do so.
+         *
+         * @param other the existing access policy to initialize from
+         */
+        public Builder(final Group other) {
+            if (other == null) {
+                throw new IllegalArgumentException("Provided group can not be null");
+            }
+
+            this.identifier = other.getIdentifier();
+            this.name = other.getName();
+            this.users.clear();
+            this.users.addAll(other.getUsers());
+            this.fromGroup = true;
+        }
+
+        /**
+         * Sets the identifier of the builder.
+         *
+         * @param identifier the identifier
+         * @return the builder
+         * @throws IllegalStateException if this method is called when this builder was constructed from an existing Group
+         */
+        public Builder identifier(final String identifier) {
+            if (fromGroup) {
+                throw new IllegalStateException(
+                        "Identifier can not be changed when initialized from an existing group");
+            }
+
+            this.identifier = identifier;
+            return this;
+        }
+
+        /**
+         * Sets the name of the builder.
+         *
+         * @param name the name
+         * @return the builder
+         */
+        public Builder name(final String name) {
+            this.name = name;
+            return this;
+        }
+
+        /**
+         * Adds all users from the provided set to the builder's set of users.
+         *
+         * @param users a set of users to add
+         * @return the builder
+         */
+        public Builder addUsers(final Set<String> users) {
+            if (users != null) {
+                this.users.addAll(users);
+            }
+            return this;
+        }
+
+        /**
+         * Adds the given user to the builder's set of users.
+         *
+         * @param user the user to add
+         * @return the builder
+         */
+        public Builder addUser(final String user) {
+            if (user != null) {
+                this.users.add(user);
+            }
+            return this;
+        }
+
+        /**
+         * Removes the given user from the builder's set of users.
+         *
+         * @param user the user to remove
+         * @return the builder
+         */
+        public Builder removeUser(final String user) {
+            if (user != null) {
+                this.users.remove(user);
+            }
+            return this;
+        }
+
+        /**
+         * Removes all users from the provided set from the builder's set of users.
+         *
+         * @param users the users to remove
+         * @return the builder
+         */
+        public Builder removeUsers(final Set<String> users) {
+            if (users != null) {
+                this.users.removeAll(users);
+            }
+            return this;
+        }
+
+        /**
+         * Clears the builder's set of users so that users is non-null with size 0.
+         *
+         * @return the builder
+         */
+        public Builder clearUsers() {
+            this.users.clear();
+            return this;
+        }
+
+        /**
+         * @return a new Group constructed from the state of the builder
+         */
+        public Group build() {
+            return new Group(this);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/RequestAction.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/RequestAction.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/RequestAction.java
new file mode 100644
index 0000000..3e28a67
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/RequestAction.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * Actions a user/entity can take on a resource.
+ */
+public enum RequestAction {
+    READ("read"),
+    WRITE("write");
+
+    private String value;
+
+    RequestAction(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return value.toLowerCase();
+    }
+
+    public static RequestAction valueOfValue(final String action) {
+        if (RequestAction.READ.toString().equals(action)) {
+            return RequestAction.READ;
+        } else if (RequestAction.WRITE.toString().equals(action)) {
+            return RequestAction.WRITE;
+        } else {
+            throw new IllegalArgumentException("Action must be one of [" + READ.toString() + ", " + WRITE.toString() + "]");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
new file mode 100644
index 0000000..661b326
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
@@ -0,0 +1,37 @@
+/*
+ * 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 in an authorization request.
+ */
+public interface Resource {
+
+    /**
+     * The identifier for this resource.
+     *
+     * @return identifier for this resource
+     */
+    String getIdentifier();
+
+    /**
+     * The name of this resource. May be null.
+     *
+     * @return name of this resource
+     */
+    String getName();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/User.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/User.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/User.java
new file mode 100644
index 0000000..371241b
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/User.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+
+import java.util.Objects;
+
+/**
+ * A user to create authorization policies for.
+ */
+public class User {
+
+    private final String identifier;
+
+    private final String identity;
+
+    private User(final Builder builder) {
+        this.identifier = builder.identifier;
+        this.identity = builder.identity;
+
+        if (identifier == null || identifier.trim().isEmpty()) {
+            throw new IllegalArgumentException("Identifier can not be null or empty");
+        }
+
+        if (identity == null || identity.trim().isEmpty()) {
+            throw new IllegalArgumentException("Identity can not be null or empty");
+        }
+
+    }
+
+    /**
+     * @return the identifier of the user
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @return the identity string of the user
+     */
+    public String getIdentity() {
+        return identity;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final User other = (User) obj;
+        return Objects.equals(this.identifier, other.identifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.identifier);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("identifier[%s], identity[%s]", getIdentifier(), getIdentity());
+    }
+
+    /**
+     * Builder for Users.
+     */
+    public static class Builder {
+
+        private String identifier;
+        private String identity;
+        private final boolean fromUser;
+
+        /**
+         * Default constructor for building a new User.
+         */
+        public Builder() {
+            this.fromUser = false;
+        }
+
+        /**
+         * Initializes the builder with the state of the provided user. When using this constructor
+         * the identifier field of the builder can not be changed and will result in an IllegalStateException
+         * if attempting to do so.
+         *
+         * @param other the existing user to initialize from
+         */
+        public Builder(final User other) {
+            if (other == null) {
+                throw new IllegalArgumentException("Provided user can not be null");
+            }
+
+            this.identifier = other.getIdentifier();
+            this.identity = other.getIdentity();
+            this.fromUser = true;
+        }
+
+        /**
+         * Sets the identifier of the builder.
+         *
+         * @param identifier the identifier to set
+         * @return the builder
+         * @throws IllegalStateException if this method is called when this builder was constructed from an existing User
+         */
+        public Builder identifier(final String identifier) {
+            if (fromUser) {
+                throw new IllegalStateException(
+                        "Identifier can not be changed when initialized from an existing user");
+            }
+
+            this.identifier = identifier;
+            return this;
+        }
+
+        /**
+         * Sets the identity of the builder.
+         *
+         * @param identity the identity to set
+         * @return the builder
+         */
+        public Builder identity(final String identity) {
+            this.identity = identity;
+            return this;
+        }
+
+        /**
+         * @return a new User constructed from the state of the builder
+         */
+        public User build() {
+            return new User(this);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserContextKeys.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserContextKeys.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserContextKeys.java
new file mode 100644
index 0000000..fca4b74
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserContextKeys.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+/**
+ * Constants for keys that can be passed in the AuthorizationRequest user context Map.
+ */
+public enum UserContextKeys {
+
+    CLIENT_ADDRESS;
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
new file mode 100644
index 0000000..552b753
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import java.util.Set;
+
+/**
+ * A holder object to provide atomic access to policies for a given resource and users by
+ * identity. Implementations must ensure consistent access to the data backing this instance.
+ */
+public interface UsersAndAccessPolicies {
+
+    /**
+     * Retrieves the set of access policies for a given resource and action.
+     *
+     * @param resourceIdentifier the resource identifier to retrieve policies for
+     * @param action the action to retrieve policies for
+     * @return the access policy for the given resource and action
+     */
+    public AccessPolicy getAccessPolicy(final String resourceIdentifier, final RequestAction action);
+
+    /**
+     * Retrieves a user by an identity string.
+     *
+     * @param identity the identity of the user to retrieve
+     * @return the user with the given identity
+     */
+    public User getUser(final String identity);
+
+    /**
+     * Retrieves the groups for a given user identity.
+     *
+     * @param userIdentity a user identity
+     * @return the set of groups for the given user identity
+     */
+    public Set<Group> getGroups(final String userIdentity);
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java
new file mode 100644
index 0000000..b0d3f83
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java
@@ -0,0 +1,35 @@
+/*
+ * 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.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ *
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface AuthorizerContext {
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java
new file mode 100644
index 0000000..8b22d45
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.exception;
+
+/**
+ * Represents the case when an authorization decision could not be made because the Authorizer was unable to access the underlying data store.
+ */
+public class AuthorizationAccessException extends RuntimeException {
+
+    public AuthorizationAccessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AuthorizationAccessException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java
new file mode 100644
index 0000000..4264202
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.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.exception;
+
+/**
+ * Represents the exceptional case when an Authorizer fails instantiation.
+ *
+ */
+public class AuthorizerCreationException extends RuntimeException {
+
+    public AuthorizerCreationException() {
+    }
+
+    public AuthorizerCreationException(String msg) {
+        super(msg);
+    }
+
+    public AuthorizerCreationException(Throwable cause) {
+        super(cause);
+    }
+
+    public AuthorizerCreationException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java
new file mode 100644
index 0000000..852eca1
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.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.exception;
+
+/**
+ * Represents the exceptional case when an Authorizer fails destruction.
+ *
+ */
+public class AuthorizerDestructionException extends RuntimeException {
+
+    public AuthorizerDestructionException() {
+    }
+
+    public AuthorizerDestructionException(String msg) {
+        super(msg);
+    }
+
+    public AuthorizerDestructionException(Throwable cause) {
+        super(cause);
+    }
+
+    public AuthorizerDestructionException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}