Vertex-Level Access Control (Beta)
Vertex-level Access Control (VLAC) allows database administrators to control data access on the vertex level by attaching tags to individual vertices on a graph (the base graph) and creating tag-based graphs. Tag-based graphs share the underlying data with the base graph but have their own sets of roles and privileges, which allows administrators to exercise fine-grained data access control without the vertex type boundary.
Figure 1 below illustrates two tag-based graphs built upon a base graph. The base graph contains vertices of person
type, and vertices of post
type. Two tags (A and B) are used to tag them. For example, vertex 1 and vertex 9 both have tag A. Vertex 3 and vertex 11 both have tag A and B. A tag-based graph named tagA
will only present to its users those base graph vertices that have tag A (the bottom-left graph). The other tag-based graph named tagB
will only present to its users those base graph vertices that have tag B (the bottom-right graph).
For users operating on a tag-based graph, tags are an invisible aspect that silently filters how they load and query data. A tag-based graph defines its view, and all data outside its view is invisible to it.
Prerequisites
Sufficient privileges on the base graph or on the global scope are required to perform the steps described on this page.
ACCESS_TAG
Any operation involving tags
WRITE_SCHEMA
Create/run schema change jobs
Create tag-based graphs
READ_DATA, WRITE_DATA
Run queries that modify the graph
WRITE_LOADINGJOB
,EXECUTE_LOADINGJOB
Create/run loading jobs
Workflow - Using Vertex Level Access Control
Below is the basic workflow on using the VLAC to control data access for a database administrator:
1. Create a tag-based graph
2. Manage users of the tag-based graph
Grant built-in roles to users on a tag-based graph
Define roles and grant them to users on a tag-based graph
3. Load and tag data
There are three main options for tagging vertices.
Explicitly add/modify tags on existing data: A user with the privilege
ACCESS_TAG
andWRITE_DATA
privileges on the base graph can create and run a DML query that sets tags on selected individual vertices.Explicitly set tags when loading data into to a base graph: A user with
EXECUTE_LOADINGJOB
,WRITE_LOADINGJOB
andACCESS_TAG
privileges on the base graph can create and run a loading job that explicitly sets tags on the newly loaded base graph vertices.Implicitly set tags when loading into a tag-based graph: A user with tag-based graph loading or insert privilege (e.g., a
designer
orquerywriter
) can create an ordinary loading or upsert job which inserts new vertices. The new vertices will be automatically tagged according to the tag-based graph's schema definition.
4. Query and update Data
Users with data read and write privileges (e.g., the querywriter
and queryreader
built-in roles) can query and update the tag-based graph as they would do any other graph. The data filtering for querying or data tagging for insertion is applied automatically.
The rest of this tutorial will first describe tag management: creating and dropping tags, making vertex type taggable, and using tags to define tag-based graphs. Next, the three ways to tag vertices are described and illustrated. We summarize the privilege scheme of tag-based graphs in terms of GSQL's predefined roles. Finally, we give some use cases that can be solved by VLAC.
Features not yet supported:
DDL tag operations can only be done in GSQL. They are not yet supported in GraphStudio. This includes create/drop tags, create/alter vertices that are taggable, define a tag-based graph.
The privilege control for DDL operations (only admin and designer users should be able to explicitly manage tags) is not fully functional.
In summary, all necessary operations to set up VLAC graphs and users are supported in GSQL. Due to a known bug, standard users (with querywriter
and queryreader
roles) can run some DDL operations which they should not be able to.
We’ll use the graph socialNet as an example in the following sections.
Tag Management
A tag is a special attribute of a vertex, which appears as a string for input and output purposes. If a vertex type is declared to be taggable, then each vertex of that type can have one or more tags. The maximum number of different tags in a global graph is 64. All operations involving tags requires the user to have the ACCESS_TAG
privilege.
Define a tag
A tag name has to be defined via ADD TAG
before it can be used. Each base graph defines its own set of tags. However, there is a global maximum number of different tags, currently set at 64.
ADD TAG
can only be used inside a SCHEMA_CHANGE JOB
. An example is below:
List tags
Run ls
to see a list of defined tags:
Drop a tag
The DROP TAG
command not only removes the given tag(s) from the catalog of available tags, but also deletes them from each vertex to which it is attached. You can drop multiple tags in one statement.
Like ADD TAG
, DROP TAG
also needs to be inside a SCHEMA_CHANGE JOB
:
You cannot drop a tag if it is used in the definition of a tag-based graph. You must drop the graph first.
When
DROP TAG
is executed, the specified tags will be made invalid, and then the foreground process will complete. A background process will continue to run to remove the tags from all data. In the meantime, each dropped tag still takes up one of the 64 slots for tags. The slot(s) will become available once the background process finishes.
Create a tag-based graph
A tag-based graph is a filtered view of a base graph, where a base graph is a simple collection of vertex types and edge types, without any tag specifiers. A tag-based graph must include at least one taggable vertex type from the base graph.
Mark vertex types as taggable
A vertex type has to be taggable to accept tags. TAGGABLE
is a boolean property of a vertex type that can be set with CREATE VERTEX
initially or with ALTER VERTEX
in a schema change job:
The property TAGGABLE is false by default. To change this default, use the WITH
clause below when creating a vertex type:
To change a vertex type from taggable to untaggable, use
WITH TAGGABLE="false".
You cannot make a vertex type untaggable if it is used in the definition of a tag-based graph.
Edge types are never tagged. See the next section to see how we determine which edges to include in the tag-based graph.
Create a Tag-Based Graph
After a tag set and taggable vertex types have been created, we can use the tags to define a tag-based graph. For each vertex type we want to include, we may also specify a tag expression which must be satisfied for an individual vertex to be included.
Examples
Here is an example of creating a tag-based graph from the base graph socialNet
.
The interpretation is "Starting from the socialNet
graph, create a tag-based graph called vipNet
which includes person
vertices which are tagged 'vip
'. Also include all post
vertices and all friend
, posted
and liked
edges."
Edges do not have tag expressions. An edge will be included when both of its vertex endpoints are included (and its edge type is included in the tag graph schema).
To describe a combination of tags, use the &
operator to combine the tags:
The graph mixedNet
will only include the person
vertices having both the public
and vip
tags, and posts having all three of the public
, tech
and dummy
tags.
Same tag for all vertex types
If the desired tag-based graph is "anything in the base graph that has these tags", there is a convenient shortcut:
is the same as
General Syntax
The formal syntax for both the general form and the simplified form of creating a tag-based graph is shown below:
How To Tag Vertices
There are three main options for tagging vertices in the base graph.
Add tags on existing data with DML queries. For existing data, a user with base graph tagging privilege (e.g., an
admin
ordesigner
) can create and run a DML query that sets tags on selected individual vertices.Explicitly set tags when loading/inserting to a base graph. For new data, a user with base graph loading and tagging privilege (e.g., an
admin
ordesigner
) can create and run a loading job that explicitly sets tags on the newly loaded vertices.Implicitly set tags when loading/inserting into a tag-based graph. For new data, a user with tag-based graph loading or insert privilege (e.g., a
designer
orquerywriter
) can create an ordinary Loading or Upsert Job which inserts new vertices. The new vertices will be automatically tagged according to the tag-based graph's schema definition.
Add tags on existing data
In GSQL, special vertex methods are provided to access and modify the tags of a vertex in a DML query (full list available on page Vertex Functions). These functions are only available for vertex aliases (defined in the FROM
clause of a SELECT
statement); they cannot be applied to vertex variables in other contexts.
There are 8 DML-level tag-access functions in the vertex-query block or edge-query block. Use the v.addTags()
function to tag a vertex.
Required privilege
READ_DATA
, WRITE_DATA
, WRITE_QUERY
, ACCESS_TAG
To add or modify tags, you should work at the base graph level.
Examples
addTags()
is shown below. This query will add tags to person vertices to achieve the same effect as a base graph loading job example in the previous section.
Use removeTags()
and removeAllTags()
to remove tags from vertices:
Set tags explicitly with TAGS
clause
TAGS
clauseTags can be added to vertices at their loading time using a base graph loading job.
The LOAD
statement has an optional clause for explicit tagging of loaded data. The tagging clause has two keywords, TAGS
and BY:
TAGS(<tag_list>)
specifies the tags to be set.BY
specifies how to merge tags if the targeted vertex exists in the graphBY OR:
Add the given tags to the existing set of tags.BY OVERWRITE:
Replace the existing tags with the given ones.
Required privilege
WRITE_LOADINGJOB
, EXECUTE_LOADINGJOB
, ACCESS_TAG
Example 1
Suppose we want to put the tags vip
and public
on the person
vertex data coming from a certain file. We have three files: persons1
, persons2
, persons3
.
Create and run three loading jobs:
Note that the TAGS
clause can specify a tag with a string literal ("vip"
) so every vertex gets the same tag, or with a token reference by position ($2
) or by name ($"label"
) from the source file, so each vertex gets a data-dependent tag. If the tag clause refers to a non-existent tag, the loading job will still run, but the data will not be loaded at runtime. The loading job log will report these non-loaded vertices.
Example 2
We have three post files: posts1
, posts2
, and posts3
.
We create and run the following loading jobs:
Set tags implicitly by inserting into a tag-based graph
Loading data to a tag-based graph automatically tags each vertex with the tags specified in the graph's definition. For example, when loading to vipNet
, the person
vertices will automatically be tagged with vip
.
If you load data into a tag-based graph, these vertices are actually being added to the parent base graph. If two tag-based graphs have overlapping views (e.g. if the graph vipNet2
also includes person:vip
), then when one adds a vertex via the tag-based graph, the other tag-based graph may also see it.
Portability and Reusability: The same loading job works for
socialNet
or any graph derived fromsocialNet
which containsperson
. The difference is in the effect: running it withvipNet
will apply thevip
tag. Running it with a different tag-based graph would apply different tags. Users of a given tag-based graph automatically insert and query data for that tag-based graph.Tagging Shared Data: The default behavior of GSQL loading is upsert: if you attempt to insert a vertex or edge which already exists (e.g., uses an existing ID), you will instead update the existing element with the new attribute values. If the attribute is a list or set, the new values will be added to the existing list/set. This applies to tags. If you attempt to load an existing vertex, the new tag(s) will be added to any existing tags. Loading a vertex that already exists extends the tag set with the guidance of the tag-graph schema.
Query a Tag-based Graph
The graph vipNet
only includes vertices with the tag vip
. We can verify this by running a simple query to return all person vertices in vipNet
:
The output of the query would be:
Access Control
Users with global WRITE_SCHEMA
and ACCESS_TAG
privileges can create, modify and drop tags, as well as create tag-based graphs for all graphs.
On the base graph
Users with roles on the base graph that have the ACCESS_TAG
privilege (e.g.admin
and designer
roles) can create/drop tags, and tag vertices. Users that have both the ACCESS_TAG
privilege and WRITE_SCHEMA
privilege (e.g. admin
and designer
roles) can create/drop tag-based graphs of the base graph.
Users with roles that don't have the ACCESS_TAG
privilege on the base graph are able to access the base graph as their roles allow, but they do not have access to the tags on the base graph. They cannot see whether any vertex type on the graph is taggable or if there are tag-based graphs of the base graph.
Users with roles on the tag-based graphs of the base graph cannot access the base graph if they don't have a role with privileges for the base graph.
On tag-based graphs
When a new tag-based graph is created, users with admin
or designer
roles will inherit their base graph role on the tag-based graph. Additionally, the creator of the tag-based graph becomes an admin of the tag-based graph.
Users who are given roles on a tag-based graph have the privileges on the tag-based graph that correspond to their roles, except they are not allowed to edit the tag-based graph's graph schema.
Sample Use Cases
Scenario I
Problem
A user with admin
role on a graph wants to grant a group of users access to a selective set of vertices.
Solution
The base graph admin can do the following security setup.
Define a tag. In a schema change job, declare a tag
T
for this application.Mark vertex types as taggable. Identify the vertex types you want to give selective access for, and mark those vertex types as taggable in a schema change job.
Define a tag-based graph. Define a tag-based graph
B
with the taggable vertex types, withT
as their tag expression.Tag vertices. Write a DML query on the base graph and use the tag functions in the query to tag the vertices you want to include in the tag-based graph, and run the query.
Grant users permission to the tag-based graph. On the tag-based graph B, grant roles that have the appropriate privileges for graph
B
to the target users.
Scenario II
Problem
You have a source file containing class annotations (tags) on vertex data. You want to grant users access to the vertices that have the annotation T1
. In the future, you also want the ability to give other users access to vertices based on the vertex class.
Solution
The base graph admin
user can do the following setup.
Define tags. Declare tags
T1, T2, … Tn
for all the classes in your source file in a schema change job.Mark vertex types as taggable. Identify the vertex types of the vertices in your source file that have class annotations, and mark those vertex types as taggable in a schema change job.
Define a tag-based graph. Define a tag-based graph
B
withT1
as the tag expression.Explicitly tag vertices during data loading. Write a base graph loading job, and in the loading job, use a
TAGS() BY
clause to explicitly add tags to the ingested vertices.Grant roles on the tag-based graph. On the tag-based graph
B
, grant roles that have the appropriate privileges for the graphB
to target users.
Scenario III
Problem
An admin
user on a graph wants to give a group of users read/write access for a specific class of vertices. The users would be able to insert new vertices into the graph and query the data, and all the data they insert into the graph are tagged as the same class.
Solution
The base graph admin can do the following setup.
Define a tag. Declare a tag
T
for this application in a schema change job.Mark vertex types as taggable. Identify the vertex types to give selective access to, and mark the relevant vertex types as taggable in a schema change job.
Define a tag-based graph. Define a tag-based graph
B
withT
as the tag expression.Grant roles on the tag-based graph. On the tag-based graph, grant roles with the appropriate privileges to target users.
These group users operate (including delete/update/insert) on graph B
as if it is a normal graph. They can ingest new data, as well as operate on those vertices from the base graph that have the tag T
.
Last updated