Access Control Model in TigerGraph

TigerGraph supports both role-based access control (RBAC) and access control lists (ACL). RBAC lets you grant access to different actions on all of a certain type of objects on a graph, such as allowing a role to read or write all queries. ACLs let you grant fine-grained access to a specific query.

All access control is only in effect when user authentication is enabled. Authentication is not enabled by default and must be enabled manually.

Role-based access control

TigerGraph uses role-based access control (RBAC) to manage authorization. On every graph, privileges to perform actions are assigned to roles, and roles are granted to users. Outside the permissions granted by their roles, a user has no access to the system.

Privileges

A privilege is permission to perform an action in a given scope. When a privilege is assigned to a role, it allows users with the role to perform the specified action in the specified scope. For example, the privilege READ_SCHEMA on graph social gives a user read permission to the schema of the graph social. This allows the user to run commands such as ls and SHOW VERTEX on the graph.

To view a complete list of privileges available in TigerGraph and the commands they enable a user to run, see List of Privileges.

Privilege scopes

There are four different scopes for a privilege:

Global privileges apply to all graphs and global objects. Graph-level privileges only apply on the graph they belong to. Type-level privileges only apply to specific vertex or edge types on a graph. Attribute-level privileges only apply to specific attributes of a vertex or edge type.

A privilege on a large scope applies to the entire scope, including all lower scopes encompassed by that scope. If you have a privilege on the graph level, you also have that privilege on the type level and attribute level for all types and attributes in that graph. If you have a privilege on the global scope, you have that privilege across all graphs, types and attributes.

Most privileges are global or graph-level. Only privileges pertaining to graph data (CREATE_DATA, READ_DATA, UPDATE_DATA, DELETE_DATA) can be granted on the type level or attribute level.

For example:

  • A role with WRITE_QUERY on graph Social can only create queries on graph social, but not on other graphs. In contrast, a role with WRITE_QUERY on the global scope can create queries on all graphs.

  • A role with UPDATE_DATA on the age attribute of the Person vertex on graph Social are allowed to run queries that update the value of the age attribute of Person vertices.

  • A role with READ_DATA on the global scope can run queries that read graph data on any graph, any type, or any attribute. They do not need to have privileges specifically for those graphs, types, or attributes.

Data CRUD privileges

Data CRUD privileges (CREATE_DATA, READ_DATA, UPDATE_DATA, DELETE_DATA) are special in that they can be granted on the type level and attribute level.

Data CRUD privileges only govern data access through queries and REST endpoints. Users with the EXECUTE_LOADINGJOB privilege do not need additional privileges in order to run a loading job that inserts or deletes vertices and edges.

The privileges govern specific ways in which a user can access and modify data. Even regarding a single REST endpoint, whether a request is authorized depends on the information that the request is accessing or modifying.

Privilege Type level Attribute level

CREATE_DATA

Permission to create vertices and edges, and specify values for all attributes for the type where the privilege is granted.

  • If granted on a vertex type attribute, it gives permission to create vertices, but only specify values for attributes where the user has CREATE_DATA privilege if the user also has UPDATE_DATA privilege on all attributes of that type.

    • The user must have CREATE_DATA privilege on the primary ID of the vertex type to be able to create vertices.

  • If granted on an edge type attribute, it gives permission to create edges, but only specify values for attributes where the user has CREATE_DATA privilege if the user also has UPDATE_DATA privilege on all attributes of that type.

  • For attributes where the user doesn’t have privilege, they must use wildcards(_) to use the default value for vertices/edges created by the INSERT INTO statements.

READ_DATA

Permission to access all data of the type where the privilege is granted.

Permission to access the attribute value where the privilege is granted.

To grant READ_DATA to a specific attribute of a type, you must grant READ_DATA to the primary key of the type first or in the same command.

For edges, you must grant READ_DATA to the primary key of the FROM and TO vertex types before granting READ_DATA to other attributes of the edge type.

UPDATE_DATA

Permission to update all data of the type where the privilege is granted.

Permission to update the attribute value where the privilege is granted. UPDATE_DATA on all attributes is also required for creating new vertices and edges.

DELETE_DATA

Permission to delete data of the type where the privilege is granted.

N/A. This privilege is not applicable on the attribute level.

Examples

Suppose we have a graph with schema as below:

CREATE VERTEX Person(id UINT PRIMARY KEY, name STRING, INT age)
CREATE VERTEX City(id UINT PRIMARY KEY, name STRING)
CREATE GRAPH Example_Graph(Person, City)

If a user were to run the following query:

CREATE QUERY example_query() {
  Seed = {City.*}; (1)
  vSet = SELECT s FROM Seed:s
         POST-ACCUM
            s.name = s.name + ".post"; (2)
  INSERT INTO Person VALUES ("id3", "Tom", _) (3)
}
1 This action requires READ_DATA on type City.
2 This action requires UPDATE_DATA on attribute name of type City.
3 This action requires UPDATE_DATA on all attributes of type Person and CREATE_DATA on attribute id and name.

Running the query would at a minimum require READ_DATA on type City and UPDATE_DATA on attribute name of type City.

If a user were to make the following REST request:

$ curl -X GET "http://localhost:9000/graph/Example_Graph/vertices/Person/id1"

The request requires that the user has at least READ_DATA on type Person, or all attributes of type Person. However, if the user specify the attributes for the request to return:

$ curl -X GET "http://localhost:9000/graph/Example_Graph/vertices/Person/id1?select=age"

The request would no longer require READ_DATA on the attribute name and only require READ_DATA on id and age.

Roles

A role is a collection of privileges you can assign to users to grant them permission to perform actions on specific resources.

Global vs local roles

Local roles are deprecated, and will be dropped in a future version.

Roles can be global or local. Local roles can only be granted graph-level privileges, while global roles can be granted privileges at every level.

For example, if a user creates a role manager on the graph social:

GSQL > CREATE ROLE manager ON GRAPH social
Successfully created roles: [manager].

This role can only be granted privileges on the graph social. It cannot be granted global privileges.

Built-in roles

GSQL offers five built-in local roles and two built-in global roles. The built-in roles cannot be dropped. The following table details the built-in roles and their corresponding set of privileges.

Name Global or Local Privilege List

observer

Local

READ_SCHEMA, READ_LOADINGJOB,READ_QUERY

queryreader

Local

READ_SCHEMA, READ_LOADINGJOB,READ_QUERY, EXECUTE_LOADINGJOB, READ_DATA, APP_ACCESS_DATA, READ_POLICY

querywriter

Local

READ_SCHEMA, READ_LOADINGJOB,READ_QUERY, EXECUTE_LOADINGJOB, READ_DATA, WRITE_QUERY, CREATE_DATA, UPDATE_DATA, DELETE_DATA, APP_ACCESS_DATA, READ_POLICY, WRITE_POLICY

designer

Local

READ_SCHEMA, READ_LOADINGJOB,READ_QUERY, EXECUTE_LOADINGJOB, READ_DATA, WRITE_QUERY, CREATE_DATA, UPDATE_DATA, DELETE_DATA, WRITE_SCHEMA, WRITE_LOADINGJOB, ACCESS_TAG, APP_ACCESS_DATA, READ_POLICY, WRITE_POLICY

admin

Local

READ_SCHEMA, READ_LOADINGJOB, READ_QUERY, EXECUTE_LOADINGJOB, READ_DATA, WRITE_QUERY, CREATE_DATA, UPDATE_DATA, DELETE_DATA, WRITE_SCHEMA, WRITE_LOADINGJOB, ACCESS_TAG WRITE_ROLE, WRITE_DATASOURCE, READ_ROLE, READ_USER, READ_PROXYGROUP, READ_POLICY, WRITE_POLICY, APP_ACCESS_DATA

globaldesigner

Global

READ_SCHEMA WRITE_SCHEMA' `READ_LOADINGJOB EXECUTE_LOADINGJOB WRITE_LOADINGJOB READ_QUERY WRITE_QUERY READ_FILE WRITE_FILE ACCESS_TAG READ_DATA CREATE_DATA UPDATE_DATA DELETE_DATA APP_ACCESS_DATA READ_POLICY WRITE_POLICY USE_FUNCTION WRITE_FUNCTION

superuser

Global

All supported RBAC privileges: READ_SCHEMA WRITE_SCHEMA READ_LOADINGJOB EXECUTE_LOADINGJOB WRITE_LOADINGJOB READ_QUERY WRITE_QUERY WRITE_DATASOURCE READ_ROLE WRITE_ROLE READ_USER WRITE_USER READ_PROXYGROUP WRITE_PROXYGROUP READ_FILE WRITE_FILE DROP_GRAPH EXPORT_GRAPH CLEAR_GRAPHSTORE DROP_ALL ACCESS_TAG READ_DATA CREATE_DATA UPDATE_DATA DELETE_DATA APP_ACCESS_DATA READ_POLICY WRITE_POLICY USE_FUNCTION WRITE_FUNCTION READ_WORKLOAD_QUEUE WRITE_WORKLOAD_QUEUE

For Row Policy related Built-in roles see Row Policy built-in role changes

User-defined roles

Users can define roles with their own list of privileges they want to grant to the role. To learn how to create/drop user-defined roles and manage privileges for the roles, see Role Management.

Access control lists

ACLs give you the ability to apply finer-grained access control to a GSQL query by specifying who can read or execute the query. ACLs are bound to queries.

An ACL contains two entries - READ and EXECUTE - for read privilege and execute (run) privilege on a given query, respectively. Both entries have a permission list that contains roles. Users with roles on the list have the permission to either read or execute the query.

ACL entry status

In the ACL of a query, each type of privilege’s entry (READ/EXECUTE) has three statuses:

Unspecified

Default status. When an ACL privilege is unspecified, RBAC governs the access for that privilege

Specified Roles

Only the users with specified roles have the ACL privilege. Any roles (local/global, built-in/user-defined) can be a grantee of an ACL privilege.

Nobody

No one, not even the owner, can access the query, even with corresponding RBAC privileges.

Query owner

Every query has one and only one owner. Only the owner of a query can:

  • run ACL management commands to modify the ACL of query.

  • run CREATE OR REPLACE to update a query. When the query owner runs CREATE OR REPLACE to update a query, the ACL on the query remains unchanged.

When a query is created, the creator of the query is assigned to be the owner automatically. When a user is the owner of a query, the user cannot be dropped unless the query is dropped or if the owner of the query is changed.

When you upgrade from a version prior to 3.4, the old queries have no owner. Users with WRITE_ROLE privilege on the graph or on the global scope can assign an owner to a query without owners.

ACL password

Users have the option of setting an ACL password. When a user has an ACL password, operations that modify ACL privileges of queries owned by the user requires the ACL password. These operations include:

  • Changing the owner of a query

  • Modifying the ACL privileges on a query

Examples

Using NOBODY entry status to hide query from everyone

In the following example, user1 protects their query q1 from being seen by anyone including users with superuser roles, by setting the status of the READ entry of their query’s ACL to NOBODY.

Even though no one can see the content of the query, but since the EXECUTE entry is unspecified, users with sufficient RBAC privileges can still execute the query. This allows you to protect the content of a sensitive query, but still allows people to run it.

The following GSQL command are performed by user1.

GSQL > GRANT ACL PRIVILEGE READ ON QUERY q1 TO NOBODY (1)
[WARNING] The READ privileges on the query q1 are denied for any user.
Successfully granted READ on query q1 in the graph ldbc_snb to roles: <NOBODY>.
GSQL > SHOW ACL PRIVILEGE ON QUERY q1 (2)
Query: "q1"
    - Owner:   user1
    - READ:    <Nobody> (2)
    - EXECUTE: <Unspecified>
GSQL > SHOW QUERY q1
CREATE QUERY q1 () {
  /******* Query Content is Hidden. Require ACL privilege READ *******/ (3)
}
GSQL > ALTER ACL PASSWORD SET XXXXXX (4)
1 This command forbids anyone to read the query, even the owner. See ACL entry status: NOBODY.
2 Use the SHOW ACL PRIVILEGE ON QUERY command to verify the NOBODY status of the READ entry.
3 Query content cannot be seen by any user, including the owner.
4 If user user1 does not have an ACL password, it is important to set one. Otherwise, other users with the WRITE_ROLE privilege can change the owner of the query.

Granting and revoking EXECUTE Privilege

In this example, the superuser tigergraph grants and revokes EXECUTE privilege for query q1 for roles role1 and admin.

User user1 is first granted the privilege while user2 is not, then the privilege is revoked from all users.

GSQL > CREATE ROLE role1 ON GRAPH G1
Successfully created local roles on graph 'G1': [role1].
GSQL > GRANT ACL PRIVILEGE EXECUTE ON QUERY q1 TO role1, admin SECURED BY "example_password"
Successfully granted EXECUTE on query q1 in the graph ldbc_snb to roles: [role1, admin].
GSQL > SHOW ACL PRIVILEGE ON ROLE role1, admin
Role: "role1"
- QUERY:
  - EXECUTE:
    - Graph 'G1': [q1]
Role: "admin"
- QUERY:
  - EXECUTE:
    - Graph 'G1': [q1]
GSQL > GRANT ROLE role1 ON GRAPH G1 TO user1
GSQL > SHOW ACL PRIVILEGE ON USER user1
User: "user1"
- QUERY:
  - EXECUTE:
    - Graph 'G1': [q1]

If someone logs in as user user2, who doesn’t have the roles role1 or admin, and tries to run the query, their request is denied.

GSQL > INTERPRET QUERY q1()
User 'user2' does not have the permission to run the command. Required ACL privilege EXECUTE on the query q1.

Log back in as the owner of the query, you can set ACL entries in the query to status unspecified. This disables ACL access control and revert access control to RBAC.

GSQL > REVOKE ACL PRIVILEGE EXECUTE ON QUERY q1 FROM ALL SECURED BY XXXXXX
GSQL > SHOW ACL PRIVILEGE ON USER user1
User: "user1"

How permissions are evaluated

All operations that don’t involve queries are only governed by RBAC. ACLs only apply to queries.

When it comes to evaluating permissions for operations on queries, ACLs are evaluated first:

  • When the ACL entry is unspecified, RBAC governs the access control of the resource. By default, both ACL entries (READ and EXECUTE) for a query are unspecified.

  • If the ACL entry is specified, ACL replaces RBAC to govern access for the query.

    • Even if a user does not have the READ_QUERY permission on a graph, they can read a query if they are on the READ ACL entry permission list of the query.

    • Even if a user has the READ_QUERY permission on a graph, they cannot read a query if the READ ACL entry for the query is specified and the user is not on the list.

Visualization of the hierarchy of permission evaluation for a query evaluation.
Figure 1. How permission is evaluated for a query operation

Importing and exporting

When exporting graphs, ACLs are only exported when both queries and users are exported.

  • When you export graphs without queries, there is no ACL on the exported graphs because there are no queries.

  • When you export graphs with queries but without users, the ACL entries on the exported are reset to the unspecified status.