Role Based Filtering
The documents in a Globus Search index often describe objects in external
systems which have their own access control mechanisms.
For example, each document may describe a managed dataset with roles of
author
, curator
, and contributor
.
These example roles are defined by the Search user writing the documents. They have no special meaning to Globus Search, and are entirely distinct from the roles which define permissions on a Search index.
Every document in an index must contain a visible_to
list, which is a
list of users and groups who are allowed to see the document.
Documents may also contain a principal_sets
object, which allows viewers of
the document to filter their search results based on the listed roles for their
identities and groups.
In order to support role-based filtering of search results, the content authors
need to define principal_sets
in the data.
To filter on the attributes declared in principal_sets
, clients pass
filter_principal_sets
.
Prerequisites
In order to follow this guide, you must have an index where you have write permissions.
Additionally, you must know the Group IDs and Identity IDs of the users and groups for whom you want to assign roles in your data.
Example queries are given. You can use your own identities and groups to follow these examples, or if you have multiple accounts, one can set the policies and the other can query.
API Methods
We will leverage these API methods:
Submit an Ingest Task |
|
Perform a simple query |
You must have a means to use these APIs. For example, the Globus CLI.
Steps
Step 1: Identify Roles for Data
For the purposes of example, we will assume that we have two users, with IDs
I
and J
, and groups with IDs G
and H
.
Furthermore, we’ll define roles on a few documents as follows:
|
No roles |
|
|
|
|
Let us assume, for simplicity, that doc0
, doc1
, and doc2
are all public data.
Roles and visible_to
are orthogonal and can both apply correctly to the same search.
In order to appear in search results, you must match both criteria if they are used.
Step 2: Define a GIngest document which encodes these roles
Using principal_sets
, we would notate this by putting I
, J
, G
, and H
into Principal URNs and assigning them to each document.
Wrapping this in a GIngest document:
{
"ingest_type": "GMetaList",
"ingest_data": {
"gmeta": [
{
"subject": "doc0",
"visible_to": [
"public"
],
"content": {
"foo": "value0"
}
},
{
"subject": "doc1",
"visible_to": [
"public"
],
"principal_sets": {
"curator": [
"urn:globus::auth:identity:I",
"urn:globus::auth:identity:J"
],
"contributor": [
"urn:globus:groups:id:G"
]
},
"content": {
"foo": "value1"
}
},
{
"subject": "doc2",
"visible_to": [
"public"
],
"principal_sets": {
"contributor": [
"urn:globus:groups:id:H"
]
},
"content": {
"foo": "value2"
}
}
]
}
}
The content is not important for this example, so each contains only one field, foo
.
Step 3: Query the data
In order to query this data, use the filter_principal_sets
parameter.
For example, I
and J
would find only doc1
if they query in the form
GET /v1/index/<index_id>/search?q=*&filter_principal_sets=curator
If I
is a member of group H
, they would find doc1
and doc2
with the
query
GET /v1/index/<index_id>/search?q=*&filter_principal_sets=curator,contributor
For any user, the following query is valid but returns no results:
GET /v1/index/<index_id>/search?q=*&filter_principal_sets=nosuchrole
A Best Practice: Use Groups for Mutable Permissions
Note that principal_sets
contains principal URNs directly, in the same way
that visible_to
does.
As a result, changing the users and groups listed in principal_sets
requires
updating each document where those permissions are set.
When users are able to do so, using Globus Groups as principal_sets
provides
a simpler experience, as users can be added to and removed from a group
without updates to all of the impacted documents.