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:
- Create a
Principal
using static methods in the ACL class. - 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.
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 toBOTH_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 toCHILD_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 toPARENT_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.
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.
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.