Defining Document Permissions for custom sources
editDefining Document Permissions for custom sources
editThe following guide applies to custom sources. For more information on custom sources, visit the Custom sources indexing API reference guide.
Document-level permissions are used to manage access to various pieces of content based on an individual’s or team’s attributes. A user may be allowed or denied access to certain documents. Document-level permissions are also known as — or derived from — Access Control Lists (ACLs).
Workplace Search’s document-level permissions are applied at index time.
When reasoning about document-level permissions for custom sources, there are two key parts to consider:
-
Adding a
_allow_permissions
or_deny_permissions
field value to your Custom Source documents - Adding matching permission attributes for a given user
Defining document-level permissions
editLet’s start with a simple document:
{ "id" : 1234, "title" : "The Meaning of Life", "body" : "Be kind to others.", "url" : "https://example.com", "created_at": "2019-06-01T12:00:00+00:00", "type": "list" }
The document consists of six (6) content fields. From here, we want to add granular, user-level control information, which will allow us to restrict who gets to see this result. We can accomplish this using the document-level permission attributes:
{ "_allow_permissions": [], "_deny_permissions": [], "id" : 1235, "title" : "The Meaning of Time", "body" : "Not much. It is a made up thing.", "url" : "https://example.com", "created_at": "2019-06-01T12:00:00+00:00", "type": "list" }
Our two new arrays, _allow_permissions
and _deny_permissions
, can hold a grouping of any arbitrary strings.
First, we add permission1
to _allow_permissions
for a given document:
{ "_allow_permissions": ["permission1"], "_deny_permissions": [], "id" : 1235, "title" : "The Meaning of Sleep", "body" : "Rest, recharge, and connect to the Ether.", "url" : "https://example.com", "created_at": "2019-06-01T12:00:00+00:00", "type": "list" }
If we tried searching for this document immediately, we wouldn’t find it. Why? A user or multiple users must first be mapped to this permission value. In other words: permission1
is now required to view the document.
We can map permission1
to a user or multiple users with the External Identities API:
curl -X POST <ENTERPRISE_SEARCH_BASE_URL>/api/ws/v1/sources/[CONTENT_SOURCE_ID]/external_identities \ -H "Authorization: Bearer [TOKEN]" \ -H 'Content-Type: application/json' \ -d '{ "external_user_id": "[EXTERNAL_USER_NAME]", "external_user_properties": [ { "attribute_name": "_elasticsearch_username", "attribute_value": "[USER_NAME]" } ], "permissions": [ "permission1" ] }'
Together, [CONTENT_SOURCE_ID]
and [EXTERNAL_USER_NAME]
form a unique key. However, there can be more than one identity mapped to the same _elasticsearch_username
.
Currently, the only allowed attribute_name
within external_user_properties
is _elasticsearch_username
. Support for more attributes will be added in the future.
To map the same external user to multiple users, it is possible to use more than one _elasticsearch_username
object in external_user_properties
. Example:
{ "external_user_id": "[EXTERNAL_USER_NAME]", "external_user_properties": [ { "attribute_name": "_elasticsearch_username", "attribute_value": "john.doe" }, { "attribute_name": "_elasticsearch_username", "attribute_value": "jane.smith" } ], "permissions": [ "permission1" ] }
External identity can be created and permissions can be mapped even before the user logs in.
Let’s recap: we can assign any arbitrary value to the _allow_permissions
and _deny_permissions
arrays, for any Custom Source document. Once a user exists and has been assigned a permission value, it can be reused across documents in the Custom Source itself.
Let’s now provide a value for _deny_permissions
:
{ "_allow_permissions": ["permission1"], "_deny_permissions": ["permission2"], "id" : 1235, "title" : "The Meaning of Sleep", "body" : "Rest, recharge, and connect to the Ether.", "url" : "https://example.com", "created_at": "2019-06-01T12:00:00+00:00", "type": "list" }
A user assigned both permission1
and permission2
would not have access to the document, because the permission2
deny rule takes precedence.
Deny rules take precedence over allow rules.
Let’s add another permission to our user: permission2
. The following API call will replace the old list of permissions with a new one:
curl -X PUT <ENTERPRISE_SEARCH_BASE_URL>/api/ws/v1/sources/[CONTENT_SOURCE_ID]/external_identities/[EXTERNAL_USER_ID] \ -H "Authorization: Bearer [TOKEN]" \ -H "Content-Type: application/json" \ -d '{ "permissions": ["permission1", "permission2"] }'
# API RESPONSE { "content_source_id": "[CONTENT_SOURCE_ID]", "external_user_id": "[EXTERNAL_USER_ID]", "external_user_properties": [ { "attribute_name": "_elasticsearch_username", "attribute_value": "[USER_NAME]" } ], "permissions": [ "permission1", "permission2" ] }
With these changes applied, documents with the permission2
attributes will not be returned for [USER_NAME]
.
Read the External Identities API reference to learn more about the External Identities endpoint.