Map ACLs

To ensure that only users with access to an item can see that item within a search result, you should index items with their access control lists (ACLs) from the enterprise repository. You must model the ACLs of your repository and include those ACLs when indexing items in the repository. The Content Connector SDK provides a rich set of ACL methods powerful enough to model the ACLs of most repositories.

Create an ACL

Creating an ACL is a two step process:

  1. Create a Principal using static methods in the ACL class.
  2. Use the Acl.Builder class to build the ACL using the principal.

The remainder of this document covers some concepts you need to know to model and create ACLs, such as inheritance and containment.

Create a principal using an external ID

Google Cloud Search requires users and groups to resolve to Google email address. When indexing repository items, content connectors may not have these email addresses. However, the Content Connector SDK allows you to use any external ID (ID granting a user or group access to repository items), instead of an email address, to index an item. Use the getUserPrincipal() method or the getGroupPrincpal() method to create principals containing external IDs. There are several other static methods in the ACL class used to build Principal objects.

ACL inheritance

ACL inheritance refers to the authorization, for a specific item and a specific user, based on the result of a combination of the ACLs of the item and the ACLs of its inheritance chain. The rules used to make an authorization decision depend on the repository and on the item’s properties.

Set inheritance

Each item can have direct allowed principals and direct denied principals, specified using the setReaders() and setDeniedReaders() methods. A direct allowed principal is a user identified in an ACL that gives them direct access to a specific item. A direct denied principal is a user identified in an ACL as not having access to a specific item.

An item may also inherit indirect allowed principals and indirect denied principals using the setInheritFrom() method. An indirect allowed principal is a user who, through ACL inheritance, has indirect access to a specific item. An indirect denied principal is a user who, through ACL inheritance, is denied access to a specific item.

Figure 1 shows how the setInheritFrom() method is used to inherit indirect allowed and indirect denied principals.

Drawing of connections between items
Figure 1. The setInheritFrom() method.

These access controls are represented in Figure 1:

  • User 1 is a direct allowed principal of item A.
  • User 2 is a direct allowed principal of item B.
  • Item B inherits the ACL of item A.

Based on the access controls, the access rules are:

  • User 1 does not need to be specified explicitly as a principal of item B to be an indirect allowed principal of item B; the access is inherited because User 1 is listed as a direct allowed principal of item A and item B inherits its ACL from item A.
  • User 2 is not an indirect allowed principal to item A.

Set inheritance type

If you set inheritance using the setInheritFrom() method, you must set the inheritance type using the setInheritanceType() method. The inheritance type determines how a child's ACL combines with its parent's ACL. The Acl.InheritanceType implements three inheritance types:

  • BOTH_PERMIT - Set inheritance type to BOTH_PERMIT to grant a user access to the item only when both the child item's ACL and parent's inherited item ACL allow that user to access that item.

  • CHILD_OVERRIDE - Set inheritance type to CHILD_OVERRIDE to force the child item's ACL to take precedence over the inherited parent item's ACL when they conflict. So, if the parent item's ACL denies access to the user as a denied reader, the user still has access if they have access to the child item as a reader. Conversely, even if the parent item's ACL grants access to the user, the user doesn't have access if they are a denied reader of the child.

  • PARENT_OVERRIDE - Set inheritance type to PARENT_OVERRIDE to force the parent item's ACL to take precedence over the child item's ACL when they conflict. So, if the child item's ACL denies access to the user as a denied reader, the user still has access if they have access to the parent item as a reader. Conversely, even if the child item's ACL grants access to the user, the user doesn't have access if they are a denied reader of the parent item.

When evaluating an ACL inheritance chain, the order of evaluation can change the outcome of the authorization decision. Cloud Search provides leaf-to-root order of evaluation for ACL inheritance chains. Specifically, the ACL decision for a chain starts with evaluation of a child with its parents, and can progress all the way to the to root parent.

For example, if the child has CHILD_OVERRIDE inheritance type and the user has access to the child, then Drive doesn't need to evaluate the parent. However, if the child has PARENT_OVERRIDE or BOTH_PERMIT, then Drive continues on evaluating inheritance further up the chain.

Containment and item deletion

When indexing an item, you can label an item as a container using the setContainer() method of the IndexingItemBuilder class. The container/containee relationship establishes the physical hierarchy of items and ensures items are deleted properly. When a container is deleted, the contained items are deleted too.

Containment relationships are wholly independent from ACL inheritance rules. For example, a file in a file system can be contained by a folder for the purpose of deletion, but inherit the ACL from a different folder. Deleting a folder does not delete items that inherit its ACL, unless those items are also in the containment hierarchy of the folder.

These access controls are represented in Figure 2:

  • User 1 is a direct allowed principal of item A.
  • User 2 is a direct allowed principal of item B.
  • User 3 is a direct allowed principal of item C.
  • Item C inherits the ACL of item A.
  • Item B names item A as its container.
  • Item C names item B as its container.

Based on the access controls, the access rules are:

  • Indirect access comes from the setInheritFrom() method. Therefore, user 1 can access item C because item C inherits the ACL of item A.
  • Indirect access does not come from item C being contained by item B. Therefore, user 2 cannot access item C.
Drawing of connections between items
Figure 2. The setInheritFrom() method in use.

The separation of ACL inheritance from the containment hierarchy lets you model many different existing structures.

When an item is successfully deleted:

  • Any item that contained a deleted item becomes unsearchable and is scheduled for deletion from Google's data source.
  • Any item that has specified the deleted item using the setInheritFrom() method becomes unsearchable.

If a resource has a deleted item using the setInheritFrom() method, but it does not have a container set using setContainer(), or its containment hierarchy contains no deleted items, that item and its data remains in Google's data source. You are responsible for deleting the item.

Figure 3 shows an example of how deletion works for an item hierarchy.

Drawing of connections between items
Figure 3. Deleting an item and ACL inheritance.

These access controls are represented in Figure 3:

  • User 1 is a direct allowed principal of item A.
  • User 2 is a direct allowed principal of item D.
  • Item D and item E both inherit the ACL of item A.
  • Item D names item A as its container.
  • Items A and E are root-level items as they do not have a container item.

Deletes cascade through the container references. When item A is deleted:

  • All descendants of the setInheritFrom() reference lose access for all users.
  • No users can access item A.
  • Item D is implicitly deleted. No users can access item D.
  • Item E is not deleted, as deletion only cascades through container references.
  • Item E becomes unreachable and no users are able to search for item E.